blob: a92aa37f32a02896c934e0a1a23aa33e9c009f7f [file] [log] [blame]
Kim Phillips9c4a7962008-06-23 19:50:15 +08001/*
2 * talitos - Freescale Integrated Security Engine (SEC) device driver
3 *
Kim Phillips5228f0f2011-07-15 11:21:38 +08004 * Copyright (c) 2008-2011 Freescale Semiconductor, Inc.
Kim Phillips9c4a7962008-06-23 19:50:15 +08005 *
6 * Scatterlist Crypto API glue code copied from files with the following:
7 * Copyright (c) 2006-2007 Herbert Xu <herbert@gondor.apana.org.au>
8 *
9 * Crypto algorithm registration code copied from hifn driver:
10 * 2007+ Copyright (c) Evgeniy Polyakov <johnpol@2ka.mipt.ru>
11 * All rights reserved.
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 */
27
28#include <linux/kernel.h>
29#include <linux/module.h>
30#include <linux/mod_devicetable.h>
31#include <linux/device.h>
32#include <linux/interrupt.h>
33#include <linux/crypto.h>
34#include <linux/hw_random.h>
Rob Herring5af50732013-09-17 14:28:33 -050035#include <linux/of_address.h>
36#include <linux/of_irq.h>
Kim Phillips9c4a7962008-06-23 19:50:15 +080037#include <linux/of_platform.h>
38#include <linux/dma-mapping.h>
39#include <linux/io.h>
40#include <linux/spinlock.h>
41#include <linux/rtnetlink.h>
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090042#include <linux/slab.h>
Kim Phillips9c4a7962008-06-23 19:50:15 +080043
44#include <crypto/algapi.h>
45#include <crypto/aes.h>
Lee Nipper3952f172008-07-10 18:29:18 +080046#include <crypto/des.h>
Kim Phillips9c4a7962008-06-23 19:50:15 +080047#include <crypto/sha.h>
Lee Nipper497f2e62010-05-19 19:20:36 +100048#include <crypto/md5.h>
Herbert Xue98014a2015-05-11 17:47:48 +080049#include <crypto/internal/aead.h>
Kim Phillips9c4a7962008-06-23 19:50:15 +080050#include <crypto/authenc.h>
Lee Nipper4de9d0b2009-03-29 15:52:32 +080051#include <crypto/skcipher.h>
Lee Nipperacbf7c622010-05-19 19:19:33 +100052#include <crypto/hash.h>
53#include <crypto/internal/hash.h>
Lee Nipper4de9d0b2009-03-29 15:52:32 +080054#include <crypto/scatterwalk.h>
Kim Phillips9c4a7962008-06-23 19:50:15 +080055
56#include "talitos.h"
57
LEROY Christophe922f9dc2015-04-17 16:32:07 +020058static void to_talitos_ptr(struct talitos_ptr *ptr, dma_addr_t dma_addr,
59 bool is_sec1)
Kim Phillips81eb0242009-08-13 11:51:51 +100060{
LEROY Christopheedc6bd62015-04-17 16:31:53 +020061 ptr->ptr = cpu_to_be32(lower_32_bits(dma_addr));
LEROY Christophe922f9dc2015-04-17 16:32:07 +020062 if (!is_sec1)
63 ptr->eptr = upper_32_bits(dma_addr);
Kim Phillips81eb0242009-08-13 11:51:51 +100064}
65
Horia Geant?340ff602016-04-19 20:33:48 +030066static void copy_talitos_ptr(struct talitos_ptr *dst_ptr,
67 struct talitos_ptr *src_ptr, bool is_sec1)
68{
69 dst_ptr->ptr = src_ptr->ptr;
70 if (!is_sec1)
71 dst_ptr->eptr = src_ptr->eptr;
72}
73
Horia Geant?42e8b0d2015-05-11 20:04:56 +030074static void to_talitos_ptr_len(struct talitos_ptr *ptr, unsigned int len,
LEROY Christophe922f9dc2015-04-17 16:32:07 +020075 bool is_sec1)
LEROY Christophe538caf82015-04-17 16:31:59 +020076{
LEROY Christophe922f9dc2015-04-17 16:32:07 +020077 if (is_sec1) {
78 ptr->res = 0;
79 ptr->len1 = cpu_to_be16(len);
80 } else {
81 ptr->len = cpu_to_be16(len);
82 }
LEROY Christophe538caf82015-04-17 16:31:59 +020083}
84
LEROY Christophe922f9dc2015-04-17 16:32:07 +020085static unsigned short from_talitos_ptr_len(struct talitos_ptr *ptr,
86 bool is_sec1)
LEROY Christophe538caf82015-04-17 16:31:59 +020087{
LEROY Christophe922f9dc2015-04-17 16:32:07 +020088 if (is_sec1)
89 return be16_to_cpu(ptr->len1);
90 else
91 return be16_to_cpu(ptr->len);
LEROY Christophe538caf82015-04-17 16:31:59 +020092}
93
LEROY Christopheb096b542016-06-06 13:20:34 +020094static void to_talitos_ptr_ext_set(struct talitos_ptr *ptr, u8 val,
95 bool is_sec1)
LEROY Christophe185eb792015-04-17 16:31:55 +020096{
LEROY Christophe922f9dc2015-04-17 16:32:07 +020097 if (!is_sec1)
LEROY Christopheb096b542016-06-06 13:20:34 +020098 ptr->j_extent = val;
99}
100
101static void to_talitos_ptr_ext_or(struct talitos_ptr *ptr, u8 val, bool is_sec1)
102{
103 if (!is_sec1)
104 ptr->j_extent |= val;
LEROY Christophe185eb792015-04-17 16:31:55 +0200105}
106
Kim Phillips9c4a7962008-06-23 19:50:15 +0800107/*
108 * map virtual single (contiguous) pointer to h/w descriptor pointer
109 */
110static void map_single_talitos_ptr(struct device *dev,
LEROY Christopheedc6bd62015-04-17 16:31:53 +0200111 struct talitos_ptr *ptr,
Horia Geant?42e8b0d2015-05-11 20:04:56 +0300112 unsigned int len, void *data,
Kim Phillips9c4a7962008-06-23 19:50:15 +0800113 enum dma_data_direction dir)
114{
Kim Phillips81eb0242009-08-13 11:51:51 +1000115 dma_addr_t dma_addr = dma_map_single(dev, data, len, dir);
LEROY Christophe922f9dc2015-04-17 16:32:07 +0200116 struct talitos_private *priv = dev_get_drvdata(dev);
117 bool is_sec1 = has_ftr_sec1(priv);
Kim Phillips81eb0242009-08-13 11:51:51 +1000118
LEROY Christophe922f9dc2015-04-17 16:32:07 +0200119 to_talitos_ptr_len(ptr, len, is_sec1);
120 to_talitos_ptr(ptr, dma_addr, is_sec1);
LEROY Christopheb096b542016-06-06 13:20:34 +0200121 to_talitos_ptr_ext_set(ptr, 0, is_sec1);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800122}
123
124/*
125 * unmap bus single (contiguous) h/w descriptor pointer
126 */
127static void unmap_single_talitos_ptr(struct device *dev,
LEROY Christopheedc6bd62015-04-17 16:31:53 +0200128 struct talitos_ptr *ptr,
Kim Phillips9c4a7962008-06-23 19:50:15 +0800129 enum dma_data_direction dir)
130{
LEROY Christophe922f9dc2015-04-17 16:32:07 +0200131 struct talitos_private *priv = dev_get_drvdata(dev);
132 bool is_sec1 = has_ftr_sec1(priv);
133
LEROY Christopheedc6bd62015-04-17 16:31:53 +0200134 dma_unmap_single(dev, be32_to_cpu(ptr->ptr),
LEROY Christophe922f9dc2015-04-17 16:32:07 +0200135 from_talitos_ptr_len(ptr, is_sec1), dir);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800136}
137
138static int reset_channel(struct device *dev, int ch)
139{
140 struct talitos_private *priv = dev_get_drvdata(dev);
141 unsigned int timeout = TALITOS_TIMEOUT;
LEROY Christophedd3c0982015-04-17 16:32:13 +0200142 bool is_sec1 = has_ftr_sec1(priv);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800143
LEROY Christophedd3c0982015-04-17 16:32:13 +0200144 if (is_sec1) {
145 setbits32(priv->chan[ch].reg + TALITOS_CCCR_LO,
146 TALITOS1_CCCR_LO_RESET);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800147
LEROY Christophedd3c0982015-04-17 16:32:13 +0200148 while ((in_be32(priv->chan[ch].reg + TALITOS_CCCR_LO) &
149 TALITOS1_CCCR_LO_RESET) && --timeout)
150 cpu_relax();
151 } else {
152 setbits32(priv->chan[ch].reg + TALITOS_CCCR,
153 TALITOS2_CCCR_RESET);
154
155 while ((in_be32(priv->chan[ch].reg + TALITOS_CCCR) &
156 TALITOS2_CCCR_RESET) && --timeout)
157 cpu_relax();
158 }
Kim Phillips9c4a7962008-06-23 19:50:15 +0800159
160 if (timeout == 0) {
161 dev_err(dev, "failed to reset channel %d\n", ch);
162 return -EIO;
163 }
164
Kim Phillips81eb0242009-08-13 11:51:51 +1000165 /* set 36-bit addressing, done writeback enable and done IRQ enable */
Kim Phillipsad42d5f2011-11-21 16:13:27 +0800166 setbits32(priv->chan[ch].reg + TALITOS_CCCR_LO, TALITOS_CCCR_LO_EAE |
Kim Phillips81eb0242009-08-13 11:51:51 +1000167 TALITOS_CCCR_LO_CDWE | TALITOS_CCCR_LO_CDIE);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800168
Kim Phillipsfe5720e2008-10-12 20:33:14 +0800169 /* and ICCR writeback, if available */
170 if (priv->features & TALITOS_FTR_HW_AUTH_CHECK)
Kim Phillipsad42d5f2011-11-21 16:13:27 +0800171 setbits32(priv->chan[ch].reg + TALITOS_CCCR_LO,
Kim Phillipsfe5720e2008-10-12 20:33:14 +0800172 TALITOS_CCCR_LO_IWSE);
173
Kim Phillips9c4a7962008-06-23 19:50:15 +0800174 return 0;
175}
176
177static int reset_device(struct device *dev)
178{
179 struct talitos_private *priv = dev_get_drvdata(dev);
180 unsigned int timeout = TALITOS_TIMEOUT;
LEROY Christophedd3c0982015-04-17 16:32:13 +0200181 bool is_sec1 = has_ftr_sec1(priv);
182 u32 mcr = is_sec1 ? TALITOS1_MCR_SWR : TALITOS2_MCR_SWR;
Kim Phillips9c4a7962008-06-23 19:50:15 +0800183
Kim Phillipsc3e337f2011-11-21 16:13:27 +0800184 setbits32(priv->reg + TALITOS_MCR, mcr);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800185
LEROY Christophedd3c0982015-04-17 16:32:13 +0200186 while ((in_be32(priv->reg + TALITOS_MCR) & mcr)
Kim Phillips9c4a7962008-06-23 19:50:15 +0800187 && --timeout)
188 cpu_relax();
189
Kim Phillips2cdba3c2011-12-12 14:59:11 -0600190 if (priv->irq[1]) {
Kim Phillipsc3e337f2011-11-21 16:13:27 +0800191 mcr = TALITOS_MCR_RCA1 | TALITOS_MCR_RCA3;
192 setbits32(priv->reg + TALITOS_MCR, mcr);
193 }
194
Kim Phillips9c4a7962008-06-23 19:50:15 +0800195 if (timeout == 0) {
196 dev_err(dev, "failed to reset device\n");
197 return -EIO;
198 }
199
200 return 0;
201}
202
203/*
204 * Reset and initialize the device
205 */
206static int init_device(struct device *dev)
207{
208 struct talitos_private *priv = dev_get_drvdata(dev);
209 int ch, err;
LEROY Christophedd3c0982015-04-17 16:32:13 +0200210 bool is_sec1 = has_ftr_sec1(priv);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800211
212 /*
213 * Master reset
214 * errata documentation: warning: certain SEC interrupts
215 * are not fully cleared by writing the MCR:SWR bit,
216 * set bit twice to completely reset
217 */
218 err = reset_device(dev);
219 if (err)
220 return err;
221
222 err = reset_device(dev);
223 if (err)
224 return err;
225
226 /* reset channels */
227 for (ch = 0; ch < priv->num_channels; ch++) {
228 err = reset_channel(dev, ch);
229 if (err)
230 return err;
231 }
232
233 /* enable channel done and error interrupts */
LEROY Christophedd3c0982015-04-17 16:32:13 +0200234 if (is_sec1) {
235 clrbits32(priv->reg + TALITOS_IMR, TALITOS1_IMR_INIT);
236 clrbits32(priv->reg + TALITOS_IMR_LO, TALITOS1_IMR_LO_INIT);
237 /* disable parity error check in DEU (erroneous? test vect.) */
238 setbits32(priv->reg_deu + TALITOS_EUICR, TALITOS1_DEUICR_KPE);
239 } else {
240 setbits32(priv->reg + TALITOS_IMR, TALITOS2_IMR_INIT);
241 setbits32(priv->reg + TALITOS_IMR_LO, TALITOS2_IMR_LO_INIT);
242 }
Kim Phillips9c4a7962008-06-23 19:50:15 +0800243
Kim Phillipsfe5720e2008-10-12 20:33:14 +0800244 /* disable integrity check error interrupts (use writeback instead) */
245 if (priv->features & TALITOS_FTR_HW_AUTH_CHECK)
LEROY Christophe5fa7fa12015-04-17 16:32:11 +0200246 setbits32(priv->reg_mdeu + TALITOS_EUICR_LO,
Kim Phillipsfe5720e2008-10-12 20:33:14 +0800247 TALITOS_MDEUICR_LO_ICE);
248
Kim Phillips9c4a7962008-06-23 19:50:15 +0800249 return 0;
250}
251
252/**
253 * talitos_submit - submits a descriptor to the device for processing
254 * @dev: the SEC device to be used
Kim Phillips5228f0f2011-07-15 11:21:38 +0800255 * @ch: the SEC device channel to be used
Kim Phillips9c4a7962008-06-23 19:50:15 +0800256 * @desc: the descriptor to be processed by the device
257 * @callback: whom to call when processing is complete
258 * @context: a handle for use by caller (optional)
259 *
260 * desc must contain valid dma-mapped (bus physical) address pointers.
261 * callback must check err and feedback in descriptor header
262 * for device processing status.
263 */
Horia Geanta865d5062012-07-03 19:16:52 +0300264int talitos_submit(struct device *dev, int ch, struct talitos_desc *desc,
265 void (*callback)(struct device *dev,
266 struct talitos_desc *desc,
267 void *context, int error),
268 void *context)
Kim Phillips9c4a7962008-06-23 19:50:15 +0800269{
270 struct talitos_private *priv = dev_get_drvdata(dev);
271 struct talitos_request *request;
Kim Phillips5228f0f2011-07-15 11:21:38 +0800272 unsigned long flags;
Kim Phillips9c4a7962008-06-23 19:50:15 +0800273 int head;
LEROY Christophe7d607c6a2015-04-17 16:32:09 +0200274 bool is_sec1 = has_ftr_sec1(priv);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800275
Kim Phillips4b9926282009-08-13 11:50:38 +1000276 spin_lock_irqsave(&priv->chan[ch].head_lock, flags);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800277
Kim Phillips4b9926282009-08-13 11:50:38 +1000278 if (!atomic_inc_not_zero(&priv->chan[ch].submit_count)) {
Kim Phillipsec6644d2008-07-17 20:16:40 +0800279 /* h/w fifo is full */
Kim Phillips4b9926282009-08-13 11:50:38 +1000280 spin_unlock_irqrestore(&priv->chan[ch].head_lock, flags);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800281 return -EAGAIN;
282 }
283
Kim Phillips4b9926282009-08-13 11:50:38 +1000284 head = priv->chan[ch].head;
285 request = &priv->chan[ch].fifo[head];
Kim Phillipsec6644d2008-07-17 20:16:40 +0800286
Kim Phillips9c4a7962008-06-23 19:50:15 +0800287 /* map descriptor and save caller data */
LEROY Christophe7d607c6a2015-04-17 16:32:09 +0200288 if (is_sec1) {
289 desc->hdr1 = desc->hdr;
290 desc->next_desc = 0;
291 request->dma_desc = dma_map_single(dev, &desc->hdr1,
292 TALITOS_DESC_SIZE,
293 DMA_BIDIRECTIONAL);
294 } else {
295 request->dma_desc = dma_map_single(dev, desc,
296 TALITOS_DESC_SIZE,
297 DMA_BIDIRECTIONAL);
298 }
Kim Phillips9c4a7962008-06-23 19:50:15 +0800299 request->callback = callback;
300 request->context = context;
301
302 /* increment fifo head */
Kim Phillips4b9926282009-08-13 11:50:38 +1000303 priv->chan[ch].head = (priv->chan[ch].head + 1) & (priv->fifo_len - 1);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800304
305 smp_wmb();
306 request->desc = desc;
307
308 /* GO! */
309 wmb();
Kim Phillipsad42d5f2011-11-21 16:13:27 +0800310 out_be32(priv->chan[ch].reg + TALITOS_FF,
311 upper_32_bits(request->dma_desc));
312 out_be32(priv->chan[ch].reg + TALITOS_FF_LO,
Kim Phillipsa7524472010-09-23 15:56:38 +0800313 lower_32_bits(request->dma_desc));
Kim Phillips9c4a7962008-06-23 19:50:15 +0800314
Kim Phillips4b9926282009-08-13 11:50:38 +1000315 spin_unlock_irqrestore(&priv->chan[ch].head_lock, flags);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800316
317 return -EINPROGRESS;
318}
Horia Geanta865d5062012-07-03 19:16:52 +0300319EXPORT_SYMBOL(talitos_submit);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800320
321/*
322 * process what was done, notify callback of error if not
323 */
324static void flush_channel(struct device *dev, int ch, int error, int reset_ch)
325{
326 struct talitos_private *priv = dev_get_drvdata(dev);
327 struct talitos_request *request, saved_req;
328 unsigned long flags;
329 int tail, status;
LEROY Christophe7d607c6a2015-04-17 16:32:09 +0200330 bool is_sec1 = has_ftr_sec1(priv);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800331
Kim Phillips4b9926282009-08-13 11:50:38 +1000332 spin_lock_irqsave(&priv->chan[ch].tail_lock, flags);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800333
Kim Phillips4b9926282009-08-13 11:50:38 +1000334 tail = priv->chan[ch].tail;
335 while (priv->chan[ch].fifo[tail].desc) {
LEROY Christophe7d607c6a2015-04-17 16:32:09 +0200336 __be32 hdr;
337
Kim Phillips4b9926282009-08-13 11:50:38 +1000338 request = &priv->chan[ch].fifo[tail];
Kim Phillips9c4a7962008-06-23 19:50:15 +0800339
340 /* descriptors with their done bits set don't get the error */
341 rmb();
LEROY Christophe7d607c6a2015-04-17 16:32:09 +0200342 hdr = is_sec1 ? request->desc->hdr1 : request->desc->hdr;
343
344 if ((hdr & DESC_HDR_DONE) == DESC_HDR_DONE)
Kim Phillips9c4a7962008-06-23 19:50:15 +0800345 status = 0;
Lee Nipperca38a812008-12-20 17:09:25 +1100346 else
Kim Phillips9c4a7962008-06-23 19:50:15 +0800347 if (!error)
348 break;
349 else
350 status = error;
351
352 dma_unmap_single(dev, request->dma_desc,
LEROY Christophe7d607c6a2015-04-17 16:32:09 +0200353 TALITOS_DESC_SIZE,
Kim Phillipse938e462009-03-29 15:53:23 +0800354 DMA_BIDIRECTIONAL);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800355
356 /* copy entries so we can call callback outside lock */
357 saved_req.desc = request->desc;
358 saved_req.callback = request->callback;
359 saved_req.context = request->context;
360
361 /* release request entry in fifo */
362 smp_wmb();
363 request->desc = NULL;
364
365 /* increment fifo tail */
Kim Phillips4b9926282009-08-13 11:50:38 +1000366 priv->chan[ch].tail = (tail + 1) & (priv->fifo_len - 1);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800367
Kim Phillips4b9926282009-08-13 11:50:38 +1000368 spin_unlock_irqrestore(&priv->chan[ch].tail_lock, flags);
Kim Phillipsec6644d2008-07-17 20:16:40 +0800369
Kim Phillips4b9926282009-08-13 11:50:38 +1000370 atomic_dec(&priv->chan[ch].submit_count);
Kim Phillipsec6644d2008-07-17 20:16:40 +0800371
Kim Phillips9c4a7962008-06-23 19:50:15 +0800372 saved_req.callback(dev, saved_req.desc, saved_req.context,
373 status);
374 /* channel may resume processing in single desc error case */
375 if (error && !reset_ch && status == error)
376 return;
Kim Phillips4b9926282009-08-13 11:50:38 +1000377 spin_lock_irqsave(&priv->chan[ch].tail_lock, flags);
378 tail = priv->chan[ch].tail;
Kim Phillips9c4a7962008-06-23 19:50:15 +0800379 }
380
Kim Phillips4b9926282009-08-13 11:50:38 +1000381 spin_unlock_irqrestore(&priv->chan[ch].tail_lock, flags);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800382}
383
384/*
385 * process completed requests for channels that have done status
386 */
LEROY Christophedd3c0982015-04-17 16:32:13 +0200387#define DEF_TALITOS1_DONE(name, ch_done_mask) \
388static void talitos1_done_##name(unsigned long data) \
389{ \
390 struct device *dev = (struct device *)data; \
391 struct talitos_private *priv = dev_get_drvdata(dev); \
392 unsigned long flags; \
393 \
394 if (ch_done_mask & 0x10000000) \
395 flush_channel(dev, 0, 0, 0); \
396 if (priv->num_channels == 1) \
397 goto out; \
398 if (ch_done_mask & 0x40000000) \
399 flush_channel(dev, 1, 0, 0); \
400 if (ch_done_mask & 0x00010000) \
401 flush_channel(dev, 2, 0, 0); \
402 if (ch_done_mask & 0x00040000) \
403 flush_channel(dev, 3, 0, 0); \
404 \
405out: \
406 /* At this point, all completed channels have been processed */ \
407 /* Unmask done interrupts for channels completed later on. */ \
408 spin_lock_irqsave(&priv->reg_lock, flags); \
409 clrbits32(priv->reg + TALITOS_IMR, ch_done_mask); \
410 clrbits32(priv->reg + TALITOS_IMR_LO, TALITOS1_IMR_LO_INIT); \
411 spin_unlock_irqrestore(&priv->reg_lock, flags); \
412}
413
414DEF_TALITOS1_DONE(4ch, TALITOS1_ISR_4CHDONE)
415
416#define DEF_TALITOS2_DONE(name, ch_done_mask) \
417static void talitos2_done_##name(unsigned long data) \
Kim Phillipsc3e337f2011-11-21 16:13:27 +0800418{ \
419 struct device *dev = (struct device *)data; \
420 struct talitos_private *priv = dev_get_drvdata(dev); \
Horia Geanta511d63c2012-03-30 17:49:53 +0300421 unsigned long flags; \
Kim Phillipsc3e337f2011-11-21 16:13:27 +0800422 \
423 if (ch_done_mask & 1) \
424 flush_channel(dev, 0, 0, 0); \
425 if (priv->num_channels == 1) \
426 goto out; \
427 if (ch_done_mask & (1 << 2)) \
428 flush_channel(dev, 1, 0, 0); \
429 if (ch_done_mask & (1 << 4)) \
430 flush_channel(dev, 2, 0, 0); \
431 if (ch_done_mask & (1 << 6)) \
432 flush_channel(dev, 3, 0, 0); \
433 \
434out: \
435 /* At this point, all completed channels have been processed */ \
436 /* Unmask done interrupts for channels completed later on. */ \
Horia Geanta511d63c2012-03-30 17:49:53 +0300437 spin_lock_irqsave(&priv->reg_lock, flags); \
Kim Phillipsc3e337f2011-11-21 16:13:27 +0800438 setbits32(priv->reg + TALITOS_IMR, ch_done_mask); \
LEROY Christophedd3c0982015-04-17 16:32:13 +0200439 setbits32(priv->reg + TALITOS_IMR_LO, TALITOS2_IMR_LO_INIT); \
Horia Geanta511d63c2012-03-30 17:49:53 +0300440 spin_unlock_irqrestore(&priv->reg_lock, flags); \
Kim Phillips9c4a7962008-06-23 19:50:15 +0800441}
LEROY Christophedd3c0982015-04-17 16:32:13 +0200442
443DEF_TALITOS2_DONE(4ch, TALITOS2_ISR_4CHDONE)
444DEF_TALITOS2_DONE(ch0_2, TALITOS2_ISR_CH_0_2_DONE)
445DEF_TALITOS2_DONE(ch1_3, TALITOS2_ISR_CH_1_3_DONE)
Kim Phillips9c4a7962008-06-23 19:50:15 +0800446
447/*
448 * locate current (offending) descriptor
449 */
Kim Phillips3e721ae2011-10-21 15:20:28 +0200450static u32 current_desc_hdr(struct device *dev, int ch)
Kim Phillips9c4a7962008-06-23 19:50:15 +0800451{
452 struct talitos_private *priv = dev_get_drvdata(dev);
Horia Geantab62ffd82013-11-13 12:20:37 +0200453 int tail, iter;
Kim Phillips9c4a7962008-06-23 19:50:15 +0800454 dma_addr_t cur_desc;
455
Horia Geantab62ffd82013-11-13 12:20:37 +0200456 cur_desc = ((u64)in_be32(priv->chan[ch].reg + TALITOS_CDPR)) << 32;
457 cur_desc |= in_be32(priv->chan[ch].reg + TALITOS_CDPR_LO);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800458
Horia Geantab62ffd82013-11-13 12:20:37 +0200459 if (!cur_desc) {
460 dev_err(dev, "CDPR is NULL, giving up search for offending descriptor\n");
461 return 0;
462 }
463
464 tail = priv->chan[ch].tail;
465
466 iter = tail;
467 while (priv->chan[ch].fifo[iter].dma_desc != cur_desc) {
468 iter = (iter + 1) & (priv->fifo_len - 1);
469 if (iter == tail) {
Kim Phillips9c4a7962008-06-23 19:50:15 +0800470 dev_err(dev, "couldn't locate current descriptor\n");
Kim Phillips3e721ae2011-10-21 15:20:28 +0200471 return 0;
Kim Phillips9c4a7962008-06-23 19:50:15 +0800472 }
473 }
474
Horia Geantab62ffd82013-11-13 12:20:37 +0200475 return priv->chan[ch].fifo[iter].desc->hdr;
Kim Phillips9c4a7962008-06-23 19:50:15 +0800476}
477
478/*
479 * user diagnostics; report root cause of error based on execution unit status
480 */
Kim Phillips3e721ae2011-10-21 15:20:28 +0200481static void report_eu_error(struct device *dev, int ch, u32 desc_hdr)
Kim Phillips9c4a7962008-06-23 19:50:15 +0800482{
483 struct talitos_private *priv = dev_get_drvdata(dev);
484 int i;
485
Kim Phillips3e721ae2011-10-21 15:20:28 +0200486 if (!desc_hdr)
Kim Phillipsad42d5f2011-11-21 16:13:27 +0800487 desc_hdr = in_be32(priv->chan[ch].reg + TALITOS_DESCBUF);
Kim Phillips3e721ae2011-10-21 15:20:28 +0200488
489 switch (desc_hdr & DESC_HDR_SEL0_MASK) {
Kim Phillips9c4a7962008-06-23 19:50:15 +0800490 case DESC_HDR_SEL0_AFEU:
491 dev_err(dev, "AFEUISR 0x%08x_%08x\n",
LEROY Christophe5fa7fa12015-04-17 16:32:11 +0200492 in_be32(priv->reg_afeu + TALITOS_EUISR),
493 in_be32(priv->reg_afeu + TALITOS_EUISR_LO));
Kim Phillips9c4a7962008-06-23 19:50:15 +0800494 break;
495 case DESC_HDR_SEL0_DEU:
496 dev_err(dev, "DEUISR 0x%08x_%08x\n",
LEROY Christophe5fa7fa12015-04-17 16:32:11 +0200497 in_be32(priv->reg_deu + TALITOS_EUISR),
498 in_be32(priv->reg_deu + TALITOS_EUISR_LO));
Kim Phillips9c4a7962008-06-23 19:50:15 +0800499 break;
500 case DESC_HDR_SEL0_MDEUA:
501 case DESC_HDR_SEL0_MDEUB:
502 dev_err(dev, "MDEUISR 0x%08x_%08x\n",
LEROY Christophe5fa7fa12015-04-17 16:32:11 +0200503 in_be32(priv->reg_mdeu + TALITOS_EUISR),
504 in_be32(priv->reg_mdeu + TALITOS_EUISR_LO));
Kim Phillips9c4a7962008-06-23 19:50:15 +0800505 break;
506 case DESC_HDR_SEL0_RNG:
507 dev_err(dev, "RNGUISR 0x%08x_%08x\n",
LEROY Christophe5fa7fa12015-04-17 16:32:11 +0200508 in_be32(priv->reg_rngu + TALITOS_ISR),
509 in_be32(priv->reg_rngu + TALITOS_ISR_LO));
Kim Phillips9c4a7962008-06-23 19:50:15 +0800510 break;
511 case DESC_HDR_SEL0_PKEU:
512 dev_err(dev, "PKEUISR 0x%08x_%08x\n",
LEROY Christophe5fa7fa12015-04-17 16:32:11 +0200513 in_be32(priv->reg_pkeu + TALITOS_EUISR),
514 in_be32(priv->reg_pkeu + TALITOS_EUISR_LO));
Kim Phillips9c4a7962008-06-23 19:50:15 +0800515 break;
516 case DESC_HDR_SEL0_AESU:
517 dev_err(dev, "AESUISR 0x%08x_%08x\n",
LEROY Christophe5fa7fa12015-04-17 16:32:11 +0200518 in_be32(priv->reg_aesu + TALITOS_EUISR),
519 in_be32(priv->reg_aesu + TALITOS_EUISR_LO));
Kim Phillips9c4a7962008-06-23 19:50:15 +0800520 break;
521 case DESC_HDR_SEL0_CRCU:
522 dev_err(dev, "CRCUISR 0x%08x_%08x\n",
LEROY Christophe5fa7fa12015-04-17 16:32:11 +0200523 in_be32(priv->reg_crcu + TALITOS_EUISR),
524 in_be32(priv->reg_crcu + TALITOS_EUISR_LO));
Kim Phillips9c4a7962008-06-23 19:50:15 +0800525 break;
526 case DESC_HDR_SEL0_KEU:
527 dev_err(dev, "KEUISR 0x%08x_%08x\n",
LEROY Christophe5fa7fa12015-04-17 16:32:11 +0200528 in_be32(priv->reg_pkeu + TALITOS_EUISR),
529 in_be32(priv->reg_pkeu + TALITOS_EUISR_LO));
Kim Phillips9c4a7962008-06-23 19:50:15 +0800530 break;
531 }
532
Kim Phillips3e721ae2011-10-21 15:20:28 +0200533 switch (desc_hdr & DESC_HDR_SEL1_MASK) {
Kim Phillips9c4a7962008-06-23 19:50:15 +0800534 case DESC_HDR_SEL1_MDEUA:
535 case DESC_HDR_SEL1_MDEUB:
536 dev_err(dev, "MDEUISR 0x%08x_%08x\n",
LEROY Christophe5fa7fa12015-04-17 16:32:11 +0200537 in_be32(priv->reg_mdeu + TALITOS_EUISR),
538 in_be32(priv->reg_mdeu + TALITOS_EUISR_LO));
Kim Phillips9c4a7962008-06-23 19:50:15 +0800539 break;
540 case DESC_HDR_SEL1_CRCU:
541 dev_err(dev, "CRCUISR 0x%08x_%08x\n",
LEROY Christophe5fa7fa12015-04-17 16:32:11 +0200542 in_be32(priv->reg_crcu + TALITOS_EUISR),
543 in_be32(priv->reg_crcu + TALITOS_EUISR_LO));
Kim Phillips9c4a7962008-06-23 19:50:15 +0800544 break;
545 }
546
547 for (i = 0; i < 8; i++)
548 dev_err(dev, "DESCBUF 0x%08x_%08x\n",
Kim Phillipsad42d5f2011-11-21 16:13:27 +0800549 in_be32(priv->chan[ch].reg + TALITOS_DESCBUF + 8*i),
550 in_be32(priv->chan[ch].reg + TALITOS_DESCBUF_LO + 8*i));
Kim Phillips9c4a7962008-06-23 19:50:15 +0800551}
552
553/*
554 * recover from error interrupts
555 */
Kim Phillips5e718a02011-12-12 14:59:12 -0600556static void talitos_error(struct device *dev, u32 isr, u32 isr_lo)
Kim Phillips9c4a7962008-06-23 19:50:15 +0800557{
Kim Phillips9c4a7962008-06-23 19:50:15 +0800558 struct talitos_private *priv = dev_get_drvdata(dev);
559 unsigned int timeout = TALITOS_TIMEOUT;
LEROY Christophedd3c0982015-04-17 16:32:13 +0200560 int ch, error, reset_dev = 0;
Horia Geant?42e8b0d2015-05-11 20:04:56 +0300561 u32 v_lo;
LEROY Christophedd3c0982015-04-17 16:32:13 +0200562 bool is_sec1 = has_ftr_sec1(priv);
563 int reset_ch = is_sec1 ? 1 : 0; /* only SEC2 supports continuation */
Kim Phillips9c4a7962008-06-23 19:50:15 +0800564
565 for (ch = 0; ch < priv->num_channels; ch++) {
566 /* skip channels without errors */
LEROY Christophedd3c0982015-04-17 16:32:13 +0200567 if (is_sec1) {
568 /* bits 29, 31, 17, 19 */
569 if (!(isr & (1 << (29 + (ch & 1) * 2 - (ch & 2) * 6))))
570 continue;
571 } else {
572 if (!(isr & (1 << (ch * 2 + 1))))
573 continue;
574 }
Kim Phillips9c4a7962008-06-23 19:50:15 +0800575
576 error = -EINVAL;
577
Kim Phillipsad42d5f2011-11-21 16:13:27 +0800578 v_lo = in_be32(priv->chan[ch].reg + TALITOS_CCPSR_LO);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800579
580 if (v_lo & TALITOS_CCPSR_LO_DOF) {
581 dev_err(dev, "double fetch fifo overflow error\n");
582 error = -EAGAIN;
583 reset_ch = 1;
584 }
585 if (v_lo & TALITOS_CCPSR_LO_SOF) {
586 /* h/w dropped descriptor */
587 dev_err(dev, "single fetch fifo overflow error\n");
588 error = -EAGAIN;
589 }
590 if (v_lo & TALITOS_CCPSR_LO_MDTE)
591 dev_err(dev, "master data transfer error\n");
592 if (v_lo & TALITOS_CCPSR_LO_SGDLZ)
LEROY Christophedd3c0982015-04-17 16:32:13 +0200593 dev_err(dev, is_sec1 ? "pointeur not complete error\n"
594 : "s/g data length zero error\n");
Kim Phillips9c4a7962008-06-23 19:50:15 +0800595 if (v_lo & TALITOS_CCPSR_LO_FPZ)
LEROY Christophedd3c0982015-04-17 16:32:13 +0200596 dev_err(dev, is_sec1 ? "parity error\n"
597 : "fetch pointer zero error\n");
Kim Phillips9c4a7962008-06-23 19:50:15 +0800598 if (v_lo & TALITOS_CCPSR_LO_IDH)
599 dev_err(dev, "illegal descriptor header error\n");
600 if (v_lo & TALITOS_CCPSR_LO_IEU)
LEROY Christophedd3c0982015-04-17 16:32:13 +0200601 dev_err(dev, is_sec1 ? "static assignment error\n"
602 : "invalid exec unit error\n");
Kim Phillips9c4a7962008-06-23 19:50:15 +0800603 if (v_lo & TALITOS_CCPSR_LO_EU)
Kim Phillips3e721ae2011-10-21 15:20:28 +0200604 report_eu_error(dev, ch, current_desc_hdr(dev, ch));
LEROY Christophedd3c0982015-04-17 16:32:13 +0200605 if (!is_sec1) {
606 if (v_lo & TALITOS_CCPSR_LO_GB)
607 dev_err(dev, "gather boundary error\n");
608 if (v_lo & TALITOS_CCPSR_LO_GRL)
609 dev_err(dev, "gather return/length error\n");
610 if (v_lo & TALITOS_CCPSR_LO_SB)
611 dev_err(dev, "scatter boundary error\n");
612 if (v_lo & TALITOS_CCPSR_LO_SRL)
613 dev_err(dev, "scatter return/length error\n");
614 }
Kim Phillips9c4a7962008-06-23 19:50:15 +0800615
616 flush_channel(dev, ch, error, reset_ch);
617
618 if (reset_ch) {
619 reset_channel(dev, ch);
620 } else {
Kim Phillipsad42d5f2011-11-21 16:13:27 +0800621 setbits32(priv->chan[ch].reg + TALITOS_CCCR,
LEROY Christophedd3c0982015-04-17 16:32:13 +0200622 TALITOS2_CCCR_CONT);
Kim Phillipsad42d5f2011-11-21 16:13:27 +0800623 setbits32(priv->chan[ch].reg + TALITOS_CCCR_LO, 0);
624 while ((in_be32(priv->chan[ch].reg + TALITOS_CCCR) &
LEROY Christophedd3c0982015-04-17 16:32:13 +0200625 TALITOS2_CCCR_CONT) && --timeout)
Kim Phillips9c4a7962008-06-23 19:50:15 +0800626 cpu_relax();
627 if (timeout == 0) {
628 dev_err(dev, "failed to restart channel %d\n",
629 ch);
630 reset_dev = 1;
631 }
632 }
633 }
LEROY Christophedd3c0982015-04-17 16:32:13 +0200634 if (reset_dev || (is_sec1 && isr & ~TALITOS1_ISR_4CHERR) ||
635 (!is_sec1 && isr & ~TALITOS2_ISR_4CHERR) || isr_lo) {
636 if (is_sec1 && (isr_lo & TALITOS1_ISR_TEA_ERR))
637 dev_err(dev, "TEA error: ISR 0x%08x_%08x\n",
638 isr, isr_lo);
639 else
640 dev_err(dev, "done overflow, internal time out, or "
641 "rngu error: ISR 0x%08x_%08x\n", isr, isr_lo);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800642
643 /* purge request queues */
644 for (ch = 0; ch < priv->num_channels; ch++)
645 flush_channel(dev, ch, -EIO, 1);
646
647 /* reset and reinitialize the device */
648 init_device(dev);
649 }
650}
651
LEROY Christophedd3c0982015-04-17 16:32:13 +0200652#define DEF_TALITOS1_INTERRUPT(name, ch_done_mask, ch_err_mask, tlet) \
653static irqreturn_t talitos1_interrupt_##name(int irq, void *data) \
654{ \
655 struct device *dev = data; \
656 struct talitos_private *priv = dev_get_drvdata(dev); \
657 u32 isr, isr_lo; \
658 unsigned long flags; \
659 \
660 spin_lock_irqsave(&priv->reg_lock, flags); \
661 isr = in_be32(priv->reg + TALITOS_ISR); \
662 isr_lo = in_be32(priv->reg + TALITOS_ISR_LO); \
663 /* Acknowledge interrupt */ \
664 out_be32(priv->reg + TALITOS_ICR, isr & (ch_done_mask | ch_err_mask)); \
665 out_be32(priv->reg + TALITOS_ICR_LO, isr_lo); \
666 \
667 if (unlikely(isr & ch_err_mask || isr_lo & TALITOS1_IMR_LO_INIT)) { \
668 spin_unlock_irqrestore(&priv->reg_lock, flags); \
669 talitos_error(dev, isr & ch_err_mask, isr_lo); \
670 } \
671 else { \
672 if (likely(isr & ch_done_mask)) { \
673 /* mask further done interrupts. */ \
674 setbits32(priv->reg + TALITOS_IMR, ch_done_mask); \
675 /* done_task will unmask done interrupts at exit */ \
676 tasklet_schedule(&priv->done_task[tlet]); \
677 } \
678 spin_unlock_irqrestore(&priv->reg_lock, flags); \
679 } \
680 \
681 return (isr & (ch_done_mask | ch_err_mask) || isr_lo) ? IRQ_HANDLED : \
682 IRQ_NONE; \
683}
684
685DEF_TALITOS1_INTERRUPT(4ch, TALITOS1_ISR_4CHDONE, TALITOS1_ISR_4CHERR, 0)
686
687#define DEF_TALITOS2_INTERRUPT(name, ch_done_mask, ch_err_mask, tlet) \
688static irqreturn_t talitos2_interrupt_##name(int irq, void *data) \
Kim Phillipsc3e337f2011-11-21 16:13:27 +0800689{ \
690 struct device *dev = data; \
691 struct talitos_private *priv = dev_get_drvdata(dev); \
692 u32 isr, isr_lo; \
Horia Geanta511d63c2012-03-30 17:49:53 +0300693 unsigned long flags; \
Kim Phillipsc3e337f2011-11-21 16:13:27 +0800694 \
Horia Geanta511d63c2012-03-30 17:49:53 +0300695 spin_lock_irqsave(&priv->reg_lock, flags); \
Kim Phillipsc3e337f2011-11-21 16:13:27 +0800696 isr = in_be32(priv->reg + TALITOS_ISR); \
697 isr_lo = in_be32(priv->reg + TALITOS_ISR_LO); \
698 /* Acknowledge interrupt */ \
699 out_be32(priv->reg + TALITOS_ICR, isr & (ch_done_mask | ch_err_mask)); \
700 out_be32(priv->reg + TALITOS_ICR_LO, isr_lo); \
701 \
Horia Geanta511d63c2012-03-30 17:49:53 +0300702 if (unlikely(isr & ch_err_mask || isr_lo)) { \
703 spin_unlock_irqrestore(&priv->reg_lock, flags); \
704 talitos_error(dev, isr & ch_err_mask, isr_lo); \
705 } \
706 else { \
Kim Phillipsc3e337f2011-11-21 16:13:27 +0800707 if (likely(isr & ch_done_mask)) { \
708 /* mask further done interrupts. */ \
709 clrbits32(priv->reg + TALITOS_IMR, ch_done_mask); \
710 /* done_task will unmask done interrupts at exit */ \
711 tasklet_schedule(&priv->done_task[tlet]); \
712 } \
Horia Geanta511d63c2012-03-30 17:49:53 +0300713 spin_unlock_irqrestore(&priv->reg_lock, flags); \
714 } \
Kim Phillipsc3e337f2011-11-21 16:13:27 +0800715 \
716 return (isr & (ch_done_mask | ch_err_mask) || isr_lo) ? IRQ_HANDLED : \
717 IRQ_NONE; \
Kim Phillips9c4a7962008-06-23 19:50:15 +0800718}
LEROY Christophedd3c0982015-04-17 16:32:13 +0200719
720DEF_TALITOS2_INTERRUPT(4ch, TALITOS2_ISR_4CHDONE, TALITOS2_ISR_4CHERR, 0)
721DEF_TALITOS2_INTERRUPT(ch0_2, TALITOS2_ISR_CH_0_2_DONE, TALITOS2_ISR_CH_0_2_ERR,
722 0)
723DEF_TALITOS2_INTERRUPT(ch1_3, TALITOS2_ISR_CH_1_3_DONE, TALITOS2_ISR_CH_1_3_ERR,
724 1)
Kim Phillips9c4a7962008-06-23 19:50:15 +0800725
726/*
727 * hwrng
728 */
729static int talitos_rng_data_present(struct hwrng *rng, int wait)
730{
731 struct device *dev = (struct device *)rng->priv;
732 struct talitos_private *priv = dev_get_drvdata(dev);
733 u32 ofl;
734 int i;
735
736 for (i = 0; i < 20; i++) {
LEROY Christophe5fa7fa12015-04-17 16:32:11 +0200737 ofl = in_be32(priv->reg_rngu + TALITOS_EUSR_LO) &
Kim Phillips9c4a7962008-06-23 19:50:15 +0800738 TALITOS_RNGUSR_LO_OFL;
739 if (ofl || !wait)
740 break;
741 udelay(10);
742 }
743
744 return !!ofl;
745}
746
747static int talitos_rng_data_read(struct hwrng *rng, u32 *data)
748{
749 struct device *dev = (struct device *)rng->priv;
750 struct talitos_private *priv = dev_get_drvdata(dev);
751
752 /* rng fifo requires 64-bit accesses */
LEROY Christophe5fa7fa12015-04-17 16:32:11 +0200753 *data = in_be32(priv->reg_rngu + TALITOS_EU_FIFO);
754 *data = in_be32(priv->reg_rngu + TALITOS_EU_FIFO_LO);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800755
756 return sizeof(u32);
757}
758
759static int talitos_rng_init(struct hwrng *rng)
760{
761 struct device *dev = (struct device *)rng->priv;
762 struct talitos_private *priv = dev_get_drvdata(dev);
763 unsigned int timeout = TALITOS_TIMEOUT;
764
LEROY Christophe5fa7fa12015-04-17 16:32:11 +0200765 setbits32(priv->reg_rngu + TALITOS_EURCR_LO, TALITOS_RNGURCR_LO_SR);
766 while (!(in_be32(priv->reg_rngu + TALITOS_EUSR_LO)
767 & TALITOS_RNGUSR_LO_RD)
Kim Phillips9c4a7962008-06-23 19:50:15 +0800768 && --timeout)
769 cpu_relax();
770 if (timeout == 0) {
771 dev_err(dev, "failed to reset rng hw\n");
772 return -ENODEV;
773 }
774
775 /* start generating */
LEROY Christophe5fa7fa12015-04-17 16:32:11 +0200776 setbits32(priv->reg_rngu + TALITOS_EUDSR_LO, 0);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800777
778 return 0;
779}
780
781static int talitos_register_rng(struct device *dev)
782{
783 struct talitos_private *priv = dev_get_drvdata(dev);
Aaron Sierra35a3bb32015-08-05 16:52:08 -0500784 int err;
Kim Phillips9c4a7962008-06-23 19:50:15 +0800785
786 priv->rng.name = dev_driver_string(dev),
787 priv->rng.init = talitos_rng_init,
788 priv->rng.data_present = talitos_rng_data_present,
789 priv->rng.data_read = talitos_rng_data_read,
790 priv->rng.priv = (unsigned long)dev;
791
Aaron Sierra35a3bb32015-08-05 16:52:08 -0500792 err = hwrng_register(&priv->rng);
793 if (!err)
794 priv->rng_registered = true;
795
796 return err;
Kim Phillips9c4a7962008-06-23 19:50:15 +0800797}
798
799static void talitos_unregister_rng(struct device *dev)
800{
801 struct talitos_private *priv = dev_get_drvdata(dev);
802
Aaron Sierra35a3bb32015-08-05 16:52:08 -0500803 if (!priv->rng_registered)
804 return;
805
Kim Phillips9c4a7962008-06-23 19:50:15 +0800806 hwrng_unregister(&priv->rng);
Aaron Sierra35a3bb32015-08-05 16:52:08 -0500807 priv->rng_registered = false;
Kim Phillips9c4a7962008-06-23 19:50:15 +0800808}
809
810/*
811 * crypto alg
812 */
813#define TALITOS_CRA_PRIORITY 3000
Horia Geanta357fb602012-07-03 19:16:53 +0300814#define TALITOS_MAX_KEY_SIZE 96
Lee Nipper3952f172008-07-10 18:29:18 +0800815#define TALITOS_MAX_IV_LENGTH 16 /* max of AES_BLOCK_SIZE, DES3_EDE_BLOCK_SIZE */
Lee Nipper70bcaca2008-07-03 19:08:46 +0800816
Kim Phillips9c4a7962008-06-23 19:50:15 +0800817struct talitos_ctx {
818 struct device *dev;
Kim Phillips5228f0f2011-07-15 11:21:38 +0800819 int ch;
Kim Phillips9c4a7962008-06-23 19:50:15 +0800820 __be32 desc_hdr_template;
821 u8 key[TALITOS_MAX_KEY_SIZE];
Lee Nipper70bcaca2008-07-03 19:08:46 +0800822 u8 iv[TALITOS_MAX_IV_LENGTH];
Kim Phillips9c4a7962008-06-23 19:50:15 +0800823 unsigned int keylen;
824 unsigned int enckeylen;
825 unsigned int authkeylen;
Kim Phillips9c4a7962008-06-23 19:50:15 +0800826};
827
Lee Nipper497f2e62010-05-19 19:20:36 +1000828#define HASH_MAX_BLOCK_SIZE SHA512_BLOCK_SIZE
829#define TALITOS_MDEU_MAX_CONTEXT_SIZE TALITOS_MDEU_CONTEXT_SIZE_SHA384_SHA512
830
831struct talitos_ahash_req_ctx {
Kim Phillips60f208d2010-05-19 19:21:53 +1000832 u32 hw_context[TALITOS_MDEU_MAX_CONTEXT_SIZE / sizeof(u32)];
Lee Nipper497f2e62010-05-19 19:20:36 +1000833 unsigned int hw_context_size;
834 u8 buf[HASH_MAX_BLOCK_SIZE];
835 u8 bufnext[HASH_MAX_BLOCK_SIZE];
Kim Phillips60f208d2010-05-19 19:21:53 +1000836 unsigned int swinit;
Lee Nipper497f2e62010-05-19 19:20:36 +1000837 unsigned int first;
838 unsigned int last;
839 unsigned int to_hash_later;
Horia Geant?42e8b0d2015-05-11 20:04:56 +0300840 unsigned int nbuf;
Lee Nipper497f2e62010-05-19 19:20:36 +1000841 struct scatterlist bufsl[2];
842 struct scatterlist *psrc;
843};
844
Horia Geant?3639ca82016-04-21 19:24:55 +0300845struct talitos_export_state {
846 u32 hw_context[TALITOS_MDEU_MAX_CONTEXT_SIZE / sizeof(u32)];
847 u8 buf[HASH_MAX_BLOCK_SIZE];
848 unsigned int swinit;
849 unsigned int first;
850 unsigned int last;
851 unsigned int to_hash_later;
852 unsigned int nbuf;
853};
854
Lee Nipper56af8cd2009-03-29 15:50:50 +0800855static int aead_setkey(struct crypto_aead *authenc,
856 const u8 *key, unsigned int keylen)
Kim Phillips9c4a7962008-06-23 19:50:15 +0800857{
858 struct talitos_ctx *ctx = crypto_aead_ctx(authenc);
Mathias Krausec306a982013-10-15 13:49:34 +0200859 struct crypto_authenc_keys keys;
Kim Phillips9c4a7962008-06-23 19:50:15 +0800860
Mathias Krausec306a982013-10-15 13:49:34 +0200861 if (crypto_authenc_extractkeys(&keys, key, keylen) != 0)
Kim Phillips9c4a7962008-06-23 19:50:15 +0800862 goto badkey;
863
Mathias Krausec306a982013-10-15 13:49:34 +0200864 if (keys.authkeylen + keys.enckeylen > TALITOS_MAX_KEY_SIZE)
Kim Phillips9c4a7962008-06-23 19:50:15 +0800865 goto badkey;
866
Mathias Krausec306a982013-10-15 13:49:34 +0200867 memcpy(ctx->key, keys.authkey, keys.authkeylen);
868 memcpy(&ctx->key[keys.authkeylen], keys.enckey, keys.enckeylen);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800869
Mathias Krausec306a982013-10-15 13:49:34 +0200870 ctx->keylen = keys.authkeylen + keys.enckeylen;
871 ctx->enckeylen = keys.enckeylen;
872 ctx->authkeylen = keys.authkeylen;
Kim Phillips9c4a7962008-06-23 19:50:15 +0800873
874 return 0;
875
876badkey:
877 crypto_aead_set_flags(authenc, CRYPTO_TFM_RES_BAD_KEY_LEN);
878 return -EINVAL;
879}
880
881/*
Lee Nipper56af8cd2009-03-29 15:50:50 +0800882 * talitos_edesc - s/w-extended descriptor
Kim Phillips9c4a7962008-06-23 19:50:15 +0800883 * @src_nents: number of segments in input scatterlist
884 * @dst_nents: number of segments in output scatterlist
Herbert Xuaeb4c132015-07-30 17:53:22 +0800885 * @icv_ool: whether ICV is out-of-line
Horia Geanta79fd31d2012-08-02 17:16:40 +0300886 * @iv_dma: dma address of iv for checking continuity and link table
Kim Phillips9c4a7962008-06-23 19:50:15 +0800887 * @dma_len: length of dma mapped link_tbl space
LEROY Christophe6f65f6a2015-04-17 16:32:15 +0200888 * @dma_link_tbl: bus physical address of link_tbl/buf
Kim Phillips9c4a7962008-06-23 19:50:15 +0800889 * @desc: h/w descriptor
LEROY Christophe6f65f6a2015-04-17 16:32:15 +0200890 * @link_tbl: input and output h/w link tables (if {src,dst}_nents > 1) (SEC2)
891 * @buf: input and output buffeur (if {src,dst}_nents > 1) (SEC1)
Kim Phillips9c4a7962008-06-23 19:50:15 +0800892 *
893 * if decrypting (with authcheck), or either one of src_nents or dst_nents
894 * is greater than 1, an integrity check value is concatenated to the end
895 * of link_tbl data
896 */
Lee Nipper56af8cd2009-03-29 15:50:50 +0800897struct talitos_edesc {
Kim Phillips9c4a7962008-06-23 19:50:15 +0800898 int src_nents;
899 int dst_nents;
Herbert Xuaeb4c132015-07-30 17:53:22 +0800900 bool icv_ool;
Horia Geanta79fd31d2012-08-02 17:16:40 +0300901 dma_addr_t iv_dma;
Kim Phillips9c4a7962008-06-23 19:50:15 +0800902 int dma_len;
903 dma_addr_t dma_link_tbl;
904 struct talitos_desc desc;
LEROY Christophe6f65f6a2015-04-17 16:32:15 +0200905 union {
906 struct talitos_ptr link_tbl[0];
907 u8 buf[0];
908 };
Kim Phillips9c4a7962008-06-23 19:50:15 +0800909};
910
Lee Nipper4de9d0b2009-03-29 15:52:32 +0800911static void talitos_sg_unmap(struct device *dev,
912 struct talitos_edesc *edesc,
913 struct scatterlist *src,
914 struct scatterlist *dst)
915{
916 unsigned int src_nents = edesc->src_nents ? : 1;
917 unsigned int dst_nents = edesc->dst_nents ? : 1;
918
919 if (src != dst) {
LABBE Corentinb8a011d2015-09-23 13:55:25 +0200920 dma_unmap_sg(dev, src, src_nents, DMA_TO_DEVICE);
Lee Nipper4de9d0b2009-03-29 15:52:32 +0800921
Lee Nipper497f2e62010-05-19 19:20:36 +1000922 if (dst) {
LABBE Corentinb8a011d2015-09-23 13:55:25 +0200923 dma_unmap_sg(dev, dst, dst_nents, DMA_FROM_DEVICE);
Lee Nipper497f2e62010-05-19 19:20:36 +1000924 }
Lee Nipper4de9d0b2009-03-29 15:52:32 +0800925 } else
LABBE Corentinb8a011d2015-09-23 13:55:25 +0200926 dma_unmap_sg(dev, src, src_nents, DMA_BIDIRECTIONAL);
Lee Nipper4de9d0b2009-03-29 15:52:32 +0800927}
928
Kim Phillips9c4a7962008-06-23 19:50:15 +0800929static void ipsec_esp_unmap(struct device *dev,
Lee Nipper56af8cd2009-03-29 15:50:50 +0800930 struct talitos_edesc *edesc,
Kim Phillips9c4a7962008-06-23 19:50:15 +0800931 struct aead_request *areq)
932{
933 unmap_single_talitos_ptr(dev, &edesc->desc.ptr[6], DMA_FROM_DEVICE);
934 unmap_single_talitos_ptr(dev, &edesc->desc.ptr[3], DMA_TO_DEVICE);
935 unmap_single_talitos_ptr(dev, &edesc->desc.ptr[2], DMA_TO_DEVICE);
936 unmap_single_talitos_ptr(dev, &edesc->desc.ptr[0], DMA_TO_DEVICE);
937
Lee Nipper4de9d0b2009-03-29 15:52:32 +0800938 talitos_sg_unmap(dev, edesc, areq->src, areq->dst);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800939
940 if (edesc->dma_len)
941 dma_unmap_single(dev, edesc->dma_link_tbl, edesc->dma_len,
942 DMA_BIDIRECTIONAL);
943}
944
945/*
946 * ipsec_esp descriptor callbacks
947 */
948static void ipsec_esp_encrypt_done(struct device *dev,
949 struct talitos_desc *desc, void *context,
950 int err)
951{
952 struct aead_request *areq = context;
Kim Phillips9c4a7962008-06-23 19:50:15 +0800953 struct crypto_aead *authenc = crypto_aead_reqtfm(areq);
Herbert Xuaeb4c132015-07-30 17:53:22 +0800954 unsigned int authsize = crypto_aead_authsize(authenc);
Kim Phillips19bbbc62009-03-29 15:53:59 +0800955 struct talitos_edesc *edesc;
Kim Phillips9c4a7962008-06-23 19:50:15 +0800956 struct scatterlist *sg;
957 void *icvdata;
958
Kim Phillips19bbbc62009-03-29 15:53:59 +0800959 edesc = container_of(desc, struct talitos_edesc, desc);
960
Kim Phillips9c4a7962008-06-23 19:50:15 +0800961 ipsec_esp_unmap(dev, edesc, areq);
962
963 /* copy the generated ICV to dst */
Herbert Xuaeb4c132015-07-30 17:53:22 +0800964 if (edesc->icv_ool) {
Kim Phillips9c4a7962008-06-23 19:50:15 +0800965 icvdata = &edesc->link_tbl[edesc->src_nents +
Herbert Xuaeb4c132015-07-30 17:53:22 +0800966 edesc->dst_nents + 2];
Kim Phillips9c4a7962008-06-23 19:50:15 +0800967 sg = sg_last(areq->dst, edesc->dst_nents);
Herbert Xuaeb4c132015-07-30 17:53:22 +0800968 memcpy((char *)sg_virt(sg) + sg->length - authsize,
969 icvdata, authsize);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800970 }
971
972 kfree(edesc);
973
974 aead_request_complete(areq, err);
975}
976
Kim Phillipsfe5720e2008-10-12 20:33:14 +0800977static void ipsec_esp_decrypt_swauth_done(struct device *dev,
Kim Phillipse938e462009-03-29 15:53:23 +0800978 struct talitos_desc *desc,
979 void *context, int err)
Kim Phillips9c4a7962008-06-23 19:50:15 +0800980{
981 struct aead_request *req = context;
Kim Phillips9c4a7962008-06-23 19:50:15 +0800982 struct crypto_aead *authenc = crypto_aead_reqtfm(req);
Herbert Xuaeb4c132015-07-30 17:53:22 +0800983 unsigned int authsize = crypto_aead_authsize(authenc);
Kim Phillips19bbbc62009-03-29 15:53:59 +0800984 struct talitos_edesc *edesc;
Kim Phillips9c4a7962008-06-23 19:50:15 +0800985 struct scatterlist *sg;
Herbert Xuaeb4c132015-07-30 17:53:22 +0800986 char *oicv, *icv;
Kim Phillips9c4a7962008-06-23 19:50:15 +0800987
Kim Phillips19bbbc62009-03-29 15:53:59 +0800988 edesc = container_of(desc, struct talitos_edesc, desc);
989
Kim Phillips9c4a7962008-06-23 19:50:15 +0800990 ipsec_esp_unmap(dev, edesc, req);
991
992 if (!err) {
993 /* auth check */
Kim Phillips9c4a7962008-06-23 19:50:15 +0800994 sg = sg_last(req->dst, edesc->dst_nents ? : 1);
Herbert Xuaeb4c132015-07-30 17:53:22 +0800995 icv = (char *)sg_virt(sg) + sg->length - authsize;
996
997 if (edesc->dma_len) {
998 oicv = (char *)&edesc->link_tbl[edesc->src_nents +
999 edesc->dst_nents + 2];
1000 if (edesc->icv_ool)
1001 icv = oicv + authsize;
1002 } else
1003 oicv = (char *)&edesc->link_tbl[0];
1004
David Gstir79960942015-11-15 17:14:42 +01001005 err = crypto_memneq(oicv, icv, authsize) ? -EBADMSG : 0;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001006 }
1007
1008 kfree(edesc);
1009
1010 aead_request_complete(req, err);
1011}
1012
Kim Phillipsfe5720e2008-10-12 20:33:14 +08001013static void ipsec_esp_decrypt_hwauth_done(struct device *dev,
Kim Phillipse938e462009-03-29 15:53:23 +08001014 struct talitos_desc *desc,
1015 void *context, int err)
Kim Phillipsfe5720e2008-10-12 20:33:14 +08001016{
1017 struct aead_request *req = context;
Kim Phillips19bbbc62009-03-29 15:53:59 +08001018 struct talitos_edesc *edesc;
1019
1020 edesc = container_of(desc, struct talitos_edesc, desc);
Kim Phillipsfe5720e2008-10-12 20:33:14 +08001021
1022 ipsec_esp_unmap(dev, edesc, req);
1023
1024 /* check ICV auth status */
Kim Phillipse938e462009-03-29 15:53:23 +08001025 if (!err && ((desc->hdr_lo & DESC_HDR_LO_ICCR1_MASK) !=
1026 DESC_HDR_LO_ICCR1_PASS))
1027 err = -EBADMSG;
Kim Phillipsfe5720e2008-10-12 20:33:14 +08001028
1029 kfree(edesc);
1030
1031 aead_request_complete(req, err);
1032}
1033
Kim Phillips9c4a7962008-06-23 19:50:15 +08001034/*
1035 * convert scatterlist to SEC h/w link table format
1036 * stop at cryptlen bytes
1037 */
Herbert Xuaeb4c132015-07-30 17:53:22 +08001038static int sg_to_link_tbl_offset(struct scatterlist *sg, int sg_count,
1039 unsigned int offset, int cryptlen,
1040 struct talitos_ptr *link_tbl_ptr)
Kim Phillips9c4a7962008-06-23 19:50:15 +08001041{
Lee Nipper70bcaca2008-07-03 19:08:46 +08001042 int n_sg = sg_count;
Herbert Xuaeb4c132015-07-30 17:53:22 +08001043 int count = 0;
Lee Nipper70bcaca2008-07-03 19:08:46 +08001044
Herbert Xuaeb4c132015-07-30 17:53:22 +08001045 while (cryptlen && sg && n_sg--) {
1046 unsigned int len = sg_dma_len(sg);
1047
1048 if (offset >= len) {
1049 offset -= len;
1050 goto next;
1051 }
1052
1053 len -= offset;
1054
1055 if (len > cryptlen)
1056 len = cryptlen;
1057
1058 to_talitos_ptr(link_tbl_ptr + count,
1059 sg_dma_address(sg) + offset, 0);
LEROY Christopheb096b542016-06-06 13:20:34 +02001060 to_talitos_ptr_len(link_tbl_ptr + count, len, 0);
1061 to_talitos_ptr_ext_set(link_tbl_ptr + count, 0, 0);
Herbert Xuaeb4c132015-07-30 17:53:22 +08001062 count++;
1063 cryptlen -= len;
1064 offset = 0;
1065
1066next:
Cristian Stoica5be4d4c2015-01-20 10:06:16 +02001067 sg = sg_next(sg);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001068 }
1069
Kim Phillips9c4a7962008-06-23 19:50:15 +08001070 /* tag end of link table */
Herbert Xuaeb4c132015-07-30 17:53:22 +08001071 if (count > 0)
LEROY Christopheb096b542016-06-06 13:20:34 +02001072 to_talitos_ptr_ext_set(link_tbl_ptr + count - 1,
1073 DESC_PTR_LNKTBL_RETURN, 0);
Lee Nipper70bcaca2008-07-03 19:08:46 +08001074
Herbert Xuaeb4c132015-07-30 17:53:22 +08001075 return count;
1076}
1077
1078static inline int sg_to_link_tbl(struct scatterlist *sg, int sg_count,
1079 int cryptlen,
1080 struct talitos_ptr *link_tbl_ptr)
1081{
1082 return sg_to_link_tbl_offset(sg, sg_count, 0, cryptlen,
1083 link_tbl_ptr);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001084}
1085
1086/*
1087 * fill in and submit ipsec_esp descriptor
1088 */
Lee Nipper56af8cd2009-03-29 15:50:50 +08001089static int ipsec_esp(struct talitos_edesc *edesc, struct aead_request *areq,
Herbert Xuaeb4c132015-07-30 17:53:22 +08001090 void (*callback)(struct device *dev,
1091 struct talitos_desc *desc,
1092 void *context, int error))
Kim Phillips9c4a7962008-06-23 19:50:15 +08001093{
1094 struct crypto_aead *aead = crypto_aead_reqtfm(areq);
Herbert Xuaeb4c132015-07-30 17:53:22 +08001095 unsigned int authsize = crypto_aead_authsize(aead);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001096 struct talitos_ctx *ctx = crypto_aead_ctx(aead);
1097 struct device *dev = ctx->dev;
1098 struct talitos_desc *desc = &edesc->desc;
1099 unsigned int cryptlen = areq->cryptlen;
Kim Phillipse41256f2009-08-13 11:49:06 +10001100 unsigned int ivsize = crypto_aead_ivsize(aead);
Herbert Xuaeb4c132015-07-30 17:53:22 +08001101 int tbl_off = 0;
Kim Phillipsfa86a262008-07-17 20:20:06 +08001102 int sg_count, ret;
Kim Phillipsfe5720e2008-10-12 20:33:14 +08001103 int sg_link_tbl_len;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001104
1105 /* hmac key */
1106 map_single_talitos_ptr(dev, &desc->ptr[0], ctx->authkeylen, &ctx->key,
LEROY Christophea2b35aa2015-04-17 16:31:57 +02001107 DMA_TO_DEVICE);
Horia Geanta79fd31d2012-08-02 17:16:40 +03001108
LABBE Corentinb8a011d2015-09-23 13:55:25 +02001109 sg_count = dma_map_sg(dev, areq->src, edesc->src_nents ?: 1,
1110 (areq->src == areq->dst) ? DMA_BIDIRECTIONAL
1111 : DMA_TO_DEVICE);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001112 /* hmac data */
LEROY Christopheb096b542016-06-06 13:20:34 +02001113 to_talitos_ptr_len(&desc->ptr[1], areq->assoclen, 0);
Herbert Xuaeb4c132015-07-30 17:53:22 +08001114 if (sg_count > 1 &&
1115 (ret = sg_to_link_tbl_offset(areq->src, sg_count, 0,
1116 areq->assoclen,
1117 &edesc->link_tbl[tbl_off])) > 1) {
Horia Geanta79fd31d2012-08-02 17:16:40 +03001118 to_talitos_ptr(&desc->ptr[1], edesc->dma_link_tbl + tbl_off *
LEROY Christophe922f9dc2015-04-17 16:32:07 +02001119 sizeof(struct talitos_ptr), 0);
LEROY Christopheb096b542016-06-06 13:20:34 +02001120 to_talitos_ptr_ext_set(&desc->ptr[1], DESC_PTR_LNKTBL_JUMP, 0);
Horia Geanta79fd31d2012-08-02 17:16:40 +03001121
Horia Geanta79fd31d2012-08-02 17:16:40 +03001122 dma_sync_single_for_device(dev, edesc->dma_link_tbl,
1123 edesc->dma_len, DMA_BIDIRECTIONAL);
Horia Geant?340ff602016-04-19 20:33:48 +03001124
1125 tbl_off += ret;
Horia Geanta79fd31d2012-08-02 17:16:40 +03001126 } else {
Herbert Xuaeb4c132015-07-30 17:53:22 +08001127 to_talitos_ptr(&desc->ptr[1], sg_dma_address(areq->src), 0);
LEROY Christopheb096b542016-06-06 13:20:34 +02001128 to_talitos_ptr_ext_set(&desc->ptr[1], 0, 0);
Horia Geanta79fd31d2012-08-02 17:16:40 +03001129 }
1130
Kim Phillips9c4a7962008-06-23 19:50:15 +08001131 /* cipher iv */
LEROY Christophe922f9dc2015-04-17 16:32:07 +02001132 to_talitos_ptr(&desc->ptr[2], edesc->iv_dma, 0);
LEROY Christopheb096b542016-06-06 13:20:34 +02001133 to_talitos_ptr_len(&desc->ptr[2], ivsize, 0);
1134 to_talitos_ptr_ext_set(&desc->ptr[2], 0, 0);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001135
1136 /* cipher key */
1137 map_single_talitos_ptr(dev, &desc->ptr[3], ctx->enckeylen,
LEROY Christophea2b35aa2015-04-17 16:31:57 +02001138 (char *)&ctx->key + ctx->authkeylen,
Kim Phillips9c4a7962008-06-23 19:50:15 +08001139 DMA_TO_DEVICE);
1140
1141 /*
1142 * cipher in
1143 * map and adjust cipher len to aead request cryptlen.
1144 * extent is bytes of HMAC postpended to ciphertext,
1145 * typically 12 for ipsec
1146 */
LEROY Christopheb096b542016-06-06 13:20:34 +02001147 to_talitos_ptr_len(&desc->ptr[4], cryptlen, 0);
1148 to_talitos_ptr_ext_set(&desc->ptr[4], authsize, 0);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001149
Herbert Xuaeb4c132015-07-30 17:53:22 +08001150 sg_link_tbl_len = cryptlen;
1151 if (edesc->desc.hdr & DESC_HDR_MODE1_MDEU_CICV)
1152 sg_link_tbl_len += authsize;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001153
Horia Geant?340ff602016-04-19 20:33:48 +03001154 if (sg_count == 1) {
1155 to_talitos_ptr(&desc->ptr[4], sg_dma_address(areq->src) +
1156 areq->assoclen, 0);
1157 } else if ((ret = sg_to_link_tbl_offset(areq->src, sg_count,
1158 areq->assoclen, sg_link_tbl_len,
1159 &edesc->link_tbl[tbl_off])) >
1160 1) {
LEROY Christopheb096b542016-06-06 13:20:34 +02001161 to_talitos_ptr_ext_or(&desc->ptr[4], DESC_PTR_LNKTBL_JUMP, 0);
Herbert Xuaeb4c132015-07-30 17:53:22 +08001162 to_talitos_ptr(&desc->ptr[4], edesc->dma_link_tbl +
1163 tbl_off *
1164 sizeof(struct talitos_ptr), 0);
1165 dma_sync_single_for_device(dev, edesc->dma_link_tbl,
1166 edesc->dma_len,
1167 DMA_BIDIRECTIONAL);
Horia Geant?340ff602016-04-19 20:33:48 +03001168 tbl_off += ret;
1169 } else {
1170 copy_talitos_ptr(&desc->ptr[4], &edesc->link_tbl[tbl_off], 0);
1171 }
Kim Phillips9c4a7962008-06-23 19:50:15 +08001172
1173 /* cipher out */
LEROY Christopheb096b542016-06-06 13:20:34 +02001174 to_talitos_ptr_len(&desc->ptr[5], cryptlen, 0);
1175 to_talitos_ptr_ext_set(&desc->ptr[5], authsize, 0);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001176
Kim Phillipse938e462009-03-29 15:53:23 +08001177 if (areq->src != areq->dst)
LABBE Corentinb8a011d2015-09-23 13:55:25 +02001178 sg_count = dma_map_sg(dev, areq->dst, edesc->dst_nents ? : 1,
1179 DMA_FROM_DEVICE);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001180
Herbert Xuaeb4c132015-07-30 17:53:22 +08001181 edesc->icv_ool = false;
1182
Horia Geant?340ff602016-04-19 20:33:48 +03001183 if (sg_count == 1) {
1184 to_talitos_ptr(&desc->ptr[5], sg_dma_address(areq->dst) +
1185 areq->assoclen, 0);
1186 } else if ((sg_count =
1187 sg_to_link_tbl_offset(areq->dst, sg_count,
Herbert Xuaeb4c132015-07-30 17:53:22 +08001188 areq->assoclen, cryptlen,
Horia Geant?340ff602016-04-19 20:33:48 +03001189 &edesc->link_tbl[tbl_off])) > 1) {
Horia Geanta79fd31d2012-08-02 17:16:40 +03001190 struct talitos_ptr *tbl_ptr = &edesc->link_tbl[tbl_off];
Kim Phillips9c4a7962008-06-23 19:50:15 +08001191
Kim Phillips81eb0242009-08-13 11:51:51 +10001192 to_talitos_ptr(&desc->ptr[5], edesc->dma_link_tbl +
LEROY Christophe922f9dc2015-04-17 16:32:07 +02001193 tbl_off * sizeof(struct talitos_ptr), 0);
Kim Phillipsfe5720e2008-10-12 20:33:14 +08001194
Lee Nipperf3c85bc2008-07-30 16:26:57 +08001195 /* Add an entry to the link table for ICV data */
Horia Geanta79fd31d2012-08-02 17:16:40 +03001196 tbl_ptr += sg_count - 1;
LEROY Christopheb096b542016-06-06 13:20:34 +02001197 to_talitos_ptr_ext_set(tbl_ptr, 0, 0);
Horia Geanta79fd31d2012-08-02 17:16:40 +03001198 tbl_ptr++;
LEROY Christopheb096b542016-06-06 13:20:34 +02001199 to_talitos_ptr_ext_set(tbl_ptr, DESC_PTR_LNKTBL_RETURN, 0);
1200 to_talitos_ptr_len(tbl_ptr, authsize, 0);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001201
1202 /* icv data follows link tables */
Horia Geanta79fd31d2012-08-02 17:16:40 +03001203 to_talitos_ptr(tbl_ptr, edesc->dma_link_tbl +
Herbert Xuaeb4c132015-07-30 17:53:22 +08001204 (edesc->src_nents + edesc->dst_nents +
1205 2) * sizeof(struct talitos_ptr) +
1206 authsize, 0);
LEROY Christopheb096b542016-06-06 13:20:34 +02001207 to_talitos_ptr_ext_or(&desc->ptr[5], DESC_PTR_LNKTBL_JUMP, 0);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001208 dma_sync_single_for_device(ctx->dev, edesc->dma_link_tbl,
1209 edesc->dma_len, DMA_BIDIRECTIONAL);
Herbert Xuaeb4c132015-07-30 17:53:22 +08001210
1211 edesc->icv_ool = true;
Horia Geant?340ff602016-04-19 20:33:48 +03001212 } else {
1213 copy_talitos_ptr(&desc->ptr[5], &edesc->link_tbl[tbl_off], 0);
1214 }
Kim Phillips9c4a7962008-06-23 19:50:15 +08001215
1216 /* iv out */
LEROY Christophea2b35aa2015-04-17 16:31:57 +02001217 map_single_talitos_ptr(dev, &desc->ptr[6], ivsize, ctx->iv,
Kim Phillips9c4a7962008-06-23 19:50:15 +08001218 DMA_FROM_DEVICE);
1219
Kim Phillips5228f0f2011-07-15 11:21:38 +08001220 ret = talitos_submit(dev, ctx->ch, desc, callback, areq);
Kim Phillipsfa86a262008-07-17 20:20:06 +08001221 if (ret != -EINPROGRESS) {
1222 ipsec_esp_unmap(dev, edesc, areq);
1223 kfree(edesc);
1224 }
1225 return ret;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001226}
1227
Kim Phillips9c4a7962008-06-23 19:50:15 +08001228/*
Lee Nipper56af8cd2009-03-29 15:50:50 +08001229 * allocate and map the extended descriptor
Kim Phillips9c4a7962008-06-23 19:50:15 +08001230 */
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001231static struct talitos_edesc *talitos_edesc_alloc(struct device *dev,
1232 struct scatterlist *src,
1233 struct scatterlist *dst,
Horia Geanta79fd31d2012-08-02 17:16:40 +03001234 u8 *iv,
1235 unsigned int assoclen,
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001236 unsigned int cryptlen,
1237 unsigned int authsize,
Horia Geanta79fd31d2012-08-02 17:16:40 +03001238 unsigned int ivsize,
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001239 int icv_stashing,
Horia Geanta62293a32013-11-28 15:11:17 +02001240 u32 cryptoflags,
1241 bool encrypt)
Kim Phillips9c4a7962008-06-23 19:50:15 +08001242{
Lee Nipper56af8cd2009-03-29 15:50:50 +08001243 struct talitos_edesc *edesc;
Herbert Xuaeb4c132015-07-30 17:53:22 +08001244 int src_nents, dst_nents, alloc_len, dma_len;
Horia Geanta79fd31d2012-08-02 17:16:40 +03001245 dma_addr_t iv_dma = 0;
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001246 gfp_t flags = cryptoflags & CRYPTO_TFM_REQ_MAY_SLEEP ? GFP_KERNEL :
Kim Phillips586725f2008-07-17 20:19:18 +08001247 GFP_ATOMIC;
LEROY Christophe6f65f6a2015-04-17 16:32:15 +02001248 struct talitos_private *priv = dev_get_drvdata(dev);
1249 bool is_sec1 = has_ftr_sec1(priv);
1250 int max_len = is_sec1 ? TALITOS1_MAX_DATA_LEN : TALITOS2_MAX_DATA_LEN;
LABBE Corentin8e409fe2015-11-04 21:13:34 +01001251 void *err;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001252
LEROY Christophe6f65f6a2015-04-17 16:32:15 +02001253 if (cryptlen + authsize > max_len) {
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001254 dev_err(dev, "length exceeds h/w max limit\n");
Kim Phillips9c4a7962008-06-23 19:50:15 +08001255 return ERR_PTR(-EINVAL);
1256 }
1257
Horia Geanta935e99a2013-11-19 14:57:49 +02001258 if (ivsize)
Horia Geanta79fd31d2012-08-02 17:16:40 +03001259 iv_dma = dma_map_single(dev, iv, ivsize, DMA_TO_DEVICE);
1260
Horia Geanta62293a32013-11-28 15:11:17 +02001261 if (!dst || dst == src) {
LABBE Corentinb8a011d2015-09-23 13:55:25 +02001262 src_nents = sg_nents_for_len(src,
1263 assoclen + cryptlen + authsize);
LABBE Corentin8e409fe2015-11-04 21:13:34 +01001264 if (src_nents < 0) {
1265 dev_err(dev, "Invalid number of src SG.\n");
1266 err = ERR_PTR(-EINVAL);
1267 goto error_sg;
1268 }
Horia Geanta62293a32013-11-28 15:11:17 +02001269 src_nents = (src_nents == 1) ? 0 : src_nents;
1270 dst_nents = dst ? src_nents : 0;
1271 } else { /* dst && dst != src*/
LABBE Corentinb8a011d2015-09-23 13:55:25 +02001272 src_nents = sg_nents_for_len(src, assoclen + cryptlen +
1273 (encrypt ? 0 : authsize));
LABBE Corentin8e409fe2015-11-04 21:13:34 +01001274 if (src_nents < 0) {
1275 dev_err(dev, "Invalid number of src SG.\n");
1276 err = ERR_PTR(-EINVAL);
1277 goto error_sg;
1278 }
Horia Geanta62293a32013-11-28 15:11:17 +02001279 src_nents = (src_nents == 1) ? 0 : src_nents;
LABBE Corentinb8a011d2015-09-23 13:55:25 +02001280 dst_nents = sg_nents_for_len(dst, assoclen + cryptlen +
1281 (encrypt ? authsize : 0));
LABBE Corentin8e409fe2015-11-04 21:13:34 +01001282 if (dst_nents < 0) {
1283 dev_err(dev, "Invalid number of dst SG.\n");
1284 err = ERR_PTR(-EINVAL);
1285 goto error_sg;
1286 }
Horia Geanta62293a32013-11-28 15:11:17 +02001287 dst_nents = (dst_nents == 1) ? 0 : dst_nents;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001288 }
1289
1290 /*
1291 * allocate space for base edesc plus the link tables,
Herbert Xuaeb4c132015-07-30 17:53:22 +08001292 * allowing for two separate entries for AD and generated ICV (+ 2),
1293 * and space for two sets of ICVs (stashed and generated)
Kim Phillips9c4a7962008-06-23 19:50:15 +08001294 */
Lee Nipper56af8cd2009-03-29 15:50:50 +08001295 alloc_len = sizeof(struct talitos_edesc);
Herbert Xuaeb4c132015-07-30 17:53:22 +08001296 if (src_nents || dst_nents) {
LEROY Christophe6f65f6a2015-04-17 16:32:15 +02001297 if (is_sec1)
Dan Carpenter608f37d2015-05-11 13:10:09 +03001298 dma_len = (src_nents ? cryptlen : 0) +
1299 (dst_nents ? cryptlen : 0);
LEROY Christophe6f65f6a2015-04-17 16:32:15 +02001300 else
Herbert Xuaeb4c132015-07-30 17:53:22 +08001301 dma_len = (src_nents + dst_nents + 2) *
1302 sizeof(struct talitos_ptr) + authsize * 2;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001303 alloc_len += dma_len;
1304 } else {
1305 dma_len = 0;
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001306 alloc_len += icv_stashing ? authsize : 0;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001307 }
1308
Kim Phillips586725f2008-07-17 20:19:18 +08001309 edesc = kmalloc(alloc_len, GFP_DMA | flags);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001310 if (!edesc) {
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001311 dev_err(dev, "could not allocate edescriptor\n");
LABBE Corentin8e409fe2015-11-04 21:13:34 +01001312 err = ERR_PTR(-ENOMEM);
1313 goto error_sg;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001314 }
1315
1316 edesc->src_nents = src_nents;
1317 edesc->dst_nents = dst_nents;
Horia Geanta79fd31d2012-08-02 17:16:40 +03001318 edesc->iv_dma = iv_dma;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001319 edesc->dma_len = dma_len;
Lee Nipper497f2e62010-05-19 19:20:36 +10001320 if (dma_len)
1321 edesc->dma_link_tbl = dma_map_single(dev, &edesc->link_tbl[0],
1322 edesc->dma_len,
1323 DMA_BIDIRECTIONAL);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001324
1325 return edesc;
LABBE Corentin8e409fe2015-11-04 21:13:34 +01001326error_sg:
1327 if (iv_dma)
1328 dma_unmap_single(dev, iv_dma, ivsize, DMA_TO_DEVICE);
1329 return err;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001330}
1331
Horia Geanta79fd31d2012-08-02 17:16:40 +03001332static struct talitos_edesc *aead_edesc_alloc(struct aead_request *areq, u8 *iv,
Horia Geanta62293a32013-11-28 15:11:17 +02001333 int icv_stashing, bool encrypt)
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001334{
1335 struct crypto_aead *authenc = crypto_aead_reqtfm(areq);
Herbert Xuaeb4c132015-07-30 17:53:22 +08001336 unsigned int authsize = crypto_aead_authsize(authenc);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001337 struct talitos_ctx *ctx = crypto_aead_ctx(authenc);
Horia Geanta79fd31d2012-08-02 17:16:40 +03001338 unsigned int ivsize = crypto_aead_ivsize(authenc);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001339
Herbert Xuaeb4c132015-07-30 17:53:22 +08001340 return talitos_edesc_alloc(ctx->dev, areq->src, areq->dst,
Horia Geanta79fd31d2012-08-02 17:16:40 +03001341 iv, areq->assoclen, areq->cryptlen,
Herbert Xuaeb4c132015-07-30 17:53:22 +08001342 authsize, ivsize, icv_stashing,
Horia Geanta62293a32013-11-28 15:11:17 +02001343 areq->base.flags, encrypt);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001344}
1345
Lee Nipper56af8cd2009-03-29 15:50:50 +08001346static int aead_encrypt(struct aead_request *req)
Kim Phillips9c4a7962008-06-23 19:50:15 +08001347{
1348 struct crypto_aead *authenc = crypto_aead_reqtfm(req);
1349 struct talitos_ctx *ctx = crypto_aead_ctx(authenc);
Lee Nipper56af8cd2009-03-29 15:50:50 +08001350 struct talitos_edesc *edesc;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001351
1352 /* allocate extended descriptor */
Horia Geanta62293a32013-11-28 15:11:17 +02001353 edesc = aead_edesc_alloc(req, req->iv, 0, true);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001354 if (IS_ERR(edesc))
1355 return PTR_ERR(edesc);
1356
1357 /* set encrypt */
Lee Nipper70bcaca2008-07-03 19:08:46 +08001358 edesc->desc.hdr = ctx->desc_hdr_template | DESC_HDR_MODE0_ENCRYPT;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001359
Herbert Xuaeb4c132015-07-30 17:53:22 +08001360 return ipsec_esp(edesc, req, ipsec_esp_encrypt_done);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001361}
1362
Lee Nipper56af8cd2009-03-29 15:50:50 +08001363static int aead_decrypt(struct aead_request *req)
Kim Phillips9c4a7962008-06-23 19:50:15 +08001364{
1365 struct crypto_aead *authenc = crypto_aead_reqtfm(req);
Herbert Xuaeb4c132015-07-30 17:53:22 +08001366 unsigned int authsize = crypto_aead_authsize(authenc);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001367 struct talitos_ctx *ctx = crypto_aead_ctx(authenc);
Kim Phillipsfe5720e2008-10-12 20:33:14 +08001368 struct talitos_private *priv = dev_get_drvdata(ctx->dev);
Lee Nipper56af8cd2009-03-29 15:50:50 +08001369 struct talitos_edesc *edesc;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001370 struct scatterlist *sg;
1371 void *icvdata;
1372
1373 req->cryptlen -= authsize;
1374
1375 /* allocate extended descriptor */
Horia Geanta62293a32013-11-28 15:11:17 +02001376 edesc = aead_edesc_alloc(req, req->iv, 1, false);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001377 if (IS_ERR(edesc))
1378 return PTR_ERR(edesc);
1379
Kim Phillipsfe5720e2008-10-12 20:33:14 +08001380 if ((priv->features & TALITOS_FTR_HW_AUTH_CHECK) &&
Kim Phillipse938e462009-03-29 15:53:23 +08001381 ((!edesc->src_nents && !edesc->dst_nents) ||
1382 priv->features & TALITOS_FTR_SRC_LINK_TBL_LEN_INCLUDES_EXTENT)) {
Kim Phillips9c4a7962008-06-23 19:50:15 +08001383
Kim Phillipsfe5720e2008-10-12 20:33:14 +08001384 /* decrypt and check the ICV */
Kim Phillipse938e462009-03-29 15:53:23 +08001385 edesc->desc.hdr = ctx->desc_hdr_template |
1386 DESC_HDR_DIR_INBOUND |
Kim Phillipsfe5720e2008-10-12 20:33:14 +08001387 DESC_HDR_MODE1_MDEU_CICV;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001388
Kim Phillipsfe5720e2008-10-12 20:33:14 +08001389 /* reset integrity check result bits */
1390 edesc->desc.hdr_lo = 0;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001391
Herbert Xuaeb4c132015-07-30 17:53:22 +08001392 return ipsec_esp(edesc, req, ipsec_esp_decrypt_hwauth_done);
Kim Phillipsfe5720e2008-10-12 20:33:14 +08001393 }
Kim Phillipse938e462009-03-29 15:53:23 +08001394
1395 /* Have to check the ICV with software */
1396 edesc->desc.hdr = ctx->desc_hdr_template | DESC_HDR_DIR_INBOUND;
1397
1398 /* stash incoming ICV for later cmp with ICV generated by the h/w */
1399 if (edesc->dma_len)
Herbert Xuaeb4c132015-07-30 17:53:22 +08001400 icvdata = (char *)&edesc->link_tbl[edesc->src_nents +
1401 edesc->dst_nents + 2];
Kim Phillipse938e462009-03-29 15:53:23 +08001402 else
1403 icvdata = &edesc->link_tbl[0];
1404
1405 sg = sg_last(req->src, edesc->src_nents ? : 1);
1406
Herbert Xuaeb4c132015-07-30 17:53:22 +08001407 memcpy(icvdata, (char *)sg_virt(sg) + sg->length - authsize, authsize);
Kim Phillipse938e462009-03-29 15:53:23 +08001408
Herbert Xuaeb4c132015-07-30 17:53:22 +08001409 return ipsec_esp(edesc, req, ipsec_esp_decrypt_swauth_done);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001410}
1411
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001412static int ablkcipher_setkey(struct crypto_ablkcipher *cipher,
1413 const u8 *key, unsigned int keylen)
1414{
1415 struct talitos_ctx *ctx = crypto_ablkcipher_ctx(cipher);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001416
1417 memcpy(&ctx->key, key, keylen);
1418 ctx->keylen = keylen;
1419
1420 return 0;
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001421}
1422
LEROY Christophe032d1972015-04-17 16:31:51 +02001423static void unmap_sg_talitos_ptr(struct device *dev, struct scatterlist *src,
1424 struct scatterlist *dst, unsigned int len,
1425 struct talitos_edesc *edesc)
1426{
LEROY Christophe6f65f6a2015-04-17 16:32:15 +02001427 struct talitos_private *priv = dev_get_drvdata(dev);
1428 bool is_sec1 = has_ftr_sec1(priv);
1429
1430 if (is_sec1) {
1431 if (!edesc->src_nents) {
1432 dma_unmap_sg(dev, src, 1,
1433 dst != src ? DMA_TO_DEVICE
1434 : DMA_BIDIRECTIONAL);
1435 }
1436 if (dst && edesc->dst_nents) {
1437 dma_sync_single_for_device(dev,
1438 edesc->dma_link_tbl + len,
1439 len, DMA_FROM_DEVICE);
1440 sg_copy_from_buffer(dst, edesc->dst_nents ? : 1,
1441 edesc->buf + len, len);
1442 } else if (dst && dst != src) {
1443 dma_unmap_sg(dev, dst, 1, DMA_FROM_DEVICE);
1444 }
1445 } else {
1446 talitos_sg_unmap(dev, edesc, src, dst);
1447 }
LEROY Christophe032d1972015-04-17 16:31:51 +02001448}
1449
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001450static void common_nonsnoop_unmap(struct device *dev,
1451 struct talitos_edesc *edesc,
1452 struct ablkcipher_request *areq)
1453{
1454 unmap_single_talitos_ptr(dev, &edesc->desc.ptr[5], DMA_FROM_DEVICE);
LEROY Christophe032d1972015-04-17 16:31:51 +02001455
1456 unmap_sg_talitos_ptr(dev, areq->src, areq->dst, areq->nbytes, edesc);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001457 unmap_single_talitos_ptr(dev, &edesc->desc.ptr[2], DMA_TO_DEVICE);
1458 unmap_single_talitos_ptr(dev, &edesc->desc.ptr[1], DMA_TO_DEVICE);
1459
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001460 if (edesc->dma_len)
1461 dma_unmap_single(dev, edesc->dma_link_tbl, edesc->dma_len,
1462 DMA_BIDIRECTIONAL);
1463}
1464
1465static void ablkcipher_done(struct device *dev,
1466 struct talitos_desc *desc, void *context,
1467 int err)
1468{
1469 struct ablkcipher_request *areq = context;
Kim Phillips19bbbc62009-03-29 15:53:59 +08001470 struct talitos_edesc *edesc;
1471
1472 edesc = container_of(desc, struct talitos_edesc, desc);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001473
1474 common_nonsnoop_unmap(dev, edesc, areq);
1475
1476 kfree(edesc);
1477
1478 areq->base.complete(&areq->base, err);
1479}
1480
LEROY Christophe032d1972015-04-17 16:31:51 +02001481int map_sg_in_talitos_ptr(struct device *dev, struct scatterlist *src,
1482 unsigned int len, struct talitos_edesc *edesc,
1483 enum dma_data_direction dir, struct talitos_ptr *ptr)
1484{
1485 int sg_count;
LEROY Christophe922f9dc2015-04-17 16:32:07 +02001486 struct talitos_private *priv = dev_get_drvdata(dev);
1487 bool is_sec1 = has_ftr_sec1(priv);
LEROY Christophe032d1972015-04-17 16:31:51 +02001488
LEROY Christophe922f9dc2015-04-17 16:32:07 +02001489 to_talitos_ptr_len(ptr, len, is_sec1);
LEROY Christophe032d1972015-04-17 16:31:51 +02001490
LEROY Christophe6f65f6a2015-04-17 16:32:15 +02001491 if (is_sec1) {
1492 sg_count = edesc->src_nents ? : 1;
LEROY Christophe032d1972015-04-17 16:31:51 +02001493
LEROY Christophe6f65f6a2015-04-17 16:32:15 +02001494 if (sg_count == 1) {
1495 dma_map_sg(dev, src, 1, dir);
LEROY Christophe922f9dc2015-04-17 16:32:07 +02001496 to_talitos_ptr(ptr, sg_dma_address(src), is_sec1);
LEROY Christophe6f65f6a2015-04-17 16:32:15 +02001497 } else {
1498 sg_copy_to_buffer(src, sg_count, edesc->buf, len);
1499 to_talitos_ptr(ptr, edesc->dma_link_tbl, is_sec1);
1500 dma_sync_single_for_device(dev, edesc->dma_link_tbl,
1501 len, DMA_TO_DEVICE);
1502 }
1503 } else {
LEROY Christopheb096b542016-06-06 13:20:34 +02001504 to_talitos_ptr_ext_set(ptr, 0, is_sec1);
LEROY Christophe6f65f6a2015-04-17 16:32:15 +02001505
LABBE Corentinb8a011d2015-09-23 13:55:25 +02001506 sg_count = dma_map_sg(dev, src, edesc->src_nents ? : 1, dir);
LEROY Christophe6f65f6a2015-04-17 16:32:15 +02001507
1508 if (sg_count == 1) {
1509 to_talitos_ptr(ptr, sg_dma_address(src), is_sec1);
1510 } else {
1511 sg_count = sg_to_link_tbl(src, sg_count, len,
1512 &edesc->link_tbl[0]);
1513 if (sg_count > 1) {
1514 to_talitos_ptr(ptr, edesc->dma_link_tbl, 0);
LEROY Christopheb096b542016-06-06 13:20:34 +02001515 to_talitos_ptr_ext_or(ptr, DESC_PTR_LNKTBL_JUMP,
1516 0);
LEROY Christophe6f65f6a2015-04-17 16:32:15 +02001517 dma_sync_single_for_device(dev,
1518 edesc->dma_link_tbl,
1519 edesc->dma_len,
1520 DMA_BIDIRECTIONAL);
1521 } else {
1522 /* Only one segment now, so no link tbl needed*/
1523 to_talitos_ptr(ptr, sg_dma_address(src),
1524 is_sec1);
1525 }
LEROY Christophe032d1972015-04-17 16:31:51 +02001526 }
1527 }
1528 return sg_count;
1529}
1530
1531void map_sg_out_talitos_ptr(struct device *dev, struct scatterlist *dst,
1532 unsigned int len, struct talitos_edesc *edesc,
1533 enum dma_data_direction dir,
1534 struct talitos_ptr *ptr, int sg_count)
1535{
LEROY Christophe922f9dc2015-04-17 16:32:07 +02001536 struct talitos_private *priv = dev_get_drvdata(dev);
1537 bool is_sec1 = has_ftr_sec1(priv);
1538
LEROY Christophe032d1972015-04-17 16:31:51 +02001539 if (dir != DMA_NONE)
LABBE Corentinb8a011d2015-09-23 13:55:25 +02001540 sg_count = dma_map_sg(dev, dst, edesc->dst_nents ? : 1, dir);
LEROY Christophe032d1972015-04-17 16:31:51 +02001541
LEROY Christophe6f65f6a2015-04-17 16:32:15 +02001542 to_talitos_ptr_len(ptr, len, is_sec1);
LEROY Christophe032d1972015-04-17 16:31:51 +02001543
LEROY Christophe6f65f6a2015-04-17 16:32:15 +02001544 if (is_sec1) {
1545 if (sg_count == 1) {
1546 if (dir != DMA_NONE)
1547 dma_map_sg(dev, dst, 1, dir);
1548 to_talitos_ptr(ptr, sg_dma_address(dst), is_sec1);
1549 } else {
1550 to_talitos_ptr(ptr, edesc->dma_link_tbl + len, is_sec1);
1551 dma_sync_single_for_device(dev,
1552 edesc->dma_link_tbl + len,
1553 len, DMA_FROM_DEVICE);
1554 }
1555 } else {
LEROY Christopheb096b542016-06-06 13:20:34 +02001556 to_talitos_ptr_ext_set(ptr, 0, is_sec1);
LEROY Christophe6f65f6a2015-04-17 16:32:15 +02001557
1558 if (sg_count == 1) {
1559 to_talitos_ptr(ptr, sg_dma_address(dst), is_sec1);
1560 } else {
1561 struct talitos_ptr *link_tbl_ptr =
1562 &edesc->link_tbl[edesc->src_nents + 1];
1563
1564 to_talitos_ptr(ptr, edesc->dma_link_tbl +
1565 (edesc->src_nents + 1) *
1566 sizeof(struct talitos_ptr), 0);
LEROY Christopheb096b542016-06-06 13:20:34 +02001567 to_talitos_ptr_ext_or(ptr, DESC_PTR_LNKTBL_JUMP, 0);
Horia Geant?42e8b0d2015-05-11 20:04:56 +03001568 sg_to_link_tbl(dst, sg_count, len, link_tbl_ptr);
LEROY Christophe6f65f6a2015-04-17 16:32:15 +02001569 dma_sync_single_for_device(dev, edesc->dma_link_tbl,
1570 edesc->dma_len,
1571 DMA_BIDIRECTIONAL);
1572 }
LEROY Christophe032d1972015-04-17 16:31:51 +02001573 }
1574}
1575
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001576static int common_nonsnoop(struct talitos_edesc *edesc,
1577 struct ablkcipher_request *areq,
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001578 void (*callback) (struct device *dev,
1579 struct talitos_desc *desc,
1580 void *context, int error))
1581{
1582 struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(areq);
1583 struct talitos_ctx *ctx = crypto_ablkcipher_ctx(cipher);
1584 struct device *dev = ctx->dev;
1585 struct talitos_desc *desc = &edesc->desc;
1586 unsigned int cryptlen = areq->nbytes;
Horia Geanta79fd31d2012-08-02 17:16:40 +03001587 unsigned int ivsize = crypto_ablkcipher_ivsize(cipher);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001588 int sg_count, ret;
LEROY Christophe922f9dc2015-04-17 16:32:07 +02001589 struct talitos_private *priv = dev_get_drvdata(dev);
1590 bool is_sec1 = has_ftr_sec1(priv);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001591
1592 /* first DWORD empty */
LEROY Christophe2529bc32015-04-17 16:31:49 +02001593 desc->ptr[0] = zero_entry;
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001594
1595 /* cipher iv */
LEROY Christophe922f9dc2015-04-17 16:32:07 +02001596 to_talitos_ptr(&desc->ptr[1], edesc->iv_dma, is_sec1);
1597 to_talitos_ptr_len(&desc->ptr[1], ivsize, is_sec1);
LEROY Christopheb096b542016-06-06 13:20:34 +02001598 to_talitos_ptr_ext_set(&desc->ptr[1], 0, is_sec1);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001599
1600 /* cipher key */
1601 map_single_talitos_ptr(dev, &desc->ptr[2], ctx->keylen,
LEROY Christophea2b35aa2015-04-17 16:31:57 +02001602 (char *)&ctx->key, DMA_TO_DEVICE);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001603
1604 /*
1605 * cipher in
1606 */
LEROY Christophe032d1972015-04-17 16:31:51 +02001607 sg_count = map_sg_in_talitos_ptr(dev, areq->src, cryptlen, edesc,
1608 (areq->src == areq->dst) ?
1609 DMA_BIDIRECTIONAL : DMA_TO_DEVICE,
1610 &desc->ptr[3]);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001611
1612 /* cipher out */
LEROY Christophe032d1972015-04-17 16:31:51 +02001613 map_sg_out_talitos_ptr(dev, areq->dst, cryptlen, edesc,
1614 (areq->src == areq->dst) ? DMA_NONE
1615 : DMA_FROM_DEVICE,
1616 &desc->ptr[4], sg_count);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001617
1618 /* iv out */
LEROY Christophea2b35aa2015-04-17 16:31:57 +02001619 map_single_talitos_ptr(dev, &desc->ptr[5], ivsize, ctx->iv,
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001620 DMA_FROM_DEVICE);
1621
1622 /* last DWORD empty */
LEROY Christophe2529bc32015-04-17 16:31:49 +02001623 desc->ptr[6] = zero_entry;
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001624
Kim Phillips5228f0f2011-07-15 11:21:38 +08001625 ret = talitos_submit(dev, ctx->ch, desc, callback, areq);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001626 if (ret != -EINPROGRESS) {
1627 common_nonsnoop_unmap(dev, edesc, areq);
1628 kfree(edesc);
1629 }
1630 return ret;
1631}
1632
Kim Phillipse938e462009-03-29 15:53:23 +08001633static struct talitos_edesc *ablkcipher_edesc_alloc(struct ablkcipher_request *
Horia Geanta62293a32013-11-28 15:11:17 +02001634 areq, bool encrypt)
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001635{
1636 struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(areq);
1637 struct talitos_ctx *ctx = crypto_ablkcipher_ctx(cipher);
Horia Geanta79fd31d2012-08-02 17:16:40 +03001638 unsigned int ivsize = crypto_ablkcipher_ivsize(cipher);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001639
Herbert Xuaeb4c132015-07-30 17:53:22 +08001640 return talitos_edesc_alloc(ctx->dev, areq->src, areq->dst,
Horia Geanta79fd31d2012-08-02 17:16:40 +03001641 areq->info, 0, areq->nbytes, 0, ivsize, 0,
Horia Geanta62293a32013-11-28 15:11:17 +02001642 areq->base.flags, encrypt);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001643}
1644
1645static int ablkcipher_encrypt(struct ablkcipher_request *areq)
1646{
1647 struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(areq);
1648 struct talitos_ctx *ctx = crypto_ablkcipher_ctx(cipher);
1649 struct talitos_edesc *edesc;
1650
1651 /* allocate extended descriptor */
Horia Geanta62293a32013-11-28 15:11:17 +02001652 edesc = ablkcipher_edesc_alloc(areq, true);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001653 if (IS_ERR(edesc))
1654 return PTR_ERR(edesc);
1655
1656 /* set encrypt */
1657 edesc->desc.hdr = ctx->desc_hdr_template | DESC_HDR_MODE0_ENCRYPT;
1658
Kim Phillipsfebec542011-07-15 11:21:39 +08001659 return common_nonsnoop(edesc, areq, ablkcipher_done);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001660}
1661
1662static int ablkcipher_decrypt(struct ablkcipher_request *areq)
1663{
1664 struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(areq);
1665 struct talitos_ctx *ctx = crypto_ablkcipher_ctx(cipher);
1666 struct talitos_edesc *edesc;
1667
1668 /* allocate extended descriptor */
Horia Geanta62293a32013-11-28 15:11:17 +02001669 edesc = ablkcipher_edesc_alloc(areq, false);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001670 if (IS_ERR(edesc))
1671 return PTR_ERR(edesc);
1672
1673 edesc->desc.hdr = ctx->desc_hdr_template | DESC_HDR_DIR_INBOUND;
1674
Kim Phillipsfebec542011-07-15 11:21:39 +08001675 return common_nonsnoop(edesc, areq, ablkcipher_done);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001676}
1677
Lee Nipper497f2e62010-05-19 19:20:36 +10001678static void common_nonsnoop_hash_unmap(struct device *dev,
1679 struct talitos_edesc *edesc,
1680 struct ahash_request *areq)
1681{
1682 struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
LEROY Christophe922f9dc2015-04-17 16:32:07 +02001683 struct talitos_private *priv = dev_get_drvdata(dev);
1684 bool is_sec1 = has_ftr_sec1(priv);
Lee Nipper497f2e62010-05-19 19:20:36 +10001685
1686 unmap_single_talitos_ptr(dev, &edesc->desc.ptr[5], DMA_FROM_DEVICE);
1687
LEROY Christophe032d1972015-04-17 16:31:51 +02001688 unmap_sg_talitos_ptr(dev, req_ctx->psrc, NULL, 0, edesc);
1689
Lee Nipper497f2e62010-05-19 19:20:36 +10001690 /* When using hashctx-in, must unmap it. */
LEROY Christophe922f9dc2015-04-17 16:32:07 +02001691 if (from_talitos_ptr_len(&edesc->desc.ptr[1], is_sec1))
Lee Nipper497f2e62010-05-19 19:20:36 +10001692 unmap_single_talitos_ptr(dev, &edesc->desc.ptr[1],
1693 DMA_TO_DEVICE);
1694
LEROY Christophe922f9dc2015-04-17 16:32:07 +02001695 if (from_talitos_ptr_len(&edesc->desc.ptr[2], is_sec1))
Lee Nipper497f2e62010-05-19 19:20:36 +10001696 unmap_single_talitos_ptr(dev, &edesc->desc.ptr[2],
1697 DMA_TO_DEVICE);
1698
Lee Nipper497f2e62010-05-19 19:20:36 +10001699 if (edesc->dma_len)
1700 dma_unmap_single(dev, edesc->dma_link_tbl, edesc->dma_len,
1701 DMA_BIDIRECTIONAL);
1702
1703}
1704
1705static void ahash_done(struct device *dev,
1706 struct talitos_desc *desc, void *context,
1707 int err)
1708{
1709 struct ahash_request *areq = context;
1710 struct talitos_edesc *edesc =
1711 container_of(desc, struct talitos_edesc, desc);
1712 struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
1713
1714 if (!req_ctx->last && req_ctx->to_hash_later) {
1715 /* Position any partial block for next update/final/finup */
1716 memcpy(req_ctx->buf, req_ctx->bufnext, req_ctx->to_hash_later);
Lee Nipper5e833bc2010-06-16 15:29:15 +10001717 req_ctx->nbuf = req_ctx->to_hash_later;
Lee Nipper497f2e62010-05-19 19:20:36 +10001718 }
1719 common_nonsnoop_hash_unmap(dev, edesc, areq);
1720
1721 kfree(edesc);
1722
1723 areq->base.complete(&areq->base, err);
1724}
1725
LEROY Christophe2d029052015-04-17 16:32:18 +02001726/*
1727 * SEC1 doesn't like hashing of 0 sized message, so we do the padding
1728 * ourself and submit a padded block
1729 */
1730void talitos_handle_buggy_hash(struct talitos_ctx *ctx,
1731 struct talitos_edesc *edesc,
1732 struct talitos_ptr *ptr)
1733{
1734 static u8 padded_hash[64] = {
1735 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1736 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1737 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1738 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1739 };
1740
1741 pr_err_once("Bug in SEC1, padding ourself\n");
1742 edesc->desc.hdr &= ~DESC_HDR_MODE0_MDEU_PAD;
1743 map_single_talitos_ptr(ctx->dev, ptr, sizeof(padded_hash),
1744 (char *)padded_hash, DMA_TO_DEVICE);
1745}
1746
Lee Nipper497f2e62010-05-19 19:20:36 +10001747static int common_nonsnoop_hash(struct talitos_edesc *edesc,
1748 struct ahash_request *areq, unsigned int length,
1749 void (*callback) (struct device *dev,
1750 struct talitos_desc *desc,
1751 void *context, int error))
1752{
1753 struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
1754 struct talitos_ctx *ctx = crypto_ahash_ctx(tfm);
1755 struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
1756 struct device *dev = ctx->dev;
1757 struct talitos_desc *desc = &edesc->desc;
LEROY Christophe032d1972015-04-17 16:31:51 +02001758 int ret;
LEROY Christophe922f9dc2015-04-17 16:32:07 +02001759 struct talitos_private *priv = dev_get_drvdata(dev);
1760 bool is_sec1 = has_ftr_sec1(priv);
Lee Nipper497f2e62010-05-19 19:20:36 +10001761
1762 /* first DWORD empty */
1763 desc->ptr[0] = zero_entry;
1764
Kim Phillips60f208d2010-05-19 19:21:53 +10001765 /* hash context in */
1766 if (!req_ctx->first || req_ctx->swinit) {
Lee Nipper497f2e62010-05-19 19:20:36 +10001767 map_single_talitos_ptr(dev, &desc->ptr[1],
1768 req_ctx->hw_context_size,
LEROY Christophea2b35aa2015-04-17 16:31:57 +02001769 (char *)req_ctx->hw_context,
Lee Nipper497f2e62010-05-19 19:20:36 +10001770 DMA_TO_DEVICE);
Kim Phillips60f208d2010-05-19 19:21:53 +10001771 req_ctx->swinit = 0;
Lee Nipper497f2e62010-05-19 19:20:36 +10001772 } else {
1773 desc->ptr[1] = zero_entry;
1774 /* Indicate next op is not the first. */
1775 req_ctx->first = 0;
1776 }
1777
1778 /* HMAC key */
1779 if (ctx->keylen)
1780 map_single_talitos_ptr(dev, &desc->ptr[2], ctx->keylen,
LEROY Christophea2b35aa2015-04-17 16:31:57 +02001781 (char *)&ctx->key, DMA_TO_DEVICE);
Lee Nipper497f2e62010-05-19 19:20:36 +10001782 else
1783 desc->ptr[2] = zero_entry;
1784
1785 /*
1786 * data in
1787 */
LEROY Christophe032d1972015-04-17 16:31:51 +02001788 map_sg_in_talitos_ptr(dev, req_ctx->psrc, length, edesc,
1789 DMA_TO_DEVICE, &desc->ptr[3]);
Lee Nipper497f2e62010-05-19 19:20:36 +10001790
1791 /* fifth DWORD empty */
1792 desc->ptr[4] = zero_entry;
1793
1794 /* hash/HMAC out -or- hash context out */
1795 if (req_ctx->last)
1796 map_single_talitos_ptr(dev, &desc->ptr[5],
1797 crypto_ahash_digestsize(tfm),
LEROY Christophea2b35aa2015-04-17 16:31:57 +02001798 areq->result, DMA_FROM_DEVICE);
Lee Nipper497f2e62010-05-19 19:20:36 +10001799 else
1800 map_single_talitos_ptr(dev, &desc->ptr[5],
1801 req_ctx->hw_context_size,
LEROY Christophea2b35aa2015-04-17 16:31:57 +02001802 req_ctx->hw_context, DMA_FROM_DEVICE);
Lee Nipper497f2e62010-05-19 19:20:36 +10001803
1804 /* last DWORD empty */
1805 desc->ptr[6] = zero_entry;
1806
LEROY Christophe2d029052015-04-17 16:32:18 +02001807 if (is_sec1 && from_talitos_ptr_len(&desc->ptr[3], true) == 0)
1808 talitos_handle_buggy_hash(ctx, edesc, &desc->ptr[3]);
1809
Kim Phillips5228f0f2011-07-15 11:21:38 +08001810 ret = talitos_submit(dev, ctx->ch, desc, callback, areq);
Lee Nipper497f2e62010-05-19 19:20:36 +10001811 if (ret != -EINPROGRESS) {
1812 common_nonsnoop_hash_unmap(dev, edesc, areq);
1813 kfree(edesc);
1814 }
1815 return ret;
1816}
1817
1818static struct talitos_edesc *ahash_edesc_alloc(struct ahash_request *areq,
1819 unsigned int nbytes)
1820{
1821 struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
1822 struct talitos_ctx *ctx = crypto_ahash_ctx(tfm);
1823 struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
1824
Herbert Xuaeb4c132015-07-30 17:53:22 +08001825 return talitos_edesc_alloc(ctx->dev, req_ctx->psrc, NULL, NULL, 0,
Horia Geanta62293a32013-11-28 15:11:17 +02001826 nbytes, 0, 0, 0, areq->base.flags, false);
Lee Nipper497f2e62010-05-19 19:20:36 +10001827}
1828
1829static int ahash_init(struct ahash_request *areq)
1830{
1831 struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
1832 struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
1833
1834 /* Initialize the context */
Lee Nipper5e833bc2010-06-16 15:29:15 +10001835 req_ctx->nbuf = 0;
Kim Phillips60f208d2010-05-19 19:21:53 +10001836 req_ctx->first = 1; /* first indicates h/w must init its context */
1837 req_ctx->swinit = 0; /* assume h/w init of context */
Lee Nipper497f2e62010-05-19 19:20:36 +10001838 req_ctx->hw_context_size =
1839 (crypto_ahash_digestsize(tfm) <= SHA256_DIGEST_SIZE)
1840 ? TALITOS_MDEU_CONTEXT_SIZE_MD5_SHA1_SHA256
1841 : TALITOS_MDEU_CONTEXT_SIZE_SHA384_SHA512;
1842
1843 return 0;
1844}
1845
Kim Phillips60f208d2010-05-19 19:21:53 +10001846/*
1847 * on h/w without explicit sha224 support, we initialize h/w context
1848 * manually with sha224 constants, and tell it to run sha256.
1849 */
1850static int ahash_init_sha224_swinit(struct ahash_request *areq)
1851{
1852 struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
1853
1854 ahash_init(areq);
1855 req_ctx->swinit = 1;/* prevent h/w initting context with sha256 values*/
1856
Kim Phillipsa7524472010-09-23 15:56:38 +08001857 req_ctx->hw_context[0] = SHA224_H0;
1858 req_ctx->hw_context[1] = SHA224_H1;
1859 req_ctx->hw_context[2] = SHA224_H2;
1860 req_ctx->hw_context[3] = SHA224_H3;
1861 req_ctx->hw_context[4] = SHA224_H4;
1862 req_ctx->hw_context[5] = SHA224_H5;
1863 req_ctx->hw_context[6] = SHA224_H6;
1864 req_ctx->hw_context[7] = SHA224_H7;
Kim Phillips60f208d2010-05-19 19:21:53 +10001865
1866 /* init 64-bit count */
1867 req_ctx->hw_context[8] = 0;
1868 req_ctx->hw_context[9] = 0;
1869
1870 return 0;
1871}
1872
Lee Nipper497f2e62010-05-19 19:20:36 +10001873static int ahash_process_req(struct ahash_request *areq, unsigned int nbytes)
1874{
1875 struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
1876 struct talitos_ctx *ctx = crypto_ahash_ctx(tfm);
1877 struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
1878 struct talitos_edesc *edesc;
1879 unsigned int blocksize =
1880 crypto_tfm_alg_blocksize(crypto_ahash_tfm(tfm));
1881 unsigned int nbytes_to_hash;
1882 unsigned int to_hash_later;
Lee Nipper5e833bc2010-06-16 15:29:15 +10001883 unsigned int nsg;
LABBE Corentin8e409fe2015-11-04 21:13:34 +01001884 int nents;
Lee Nipper497f2e62010-05-19 19:20:36 +10001885
Lee Nipper5e833bc2010-06-16 15:29:15 +10001886 if (!req_ctx->last && (nbytes + req_ctx->nbuf <= blocksize)) {
1887 /* Buffer up to one whole block */
LABBE Corentin8e409fe2015-11-04 21:13:34 +01001888 nents = sg_nents_for_len(areq->src, nbytes);
1889 if (nents < 0) {
1890 dev_err(ctx->dev, "Invalid number of src SG.\n");
1891 return nents;
1892 }
1893 sg_copy_to_buffer(areq->src, nents,
Lee Nipper5e833bc2010-06-16 15:29:15 +10001894 req_ctx->buf + req_ctx->nbuf, nbytes);
1895 req_ctx->nbuf += nbytes;
Lee Nipper497f2e62010-05-19 19:20:36 +10001896 return 0;
1897 }
1898
Lee Nipper5e833bc2010-06-16 15:29:15 +10001899 /* At least (blocksize + 1) bytes are available to hash */
1900 nbytes_to_hash = nbytes + req_ctx->nbuf;
1901 to_hash_later = nbytes_to_hash & (blocksize - 1);
1902
1903 if (req_ctx->last)
1904 to_hash_later = 0;
1905 else if (to_hash_later)
1906 /* There is a partial block. Hash the full block(s) now */
1907 nbytes_to_hash -= to_hash_later;
1908 else {
1909 /* Keep one block buffered */
1910 nbytes_to_hash -= blocksize;
1911 to_hash_later = blocksize;
1912 }
1913
1914 /* Chain in any previously buffered data */
1915 if (req_ctx->nbuf) {
1916 nsg = (req_ctx->nbuf < nbytes_to_hash) ? 2 : 1;
1917 sg_init_table(req_ctx->bufsl, nsg);
1918 sg_set_buf(req_ctx->bufsl, req_ctx->buf, req_ctx->nbuf);
1919 if (nsg > 1)
Dan Williamsc56f6d12015-08-07 18:15:13 +02001920 sg_chain(req_ctx->bufsl, 2, areq->src);
Lee Nipper497f2e62010-05-19 19:20:36 +10001921 req_ctx->psrc = req_ctx->bufsl;
Lee Nipper5e833bc2010-06-16 15:29:15 +10001922 } else
Lee Nipper497f2e62010-05-19 19:20:36 +10001923 req_ctx->psrc = areq->src;
Lee Nipper497f2e62010-05-19 19:20:36 +10001924
Lee Nipper5e833bc2010-06-16 15:29:15 +10001925 if (to_hash_later) {
LABBE Corentin8e409fe2015-11-04 21:13:34 +01001926 nents = sg_nents_for_len(areq->src, nbytes);
1927 if (nents < 0) {
1928 dev_err(ctx->dev, "Invalid number of src SG.\n");
1929 return nents;
1930 }
Akinobu Mitad0525722013-07-08 16:01:55 -07001931 sg_pcopy_to_buffer(areq->src, nents,
Lee Nipper5e833bc2010-06-16 15:29:15 +10001932 req_ctx->bufnext,
1933 to_hash_later,
1934 nbytes - to_hash_later);
Lee Nipper497f2e62010-05-19 19:20:36 +10001935 }
Lee Nipper5e833bc2010-06-16 15:29:15 +10001936 req_ctx->to_hash_later = to_hash_later;
Lee Nipper497f2e62010-05-19 19:20:36 +10001937
Lee Nipper5e833bc2010-06-16 15:29:15 +10001938 /* Allocate extended descriptor */
Lee Nipper497f2e62010-05-19 19:20:36 +10001939 edesc = ahash_edesc_alloc(areq, nbytes_to_hash);
1940 if (IS_ERR(edesc))
1941 return PTR_ERR(edesc);
1942
1943 edesc->desc.hdr = ctx->desc_hdr_template;
1944
1945 /* On last one, request SEC to pad; otherwise continue */
1946 if (req_ctx->last)
1947 edesc->desc.hdr |= DESC_HDR_MODE0_MDEU_PAD;
1948 else
1949 edesc->desc.hdr |= DESC_HDR_MODE0_MDEU_CONT;
1950
Kim Phillips60f208d2010-05-19 19:21:53 +10001951 /* request SEC to INIT hash. */
1952 if (req_ctx->first && !req_ctx->swinit)
Lee Nipper497f2e62010-05-19 19:20:36 +10001953 edesc->desc.hdr |= DESC_HDR_MODE0_MDEU_INIT;
1954
1955 /* When the tfm context has a keylen, it's an HMAC.
1956 * A first or last (ie. not middle) descriptor must request HMAC.
1957 */
1958 if (ctx->keylen && (req_ctx->first || req_ctx->last))
1959 edesc->desc.hdr |= DESC_HDR_MODE0_MDEU_HMAC;
1960
1961 return common_nonsnoop_hash(edesc, areq, nbytes_to_hash,
1962 ahash_done);
1963}
1964
1965static int ahash_update(struct ahash_request *areq)
1966{
1967 struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
1968
1969 req_ctx->last = 0;
1970
1971 return ahash_process_req(areq, areq->nbytes);
1972}
1973
1974static int ahash_final(struct ahash_request *areq)
1975{
1976 struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
1977
1978 req_ctx->last = 1;
1979
1980 return ahash_process_req(areq, 0);
1981}
1982
1983static int ahash_finup(struct ahash_request *areq)
1984{
1985 struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
1986
1987 req_ctx->last = 1;
1988
1989 return ahash_process_req(areq, areq->nbytes);
1990}
1991
1992static int ahash_digest(struct ahash_request *areq)
1993{
1994 struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
Kim Phillips60f208d2010-05-19 19:21:53 +10001995 struct crypto_ahash *ahash = crypto_ahash_reqtfm(areq);
Lee Nipper497f2e62010-05-19 19:20:36 +10001996
Kim Phillips60f208d2010-05-19 19:21:53 +10001997 ahash->init(areq);
Lee Nipper497f2e62010-05-19 19:20:36 +10001998 req_ctx->last = 1;
1999
2000 return ahash_process_req(areq, areq->nbytes);
2001}
2002
Horia Geant?3639ca82016-04-21 19:24:55 +03002003static int ahash_export(struct ahash_request *areq, void *out)
2004{
2005 struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
2006 struct talitos_export_state *export = out;
2007
2008 memcpy(export->hw_context, req_ctx->hw_context,
2009 req_ctx->hw_context_size);
2010 memcpy(export->buf, req_ctx->buf, req_ctx->nbuf);
2011 export->swinit = req_ctx->swinit;
2012 export->first = req_ctx->first;
2013 export->last = req_ctx->last;
2014 export->to_hash_later = req_ctx->to_hash_later;
2015 export->nbuf = req_ctx->nbuf;
2016
2017 return 0;
2018}
2019
2020static int ahash_import(struct ahash_request *areq, const void *in)
2021{
2022 struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
2023 struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
2024 const struct talitos_export_state *export = in;
2025
2026 memset(req_ctx, 0, sizeof(*req_ctx));
2027 req_ctx->hw_context_size =
2028 (crypto_ahash_digestsize(tfm) <= SHA256_DIGEST_SIZE)
2029 ? TALITOS_MDEU_CONTEXT_SIZE_MD5_SHA1_SHA256
2030 : TALITOS_MDEU_CONTEXT_SIZE_SHA384_SHA512;
2031 memcpy(req_ctx->hw_context, export->hw_context,
2032 req_ctx->hw_context_size);
2033 memcpy(req_ctx->buf, export->buf, export->nbuf);
2034 req_ctx->swinit = export->swinit;
2035 req_ctx->first = export->first;
2036 req_ctx->last = export->last;
2037 req_ctx->to_hash_later = export->to_hash_later;
2038 req_ctx->nbuf = export->nbuf;
2039
2040 return 0;
2041}
2042
Lee Nipper79b3a412011-11-21 16:13:25 +08002043struct keyhash_result {
2044 struct completion completion;
2045 int err;
2046};
2047
2048static void keyhash_complete(struct crypto_async_request *req, int err)
2049{
2050 struct keyhash_result *res = req->data;
2051
2052 if (err == -EINPROGRESS)
2053 return;
2054
2055 res->err = err;
2056 complete(&res->completion);
2057}
2058
2059static int keyhash(struct crypto_ahash *tfm, const u8 *key, unsigned int keylen,
2060 u8 *hash)
2061{
2062 struct talitos_ctx *ctx = crypto_tfm_ctx(crypto_ahash_tfm(tfm));
2063
2064 struct scatterlist sg[1];
2065 struct ahash_request *req;
2066 struct keyhash_result hresult;
2067 int ret;
2068
2069 init_completion(&hresult.completion);
2070
2071 req = ahash_request_alloc(tfm, GFP_KERNEL);
2072 if (!req)
2073 return -ENOMEM;
2074
2075 /* Keep tfm keylen == 0 during hash of the long key */
2076 ctx->keylen = 0;
2077 ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
2078 keyhash_complete, &hresult);
2079
2080 sg_init_one(&sg[0], key, keylen);
2081
2082 ahash_request_set_crypt(req, sg, hash, keylen);
2083 ret = crypto_ahash_digest(req);
2084 switch (ret) {
2085 case 0:
2086 break;
2087 case -EINPROGRESS:
2088 case -EBUSY:
2089 ret = wait_for_completion_interruptible(
2090 &hresult.completion);
2091 if (!ret)
2092 ret = hresult.err;
2093 break;
2094 default:
2095 break;
2096 }
2097 ahash_request_free(req);
2098
2099 return ret;
2100}
2101
2102static int ahash_setkey(struct crypto_ahash *tfm, const u8 *key,
2103 unsigned int keylen)
2104{
2105 struct talitos_ctx *ctx = crypto_tfm_ctx(crypto_ahash_tfm(tfm));
2106 unsigned int blocksize =
2107 crypto_tfm_alg_blocksize(crypto_ahash_tfm(tfm));
2108 unsigned int digestsize = crypto_ahash_digestsize(tfm);
2109 unsigned int keysize = keylen;
2110 u8 hash[SHA512_DIGEST_SIZE];
2111 int ret;
2112
2113 if (keylen <= blocksize)
2114 memcpy(ctx->key, key, keysize);
2115 else {
2116 /* Must get the hash of the long key */
2117 ret = keyhash(tfm, key, keylen, hash);
2118
2119 if (ret) {
2120 crypto_ahash_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN);
2121 return -EINVAL;
2122 }
2123
2124 keysize = digestsize;
2125 memcpy(ctx->key, hash, digestsize);
2126 }
2127
2128 ctx->keylen = keysize;
2129
2130 return 0;
2131}
2132
2133
Kim Phillips9c4a7962008-06-23 19:50:15 +08002134struct talitos_alg_template {
Lee Nipperd5e4aae2010-05-19 19:18:38 +10002135 u32 type;
2136 union {
2137 struct crypto_alg crypto;
Lee Nipperacbf7c622010-05-19 19:19:33 +10002138 struct ahash_alg hash;
Herbert Xuaeb4c132015-07-30 17:53:22 +08002139 struct aead_alg aead;
Lee Nipperd5e4aae2010-05-19 19:18:38 +10002140 } alg;
Kim Phillips9c4a7962008-06-23 19:50:15 +08002141 __be32 desc_hdr_template;
2142};
2143
2144static struct talitos_alg_template driver_algs[] = {
Horia Geanta991155b2013-03-20 16:31:38 +02002145 /* AEAD algorithms. These use a single-pass ipsec_esp descriptor */
Lee Nipperd5e4aae2010-05-19 19:18:38 +10002146 { .type = CRYPTO_ALG_TYPE_AEAD,
Herbert Xuaeb4c132015-07-30 17:53:22 +08002147 .alg.aead = {
2148 .base = {
2149 .cra_name = "authenc(hmac(sha1),cbc(aes))",
2150 .cra_driver_name = "authenc-hmac-sha1-"
2151 "cbc-aes-talitos",
2152 .cra_blocksize = AES_BLOCK_SIZE,
2153 .cra_flags = CRYPTO_ALG_ASYNC,
2154 },
2155 .ivsize = AES_BLOCK_SIZE,
2156 .maxauthsize = SHA1_DIGEST_SIZE,
Lee Nipper56af8cd2009-03-29 15:50:50 +08002157 },
Kim Phillips9c4a7962008-06-23 19:50:15 +08002158 .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
2159 DESC_HDR_SEL0_AESU |
2160 DESC_HDR_MODE0_AESU_CBC |
2161 DESC_HDR_SEL1_MDEUA |
2162 DESC_HDR_MODE1_MDEU_INIT |
2163 DESC_HDR_MODE1_MDEU_PAD |
2164 DESC_HDR_MODE1_MDEU_SHA1_HMAC,
Lee Nipper70bcaca2008-07-03 19:08:46 +08002165 },
Lee Nipperd5e4aae2010-05-19 19:18:38 +10002166 { .type = CRYPTO_ALG_TYPE_AEAD,
Herbert Xuaeb4c132015-07-30 17:53:22 +08002167 .alg.aead = {
2168 .base = {
2169 .cra_name = "authenc(hmac(sha1),"
2170 "cbc(des3_ede))",
2171 .cra_driver_name = "authenc-hmac-sha1-"
2172 "cbc-3des-talitos",
2173 .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2174 .cra_flags = CRYPTO_ALG_ASYNC,
2175 },
2176 .ivsize = DES3_EDE_BLOCK_SIZE,
2177 .maxauthsize = SHA1_DIGEST_SIZE,
Lee Nipper56af8cd2009-03-29 15:50:50 +08002178 },
Lee Nipper70bcaca2008-07-03 19:08:46 +08002179 .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
2180 DESC_HDR_SEL0_DEU |
2181 DESC_HDR_MODE0_DEU_CBC |
2182 DESC_HDR_MODE0_DEU_3DES |
2183 DESC_HDR_SEL1_MDEUA |
2184 DESC_HDR_MODE1_MDEU_INIT |
2185 DESC_HDR_MODE1_MDEU_PAD |
2186 DESC_HDR_MODE1_MDEU_SHA1_HMAC,
Lee Nipper3952f172008-07-10 18:29:18 +08002187 },
Horia Geanta357fb602012-07-03 19:16:53 +03002188 { .type = CRYPTO_ALG_TYPE_AEAD,
Herbert Xuaeb4c132015-07-30 17:53:22 +08002189 .alg.aead = {
2190 .base = {
2191 .cra_name = "authenc(hmac(sha224),cbc(aes))",
2192 .cra_driver_name = "authenc-hmac-sha224-"
2193 "cbc-aes-talitos",
2194 .cra_blocksize = AES_BLOCK_SIZE,
2195 .cra_flags = CRYPTO_ALG_ASYNC,
2196 },
2197 .ivsize = AES_BLOCK_SIZE,
2198 .maxauthsize = SHA224_DIGEST_SIZE,
Horia Geanta357fb602012-07-03 19:16:53 +03002199 },
2200 .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
2201 DESC_HDR_SEL0_AESU |
2202 DESC_HDR_MODE0_AESU_CBC |
2203 DESC_HDR_SEL1_MDEUA |
2204 DESC_HDR_MODE1_MDEU_INIT |
2205 DESC_HDR_MODE1_MDEU_PAD |
2206 DESC_HDR_MODE1_MDEU_SHA224_HMAC,
2207 },
2208 { .type = CRYPTO_ALG_TYPE_AEAD,
Herbert Xuaeb4c132015-07-30 17:53:22 +08002209 .alg.aead = {
2210 .base = {
2211 .cra_name = "authenc(hmac(sha224),"
2212 "cbc(des3_ede))",
2213 .cra_driver_name = "authenc-hmac-sha224-"
2214 "cbc-3des-talitos",
2215 .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2216 .cra_flags = CRYPTO_ALG_ASYNC,
2217 },
2218 .ivsize = DES3_EDE_BLOCK_SIZE,
2219 .maxauthsize = SHA224_DIGEST_SIZE,
Horia Geanta357fb602012-07-03 19:16:53 +03002220 },
2221 .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
2222 DESC_HDR_SEL0_DEU |
2223 DESC_HDR_MODE0_DEU_CBC |
2224 DESC_HDR_MODE0_DEU_3DES |
2225 DESC_HDR_SEL1_MDEUA |
2226 DESC_HDR_MODE1_MDEU_INIT |
2227 DESC_HDR_MODE1_MDEU_PAD |
2228 DESC_HDR_MODE1_MDEU_SHA224_HMAC,
2229 },
Lee Nipperd5e4aae2010-05-19 19:18:38 +10002230 { .type = CRYPTO_ALG_TYPE_AEAD,
Herbert Xuaeb4c132015-07-30 17:53:22 +08002231 .alg.aead = {
2232 .base = {
2233 .cra_name = "authenc(hmac(sha256),cbc(aes))",
2234 .cra_driver_name = "authenc-hmac-sha256-"
2235 "cbc-aes-talitos",
2236 .cra_blocksize = AES_BLOCK_SIZE,
2237 .cra_flags = CRYPTO_ALG_ASYNC,
2238 },
2239 .ivsize = AES_BLOCK_SIZE,
2240 .maxauthsize = SHA256_DIGEST_SIZE,
Lee Nipper56af8cd2009-03-29 15:50:50 +08002241 },
Lee Nipper3952f172008-07-10 18:29:18 +08002242 .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
2243 DESC_HDR_SEL0_AESU |
2244 DESC_HDR_MODE0_AESU_CBC |
2245 DESC_HDR_SEL1_MDEUA |
2246 DESC_HDR_MODE1_MDEU_INIT |
2247 DESC_HDR_MODE1_MDEU_PAD |
2248 DESC_HDR_MODE1_MDEU_SHA256_HMAC,
2249 },
Lee Nipperd5e4aae2010-05-19 19:18:38 +10002250 { .type = CRYPTO_ALG_TYPE_AEAD,
Herbert Xuaeb4c132015-07-30 17:53:22 +08002251 .alg.aead = {
2252 .base = {
2253 .cra_name = "authenc(hmac(sha256),"
2254 "cbc(des3_ede))",
2255 .cra_driver_name = "authenc-hmac-sha256-"
2256 "cbc-3des-talitos",
2257 .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2258 .cra_flags = CRYPTO_ALG_ASYNC,
2259 },
2260 .ivsize = DES3_EDE_BLOCK_SIZE,
2261 .maxauthsize = SHA256_DIGEST_SIZE,
Lee Nipper56af8cd2009-03-29 15:50:50 +08002262 },
Lee Nipper3952f172008-07-10 18:29:18 +08002263 .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
2264 DESC_HDR_SEL0_DEU |
2265 DESC_HDR_MODE0_DEU_CBC |
2266 DESC_HDR_MODE0_DEU_3DES |
2267 DESC_HDR_SEL1_MDEUA |
2268 DESC_HDR_MODE1_MDEU_INIT |
2269 DESC_HDR_MODE1_MDEU_PAD |
2270 DESC_HDR_MODE1_MDEU_SHA256_HMAC,
2271 },
Lee Nipperd5e4aae2010-05-19 19:18:38 +10002272 { .type = CRYPTO_ALG_TYPE_AEAD,
Herbert Xuaeb4c132015-07-30 17:53:22 +08002273 .alg.aead = {
2274 .base = {
2275 .cra_name = "authenc(hmac(sha384),cbc(aes))",
2276 .cra_driver_name = "authenc-hmac-sha384-"
2277 "cbc-aes-talitos",
2278 .cra_blocksize = AES_BLOCK_SIZE,
2279 .cra_flags = CRYPTO_ALG_ASYNC,
2280 },
2281 .ivsize = AES_BLOCK_SIZE,
2282 .maxauthsize = SHA384_DIGEST_SIZE,
Horia Geanta357fb602012-07-03 19:16:53 +03002283 },
2284 .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
2285 DESC_HDR_SEL0_AESU |
2286 DESC_HDR_MODE0_AESU_CBC |
2287 DESC_HDR_SEL1_MDEUB |
2288 DESC_HDR_MODE1_MDEU_INIT |
2289 DESC_HDR_MODE1_MDEU_PAD |
2290 DESC_HDR_MODE1_MDEUB_SHA384_HMAC,
2291 },
2292 { .type = CRYPTO_ALG_TYPE_AEAD,
Herbert Xuaeb4c132015-07-30 17:53:22 +08002293 .alg.aead = {
2294 .base = {
2295 .cra_name = "authenc(hmac(sha384),"
2296 "cbc(des3_ede))",
2297 .cra_driver_name = "authenc-hmac-sha384-"
2298 "cbc-3des-talitos",
2299 .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2300 .cra_flags = CRYPTO_ALG_ASYNC,
2301 },
2302 .ivsize = DES3_EDE_BLOCK_SIZE,
2303 .maxauthsize = SHA384_DIGEST_SIZE,
Horia Geanta357fb602012-07-03 19:16:53 +03002304 },
2305 .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
2306 DESC_HDR_SEL0_DEU |
2307 DESC_HDR_MODE0_DEU_CBC |
2308 DESC_HDR_MODE0_DEU_3DES |
2309 DESC_HDR_SEL1_MDEUB |
2310 DESC_HDR_MODE1_MDEU_INIT |
2311 DESC_HDR_MODE1_MDEU_PAD |
2312 DESC_HDR_MODE1_MDEUB_SHA384_HMAC,
2313 },
2314 { .type = CRYPTO_ALG_TYPE_AEAD,
Herbert Xuaeb4c132015-07-30 17:53:22 +08002315 .alg.aead = {
2316 .base = {
2317 .cra_name = "authenc(hmac(sha512),cbc(aes))",
2318 .cra_driver_name = "authenc-hmac-sha512-"
2319 "cbc-aes-talitos",
2320 .cra_blocksize = AES_BLOCK_SIZE,
2321 .cra_flags = CRYPTO_ALG_ASYNC,
2322 },
2323 .ivsize = AES_BLOCK_SIZE,
2324 .maxauthsize = SHA512_DIGEST_SIZE,
Horia Geanta357fb602012-07-03 19:16:53 +03002325 },
2326 .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
2327 DESC_HDR_SEL0_AESU |
2328 DESC_HDR_MODE0_AESU_CBC |
2329 DESC_HDR_SEL1_MDEUB |
2330 DESC_HDR_MODE1_MDEU_INIT |
2331 DESC_HDR_MODE1_MDEU_PAD |
2332 DESC_HDR_MODE1_MDEUB_SHA512_HMAC,
2333 },
2334 { .type = CRYPTO_ALG_TYPE_AEAD,
Herbert Xuaeb4c132015-07-30 17:53:22 +08002335 .alg.aead = {
2336 .base = {
2337 .cra_name = "authenc(hmac(sha512),"
2338 "cbc(des3_ede))",
2339 .cra_driver_name = "authenc-hmac-sha512-"
2340 "cbc-3des-talitos",
2341 .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2342 .cra_flags = CRYPTO_ALG_ASYNC,
2343 },
2344 .ivsize = DES3_EDE_BLOCK_SIZE,
2345 .maxauthsize = SHA512_DIGEST_SIZE,
Horia Geanta357fb602012-07-03 19:16:53 +03002346 },
2347 .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
2348 DESC_HDR_SEL0_DEU |
2349 DESC_HDR_MODE0_DEU_CBC |
2350 DESC_HDR_MODE0_DEU_3DES |
2351 DESC_HDR_SEL1_MDEUB |
2352 DESC_HDR_MODE1_MDEU_INIT |
2353 DESC_HDR_MODE1_MDEU_PAD |
2354 DESC_HDR_MODE1_MDEUB_SHA512_HMAC,
2355 },
2356 { .type = CRYPTO_ALG_TYPE_AEAD,
Herbert Xuaeb4c132015-07-30 17:53:22 +08002357 .alg.aead = {
2358 .base = {
2359 .cra_name = "authenc(hmac(md5),cbc(aes))",
2360 .cra_driver_name = "authenc-hmac-md5-"
2361 "cbc-aes-talitos",
2362 .cra_blocksize = AES_BLOCK_SIZE,
2363 .cra_flags = CRYPTO_ALG_ASYNC,
2364 },
2365 .ivsize = AES_BLOCK_SIZE,
2366 .maxauthsize = MD5_DIGEST_SIZE,
Lee Nipper56af8cd2009-03-29 15:50:50 +08002367 },
Lee Nipper3952f172008-07-10 18:29:18 +08002368 .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
2369 DESC_HDR_SEL0_AESU |
2370 DESC_HDR_MODE0_AESU_CBC |
2371 DESC_HDR_SEL1_MDEUA |
2372 DESC_HDR_MODE1_MDEU_INIT |
2373 DESC_HDR_MODE1_MDEU_PAD |
2374 DESC_HDR_MODE1_MDEU_MD5_HMAC,
2375 },
Lee Nipperd5e4aae2010-05-19 19:18:38 +10002376 { .type = CRYPTO_ALG_TYPE_AEAD,
Herbert Xuaeb4c132015-07-30 17:53:22 +08002377 .alg.aead = {
2378 .base = {
2379 .cra_name = "authenc(hmac(md5),cbc(des3_ede))",
2380 .cra_driver_name = "authenc-hmac-md5-"
2381 "cbc-3des-talitos",
2382 .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2383 .cra_flags = CRYPTO_ALG_ASYNC,
2384 },
2385 .ivsize = DES3_EDE_BLOCK_SIZE,
2386 .maxauthsize = MD5_DIGEST_SIZE,
Lee Nipper56af8cd2009-03-29 15:50:50 +08002387 },
Lee Nipper3952f172008-07-10 18:29:18 +08002388 .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
2389 DESC_HDR_SEL0_DEU |
2390 DESC_HDR_MODE0_DEU_CBC |
2391 DESC_HDR_MODE0_DEU_3DES |
2392 DESC_HDR_SEL1_MDEUA |
2393 DESC_HDR_MODE1_MDEU_INIT |
2394 DESC_HDR_MODE1_MDEU_PAD |
2395 DESC_HDR_MODE1_MDEU_MD5_HMAC,
Lee Nipper4de9d0b2009-03-29 15:52:32 +08002396 },
2397 /* ABLKCIPHER algorithms. */
Lee Nipperd5e4aae2010-05-19 19:18:38 +10002398 { .type = CRYPTO_ALG_TYPE_ABLKCIPHER,
2399 .alg.crypto = {
LEROY Christophe5e75ae12015-12-01 12:44:15 +01002400 .cra_name = "ecb(aes)",
2401 .cra_driver_name = "ecb-aes-talitos",
2402 .cra_blocksize = AES_BLOCK_SIZE,
2403 .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER |
2404 CRYPTO_ALG_ASYNC,
2405 .cra_ablkcipher = {
2406 .min_keysize = AES_MIN_KEY_SIZE,
2407 .max_keysize = AES_MAX_KEY_SIZE,
2408 .ivsize = AES_BLOCK_SIZE,
2409 }
2410 },
2411 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2412 DESC_HDR_SEL0_AESU,
2413 },
2414 { .type = CRYPTO_ALG_TYPE_ABLKCIPHER,
2415 .alg.crypto = {
Lee Nipper4de9d0b2009-03-29 15:52:32 +08002416 .cra_name = "cbc(aes)",
2417 .cra_driver_name = "cbc-aes-talitos",
2418 .cra_blocksize = AES_BLOCK_SIZE,
2419 .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER |
2420 CRYPTO_ALG_ASYNC,
Lee Nipper4de9d0b2009-03-29 15:52:32 +08002421 .cra_ablkcipher = {
Lee Nipper4de9d0b2009-03-29 15:52:32 +08002422 .min_keysize = AES_MIN_KEY_SIZE,
2423 .max_keysize = AES_MAX_KEY_SIZE,
2424 .ivsize = AES_BLOCK_SIZE,
2425 }
2426 },
2427 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2428 DESC_HDR_SEL0_AESU |
2429 DESC_HDR_MODE0_AESU_CBC,
2430 },
Lee Nipperd5e4aae2010-05-19 19:18:38 +10002431 { .type = CRYPTO_ALG_TYPE_ABLKCIPHER,
2432 .alg.crypto = {
LEROY Christophe5e75ae12015-12-01 12:44:15 +01002433 .cra_name = "ctr(aes)",
2434 .cra_driver_name = "ctr-aes-talitos",
2435 .cra_blocksize = AES_BLOCK_SIZE,
2436 .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER |
2437 CRYPTO_ALG_ASYNC,
2438 .cra_ablkcipher = {
2439 .min_keysize = AES_MIN_KEY_SIZE,
2440 .max_keysize = AES_MAX_KEY_SIZE,
2441 .ivsize = AES_BLOCK_SIZE,
2442 }
2443 },
2444 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2445 DESC_HDR_SEL0_AESU |
2446 DESC_HDR_MODE0_AESU_CTR,
2447 },
2448 { .type = CRYPTO_ALG_TYPE_ABLKCIPHER,
2449 .alg.crypto = {
2450 .cra_name = "ecb(des)",
2451 .cra_driver_name = "ecb-des-talitos",
2452 .cra_blocksize = DES_BLOCK_SIZE,
2453 .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER |
2454 CRYPTO_ALG_ASYNC,
2455 .cra_ablkcipher = {
2456 .min_keysize = DES_KEY_SIZE,
2457 .max_keysize = DES_KEY_SIZE,
2458 .ivsize = DES_BLOCK_SIZE,
2459 }
2460 },
2461 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2462 DESC_HDR_SEL0_DEU,
2463 },
2464 { .type = CRYPTO_ALG_TYPE_ABLKCIPHER,
2465 .alg.crypto = {
2466 .cra_name = "cbc(des)",
2467 .cra_driver_name = "cbc-des-talitos",
2468 .cra_blocksize = DES_BLOCK_SIZE,
2469 .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER |
2470 CRYPTO_ALG_ASYNC,
2471 .cra_ablkcipher = {
2472 .min_keysize = DES_KEY_SIZE,
2473 .max_keysize = DES_KEY_SIZE,
2474 .ivsize = DES_BLOCK_SIZE,
2475 }
2476 },
2477 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2478 DESC_HDR_SEL0_DEU |
2479 DESC_HDR_MODE0_DEU_CBC,
2480 },
2481 { .type = CRYPTO_ALG_TYPE_ABLKCIPHER,
2482 .alg.crypto = {
2483 .cra_name = "ecb(des3_ede)",
2484 .cra_driver_name = "ecb-3des-talitos",
2485 .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2486 .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER |
2487 CRYPTO_ALG_ASYNC,
2488 .cra_ablkcipher = {
2489 .min_keysize = DES3_EDE_KEY_SIZE,
2490 .max_keysize = DES3_EDE_KEY_SIZE,
2491 .ivsize = DES3_EDE_BLOCK_SIZE,
2492 }
2493 },
2494 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2495 DESC_HDR_SEL0_DEU |
2496 DESC_HDR_MODE0_DEU_3DES,
2497 },
2498 { .type = CRYPTO_ALG_TYPE_ABLKCIPHER,
2499 .alg.crypto = {
Lee Nipper4de9d0b2009-03-29 15:52:32 +08002500 .cra_name = "cbc(des3_ede)",
2501 .cra_driver_name = "cbc-3des-talitos",
2502 .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2503 .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER |
2504 CRYPTO_ALG_ASYNC,
Lee Nipper4de9d0b2009-03-29 15:52:32 +08002505 .cra_ablkcipher = {
Lee Nipper4de9d0b2009-03-29 15:52:32 +08002506 .min_keysize = DES3_EDE_KEY_SIZE,
2507 .max_keysize = DES3_EDE_KEY_SIZE,
2508 .ivsize = DES3_EDE_BLOCK_SIZE,
2509 }
2510 },
2511 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2512 DESC_HDR_SEL0_DEU |
2513 DESC_HDR_MODE0_DEU_CBC |
2514 DESC_HDR_MODE0_DEU_3DES,
Lee Nipper497f2e62010-05-19 19:20:36 +10002515 },
2516 /* AHASH algorithms. */
2517 { .type = CRYPTO_ALG_TYPE_AHASH,
2518 .alg.hash = {
Lee Nipper497f2e62010-05-19 19:20:36 +10002519 .halg.digestsize = MD5_DIGEST_SIZE,
Horia Geant?3639ca82016-04-21 19:24:55 +03002520 .halg.statesize = sizeof(struct talitos_export_state),
Lee Nipper497f2e62010-05-19 19:20:36 +10002521 .halg.base = {
2522 .cra_name = "md5",
2523 .cra_driver_name = "md5-talitos",
Martin Hicksb3988612015-03-03 08:21:34 -05002524 .cra_blocksize = MD5_HMAC_BLOCK_SIZE,
Lee Nipper497f2e62010-05-19 19:20:36 +10002525 .cra_flags = CRYPTO_ALG_TYPE_AHASH |
2526 CRYPTO_ALG_ASYNC,
Lee Nipper497f2e62010-05-19 19:20:36 +10002527 }
2528 },
2529 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2530 DESC_HDR_SEL0_MDEUA |
2531 DESC_HDR_MODE0_MDEU_MD5,
2532 },
2533 { .type = CRYPTO_ALG_TYPE_AHASH,
2534 .alg.hash = {
Lee Nipper497f2e62010-05-19 19:20:36 +10002535 .halg.digestsize = SHA1_DIGEST_SIZE,
Horia Geant?3639ca82016-04-21 19:24:55 +03002536 .halg.statesize = sizeof(struct talitos_export_state),
Lee Nipper497f2e62010-05-19 19:20:36 +10002537 .halg.base = {
2538 .cra_name = "sha1",
2539 .cra_driver_name = "sha1-talitos",
2540 .cra_blocksize = SHA1_BLOCK_SIZE,
2541 .cra_flags = CRYPTO_ALG_TYPE_AHASH |
2542 CRYPTO_ALG_ASYNC,
Lee Nipper497f2e62010-05-19 19:20:36 +10002543 }
2544 },
2545 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2546 DESC_HDR_SEL0_MDEUA |
2547 DESC_HDR_MODE0_MDEU_SHA1,
2548 },
2549 { .type = CRYPTO_ALG_TYPE_AHASH,
2550 .alg.hash = {
Kim Phillips60f208d2010-05-19 19:21:53 +10002551 .halg.digestsize = SHA224_DIGEST_SIZE,
Horia Geant?3639ca82016-04-21 19:24:55 +03002552 .halg.statesize = sizeof(struct talitos_export_state),
Kim Phillips60f208d2010-05-19 19:21:53 +10002553 .halg.base = {
2554 .cra_name = "sha224",
2555 .cra_driver_name = "sha224-talitos",
2556 .cra_blocksize = SHA224_BLOCK_SIZE,
2557 .cra_flags = CRYPTO_ALG_TYPE_AHASH |
2558 CRYPTO_ALG_ASYNC,
Kim Phillips60f208d2010-05-19 19:21:53 +10002559 }
2560 },
2561 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2562 DESC_HDR_SEL0_MDEUA |
2563 DESC_HDR_MODE0_MDEU_SHA224,
2564 },
2565 { .type = CRYPTO_ALG_TYPE_AHASH,
2566 .alg.hash = {
Lee Nipper497f2e62010-05-19 19:20:36 +10002567 .halg.digestsize = SHA256_DIGEST_SIZE,
Horia Geant?3639ca82016-04-21 19:24:55 +03002568 .halg.statesize = sizeof(struct talitos_export_state),
Lee Nipper497f2e62010-05-19 19:20:36 +10002569 .halg.base = {
2570 .cra_name = "sha256",
2571 .cra_driver_name = "sha256-talitos",
2572 .cra_blocksize = SHA256_BLOCK_SIZE,
2573 .cra_flags = CRYPTO_ALG_TYPE_AHASH |
2574 CRYPTO_ALG_ASYNC,
Lee Nipper497f2e62010-05-19 19:20:36 +10002575 }
2576 },
2577 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2578 DESC_HDR_SEL0_MDEUA |
2579 DESC_HDR_MODE0_MDEU_SHA256,
2580 },
2581 { .type = CRYPTO_ALG_TYPE_AHASH,
2582 .alg.hash = {
Lee Nipper497f2e62010-05-19 19:20:36 +10002583 .halg.digestsize = SHA384_DIGEST_SIZE,
Horia Geant?3639ca82016-04-21 19:24:55 +03002584 .halg.statesize = sizeof(struct talitos_export_state),
Lee Nipper497f2e62010-05-19 19:20:36 +10002585 .halg.base = {
2586 .cra_name = "sha384",
2587 .cra_driver_name = "sha384-talitos",
2588 .cra_blocksize = SHA384_BLOCK_SIZE,
2589 .cra_flags = CRYPTO_ALG_TYPE_AHASH |
2590 CRYPTO_ALG_ASYNC,
Lee Nipper497f2e62010-05-19 19:20:36 +10002591 }
2592 },
2593 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2594 DESC_HDR_SEL0_MDEUB |
2595 DESC_HDR_MODE0_MDEUB_SHA384,
2596 },
2597 { .type = CRYPTO_ALG_TYPE_AHASH,
2598 .alg.hash = {
Lee Nipper497f2e62010-05-19 19:20:36 +10002599 .halg.digestsize = SHA512_DIGEST_SIZE,
Horia Geant?3639ca82016-04-21 19:24:55 +03002600 .halg.statesize = sizeof(struct talitos_export_state),
Lee Nipper497f2e62010-05-19 19:20:36 +10002601 .halg.base = {
2602 .cra_name = "sha512",
2603 .cra_driver_name = "sha512-talitos",
2604 .cra_blocksize = SHA512_BLOCK_SIZE,
2605 .cra_flags = CRYPTO_ALG_TYPE_AHASH |
2606 CRYPTO_ALG_ASYNC,
Lee Nipper497f2e62010-05-19 19:20:36 +10002607 }
2608 },
2609 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2610 DESC_HDR_SEL0_MDEUB |
2611 DESC_HDR_MODE0_MDEUB_SHA512,
2612 },
Lee Nipper79b3a412011-11-21 16:13:25 +08002613 { .type = CRYPTO_ALG_TYPE_AHASH,
2614 .alg.hash = {
Lee Nipper79b3a412011-11-21 16:13:25 +08002615 .halg.digestsize = MD5_DIGEST_SIZE,
Horia Geant?3639ca82016-04-21 19:24:55 +03002616 .halg.statesize = sizeof(struct talitos_export_state),
Lee Nipper79b3a412011-11-21 16:13:25 +08002617 .halg.base = {
2618 .cra_name = "hmac(md5)",
2619 .cra_driver_name = "hmac-md5-talitos",
Martin Hicksb3988612015-03-03 08:21:34 -05002620 .cra_blocksize = MD5_HMAC_BLOCK_SIZE,
Lee Nipper79b3a412011-11-21 16:13:25 +08002621 .cra_flags = CRYPTO_ALG_TYPE_AHASH |
2622 CRYPTO_ALG_ASYNC,
Lee Nipper79b3a412011-11-21 16:13:25 +08002623 }
2624 },
2625 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2626 DESC_HDR_SEL0_MDEUA |
2627 DESC_HDR_MODE0_MDEU_MD5,
2628 },
2629 { .type = CRYPTO_ALG_TYPE_AHASH,
2630 .alg.hash = {
Lee Nipper79b3a412011-11-21 16:13:25 +08002631 .halg.digestsize = SHA1_DIGEST_SIZE,
Horia Geant?3639ca82016-04-21 19:24:55 +03002632 .halg.statesize = sizeof(struct talitos_export_state),
Lee Nipper79b3a412011-11-21 16:13:25 +08002633 .halg.base = {
2634 .cra_name = "hmac(sha1)",
2635 .cra_driver_name = "hmac-sha1-talitos",
2636 .cra_blocksize = SHA1_BLOCK_SIZE,
2637 .cra_flags = CRYPTO_ALG_TYPE_AHASH |
2638 CRYPTO_ALG_ASYNC,
Lee Nipper79b3a412011-11-21 16:13:25 +08002639 }
2640 },
2641 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2642 DESC_HDR_SEL0_MDEUA |
2643 DESC_HDR_MODE0_MDEU_SHA1,
2644 },
2645 { .type = CRYPTO_ALG_TYPE_AHASH,
2646 .alg.hash = {
Lee Nipper79b3a412011-11-21 16:13:25 +08002647 .halg.digestsize = SHA224_DIGEST_SIZE,
Horia Geant?3639ca82016-04-21 19:24:55 +03002648 .halg.statesize = sizeof(struct talitos_export_state),
Lee Nipper79b3a412011-11-21 16:13:25 +08002649 .halg.base = {
2650 .cra_name = "hmac(sha224)",
2651 .cra_driver_name = "hmac-sha224-talitos",
2652 .cra_blocksize = SHA224_BLOCK_SIZE,
2653 .cra_flags = CRYPTO_ALG_TYPE_AHASH |
2654 CRYPTO_ALG_ASYNC,
Lee Nipper79b3a412011-11-21 16:13:25 +08002655 }
2656 },
2657 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2658 DESC_HDR_SEL0_MDEUA |
2659 DESC_HDR_MODE0_MDEU_SHA224,
2660 },
2661 { .type = CRYPTO_ALG_TYPE_AHASH,
2662 .alg.hash = {
Lee Nipper79b3a412011-11-21 16:13:25 +08002663 .halg.digestsize = SHA256_DIGEST_SIZE,
Horia Geant?3639ca82016-04-21 19:24:55 +03002664 .halg.statesize = sizeof(struct talitos_export_state),
Lee Nipper79b3a412011-11-21 16:13:25 +08002665 .halg.base = {
2666 .cra_name = "hmac(sha256)",
2667 .cra_driver_name = "hmac-sha256-talitos",
2668 .cra_blocksize = SHA256_BLOCK_SIZE,
2669 .cra_flags = CRYPTO_ALG_TYPE_AHASH |
2670 CRYPTO_ALG_ASYNC,
Lee Nipper79b3a412011-11-21 16:13:25 +08002671 }
2672 },
2673 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2674 DESC_HDR_SEL0_MDEUA |
2675 DESC_HDR_MODE0_MDEU_SHA256,
2676 },
2677 { .type = CRYPTO_ALG_TYPE_AHASH,
2678 .alg.hash = {
Lee Nipper79b3a412011-11-21 16:13:25 +08002679 .halg.digestsize = SHA384_DIGEST_SIZE,
Horia Geant?3639ca82016-04-21 19:24:55 +03002680 .halg.statesize = sizeof(struct talitos_export_state),
Lee Nipper79b3a412011-11-21 16:13:25 +08002681 .halg.base = {
2682 .cra_name = "hmac(sha384)",
2683 .cra_driver_name = "hmac-sha384-talitos",
2684 .cra_blocksize = SHA384_BLOCK_SIZE,
2685 .cra_flags = CRYPTO_ALG_TYPE_AHASH |
2686 CRYPTO_ALG_ASYNC,
Lee Nipper79b3a412011-11-21 16:13:25 +08002687 }
2688 },
2689 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2690 DESC_HDR_SEL0_MDEUB |
2691 DESC_HDR_MODE0_MDEUB_SHA384,
2692 },
2693 { .type = CRYPTO_ALG_TYPE_AHASH,
2694 .alg.hash = {
Lee Nipper79b3a412011-11-21 16:13:25 +08002695 .halg.digestsize = SHA512_DIGEST_SIZE,
Horia Geant?3639ca82016-04-21 19:24:55 +03002696 .halg.statesize = sizeof(struct talitos_export_state),
Lee Nipper79b3a412011-11-21 16:13:25 +08002697 .halg.base = {
2698 .cra_name = "hmac(sha512)",
2699 .cra_driver_name = "hmac-sha512-talitos",
2700 .cra_blocksize = SHA512_BLOCK_SIZE,
2701 .cra_flags = CRYPTO_ALG_TYPE_AHASH |
2702 CRYPTO_ALG_ASYNC,
Lee Nipper79b3a412011-11-21 16:13:25 +08002703 }
2704 },
2705 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2706 DESC_HDR_SEL0_MDEUB |
2707 DESC_HDR_MODE0_MDEUB_SHA512,
2708 }
Kim Phillips9c4a7962008-06-23 19:50:15 +08002709};
2710
2711struct talitos_crypto_alg {
2712 struct list_head entry;
2713 struct device *dev;
Lee Nipperacbf7c622010-05-19 19:19:33 +10002714 struct talitos_alg_template algt;
Kim Phillips9c4a7962008-06-23 19:50:15 +08002715};
2716
Jonas Eymann89d124c2016-04-19 20:33:47 +03002717static int talitos_init_common(struct talitos_ctx *ctx,
2718 struct talitos_crypto_alg *talitos_alg)
Kim Phillips9c4a7962008-06-23 19:50:15 +08002719{
Kim Phillips5228f0f2011-07-15 11:21:38 +08002720 struct talitos_private *priv;
Kim Phillips9c4a7962008-06-23 19:50:15 +08002721
2722 /* update context with ptr to dev */
2723 ctx->dev = talitos_alg->dev;
Kim Phillips19bbbc62009-03-29 15:53:59 +08002724
Kim Phillips5228f0f2011-07-15 11:21:38 +08002725 /* assign SEC channel to tfm in round-robin fashion */
2726 priv = dev_get_drvdata(ctx->dev);
2727 ctx->ch = atomic_inc_return(&priv->last_chan) &
2728 (priv->num_channels - 1);
2729
Kim Phillips9c4a7962008-06-23 19:50:15 +08002730 /* copy descriptor header template value */
Lee Nipperacbf7c622010-05-19 19:19:33 +10002731 ctx->desc_hdr_template = talitos_alg->algt.desc_hdr_template;
Kim Phillips9c4a7962008-06-23 19:50:15 +08002732
Kim Phillips602dba52011-07-15 11:21:39 +08002733 /* select done notification */
2734 ctx->desc_hdr_template |= DESC_HDR_DONE_NOTIFY;
2735
Lee Nipper497f2e62010-05-19 19:20:36 +10002736 return 0;
2737}
2738
Jonas Eymann89d124c2016-04-19 20:33:47 +03002739static int talitos_cra_init(struct crypto_tfm *tfm)
2740{
2741 struct crypto_alg *alg = tfm->__crt_alg;
2742 struct talitos_crypto_alg *talitos_alg;
2743 struct talitos_ctx *ctx = crypto_tfm_ctx(tfm);
2744
2745 if ((alg->cra_flags & CRYPTO_ALG_TYPE_MASK) == CRYPTO_ALG_TYPE_AHASH)
2746 talitos_alg = container_of(__crypto_ahash_alg(alg),
2747 struct talitos_crypto_alg,
2748 algt.alg.hash);
2749 else
2750 talitos_alg = container_of(alg, struct talitos_crypto_alg,
2751 algt.alg.crypto);
2752
2753 return talitos_init_common(ctx, talitos_alg);
2754}
2755
Herbert Xuaeb4c132015-07-30 17:53:22 +08002756static int talitos_cra_init_aead(struct crypto_aead *tfm)
Lee Nipper497f2e62010-05-19 19:20:36 +10002757{
Jonas Eymann89d124c2016-04-19 20:33:47 +03002758 struct aead_alg *alg = crypto_aead_alg(tfm);
2759 struct talitos_crypto_alg *talitos_alg;
2760 struct talitos_ctx *ctx = crypto_aead_ctx(tfm);
2761
2762 talitos_alg = container_of(alg, struct talitos_crypto_alg,
2763 algt.alg.aead);
2764
2765 return talitos_init_common(ctx, talitos_alg);
Kim Phillips9c4a7962008-06-23 19:50:15 +08002766}
2767
Lee Nipper497f2e62010-05-19 19:20:36 +10002768static int talitos_cra_init_ahash(struct crypto_tfm *tfm)
2769{
2770 struct talitos_ctx *ctx = crypto_tfm_ctx(tfm);
2771
2772 talitos_cra_init(tfm);
2773
2774 ctx->keylen = 0;
2775 crypto_ahash_set_reqsize(__crypto_ahash_cast(tfm),
2776 sizeof(struct talitos_ahash_req_ctx));
2777
2778 return 0;
2779}
2780
Kim Phillips9c4a7962008-06-23 19:50:15 +08002781/*
2782 * given the alg's descriptor header template, determine whether descriptor
2783 * type and primary/secondary execution units required match the hw
2784 * capabilities description provided in the device tree node.
2785 */
2786static int hw_supports(struct device *dev, __be32 desc_hdr_template)
2787{
2788 struct talitos_private *priv = dev_get_drvdata(dev);
2789 int ret;
2790
2791 ret = (1 << DESC_TYPE(desc_hdr_template) & priv->desc_types) &&
2792 (1 << PRIMARY_EU(desc_hdr_template) & priv->exec_units);
2793
2794 if (SECONDARY_EU(desc_hdr_template))
2795 ret = ret && (1 << SECONDARY_EU(desc_hdr_template)
2796 & priv->exec_units);
2797
2798 return ret;
2799}
2800
Grant Likely2dc11582010-08-06 09:25:50 -06002801static int talitos_remove(struct platform_device *ofdev)
Kim Phillips9c4a7962008-06-23 19:50:15 +08002802{
2803 struct device *dev = &ofdev->dev;
2804 struct talitos_private *priv = dev_get_drvdata(dev);
2805 struct talitos_crypto_alg *t_alg, *n;
2806 int i;
2807
2808 list_for_each_entry_safe(t_alg, n, &priv->alg_list, entry) {
Lee Nipperacbf7c622010-05-19 19:19:33 +10002809 switch (t_alg->algt.type) {
2810 case CRYPTO_ALG_TYPE_ABLKCIPHER:
Lee Nipperacbf7c622010-05-19 19:19:33 +10002811 break;
Herbert Xuaeb4c132015-07-30 17:53:22 +08002812 case CRYPTO_ALG_TYPE_AEAD:
2813 crypto_unregister_aead(&t_alg->algt.alg.aead);
Lee Nipperacbf7c622010-05-19 19:19:33 +10002814 case CRYPTO_ALG_TYPE_AHASH:
2815 crypto_unregister_ahash(&t_alg->algt.alg.hash);
2816 break;
2817 }
Kim Phillips9c4a7962008-06-23 19:50:15 +08002818 list_del(&t_alg->entry);
2819 kfree(t_alg);
2820 }
2821
2822 if (hw_supports(dev, DESC_HDR_SEL0_RNG))
2823 talitos_unregister_rng(dev);
2824
Aaron Sierra35a3bb32015-08-05 16:52:08 -05002825 for (i = 0; priv->chan && i < priv->num_channels; i++)
Kim Phillips0b798242010-09-23 15:56:08 +08002826 kfree(priv->chan[i].fifo);
Kim Phillips9c4a7962008-06-23 19:50:15 +08002827
Kim Phillips4b9926282009-08-13 11:50:38 +10002828 kfree(priv->chan);
Kim Phillips9c4a7962008-06-23 19:50:15 +08002829
Kim Phillipsc3e337f2011-11-21 16:13:27 +08002830 for (i = 0; i < 2; i++)
Kim Phillips2cdba3c2011-12-12 14:59:11 -06002831 if (priv->irq[i]) {
Kim Phillipsc3e337f2011-11-21 16:13:27 +08002832 free_irq(priv->irq[i], dev);
2833 irq_dispose_mapping(priv->irq[i]);
2834 }
Kim Phillips9c4a7962008-06-23 19:50:15 +08002835
Kim Phillipsc3e337f2011-11-21 16:13:27 +08002836 tasklet_kill(&priv->done_task[0]);
Kim Phillips2cdba3c2011-12-12 14:59:11 -06002837 if (priv->irq[1])
Kim Phillipsc3e337f2011-11-21 16:13:27 +08002838 tasklet_kill(&priv->done_task[1]);
Kim Phillips9c4a7962008-06-23 19:50:15 +08002839
2840 iounmap(priv->reg);
2841
Kim Phillips9c4a7962008-06-23 19:50:15 +08002842 kfree(priv);
2843
2844 return 0;
2845}
2846
2847static struct talitos_crypto_alg *talitos_alg_alloc(struct device *dev,
2848 struct talitos_alg_template
2849 *template)
2850{
Kim Phillips60f208d2010-05-19 19:21:53 +10002851 struct talitos_private *priv = dev_get_drvdata(dev);
Kim Phillips9c4a7962008-06-23 19:50:15 +08002852 struct talitos_crypto_alg *t_alg;
2853 struct crypto_alg *alg;
2854
2855 t_alg = kzalloc(sizeof(struct talitos_crypto_alg), GFP_KERNEL);
2856 if (!t_alg)
2857 return ERR_PTR(-ENOMEM);
2858
Lee Nipperacbf7c622010-05-19 19:19:33 +10002859 t_alg->algt = *template;
2860
2861 switch (t_alg->algt.type) {
2862 case CRYPTO_ALG_TYPE_ABLKCIPHER:
Lee Nipper497f2e62010-05-19 19:20:36 +10002863 alg = &t_alg->algt.alg.crypto;
2864 alg->cra_init = talitos_cra_init;
Kim Phillipsd4cd3282012-08-08 20:32:00 -05002865 alg->cra_type = &crypto_ablkcipher_type;
Kim Phillipsb286e002012-08-08 20:33:34 -05002866 alg->cra_ablkcipher.setkey = ablkcipher_setkey;
2867 alg->cra_ablkcipher.encrypt = ablkcipher_encrypt;
2868 alg->cra_ablkcipher.decrypt = ablkcipher_decrypt;
2869 alg->cra_ablkcipher.geniv = "eseqiv";
Lee Nipper497f2e62010-05-19 19:20:36 +10002870 break;
Lee Nipperacbf7c622010-05-19 19:19:33 +10002871 case CRYPTO_ALG_TYPE_AEAD:
Herbert Xuaeb4c132015-07-30 17:53:22 +08002872 alg = &t_alg->algt.alg.aead.base;
Herbert Xuaeb4c132015-07-30 17:53:22 +08002873 t_alg->algt.alg.aead.init = talitos_cra_init_aead;
2874 t_alg->algt.alg.aead.setkey = aead_setkey;
2875 t_alg->algt.alg.aead.encrypt = aead_encrypt;
2876 t_alg->algt.alg.aead.decrypt = aead_decrypt;
Lee Nipperacbf7c622010-05-19 19:19:33 +10002877 break;
2878 case CRYPTO_ALG_TYPE_AHASH:
2879 alg = &t_alg->algt.alg.hash.halg.base;
Lee Nipper497f2e62010-05-19 19:20:36 +10002880 alg->cra_init = talitos_cra_init_ahash;
Kim Phillipsd4cd3282012-08-08 20:32:00 -05002881 alg->cra_type = &crypto_ahash_type;
Kim Phillipsb286e002012-08-08 20:33:34 -05002882 t_alg->algt.alg.hash.init = ahash_init;
2883 t_alg->algt.alg.hash.update = ahash_update;
2884 t_alg->algt.alg.hash.final = ahash_final;
2885 t_alg->algt.alg.hash.finup = ahash_finup;
2886 t_alg->algt.alg.hash.digest = ahash_digest;
2887 t_alg->algt.alg.hash.setkey = ahash_setkey;
Horia Geant?3639ca82016-04-21 19:24:55 +03002888 t_alg->algt.alg.hash.import = ahash_import;
2889 t_alg->algt.alg.hash.export = ahash_export;
Kim Phillipsb286e002012-08-08 20:33:34 -05002890
Lee Nipper79b3a412011-11-21 16:13:25 +08002891 if (!(priv->features & TALITOS_FTR_HMAC_OK) &&
Kim Phillips0b2730d2011-12-12 14:59:10 -06002892 !strncmp(alg->cra_name, "hmac", 4)) {
2893 kfree(t_alg);
Lee Nipper79b3a412011-11-21 16:13:25 +08002894 return ERR_PTR(-ENOTSUPP);
Kim Phillips0b2730d2011-12-12 14:59:10 -06002895 }
Kim Phillips60f208d2010-05-19 19:21:53 +10002896 if (!(priv->features & TALITOS_FTR_SHA224_HWINIT) &&
Lee Nipper79b3a412011-11-21 16:13:25 +08002897 (!strcmp(alg->cra_name, "sha224") ||
2898 !strcmp(alg->cra_name, "hmac(sha224)"))) {
Kim Phillips60f208d2010-05-19 19:21:53 +10002899 t_alg->algt.alg.hash.init = ahash_init_sha224_swinit;
2900 t_alg->algt.desc_hdr_template =
2901 DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2902 DESC_HDR_SEL0_MDEUA |
2903 DESC_HDR_MODE0_MDEU_SHA256;
2904 }
Lee Nipper497f2e62010-05-19 19:20:36 +10002905 break;
Kim Phillips1d119112010-09-23 15:55:27 +08002906 default:
2907 dev_err(dev, "unknown algorithm type %d\n", t_alg->algt.type);
Horia Geant?5fa7dad2015-05-11 20:03:24 +03002908 kfree(t_alg);
Kim Phillips1d119112010-09-23 15:55:27 +08002909 return ERR_PTR(-EINVAL);
Lee Nipperacbf7c622010-05-19 19:19:33 +10002910 }
Kim Phillips9c4a7962008-06-23 19:50:15 +08002911
Kim Phillips9c4a7962008-06-23 19:50:15 +08002912 alg->cra_module = THIS_MODULE;
Kim Phillips9c4a7962008-06-23 19:50:15 +08002913 alg->cra_priority = TALITOS_CRA_PRIORITY;
Kim Phillips9c4a7962008-06-23 19:50:15 +08002914 alg->cra_alignmask = 0;
Kim Phillips9c4a7962008-06-23 19:50:15 +08002915 alg->cra_ctxsize = sizeof(struct talitos_ctx);
Nikos Mavrogiannopoulosd912bb72011-11-01 13:39:56 +01002916 alg->cra_flags |= CRYPTO_ALG_KERN_DRIVER_ONLY;
Kim Phillips9c4a7962008-06-23 19:50:15 +08002917
Kim Phillips9c4a7962008-06-23 19:50:15 +08002918 t_alg->dev = dev;
2919
2920 return t_alg;
2921}
2922
Kim Phillipsc3e337f2011-11-21 16:13:27 +08002923static int talitos_probe_irq(struct platform_device *ofdev)
2924{
2925 struct device *dev = &ofdev->dev;
2926 struct device_node *np = ofdev->dev.of_node;
2927 struct talitos_private *priv = dev_get_drvdata(dev);
2928 int err;
LEROY Christophedd3c0982015-04-17 16:32:13 +02002929 bool is_sec1 = has_ftr_sec1(priv);
Kim Phillipsc3e337f2011-11-21 16:13:27 +08002930
2931 priv->irq[0] = irq_of_parse_and_map(np, 0);
Kim Phillips2cdba3c2011-12-12 14:59:11 -06002932 if (!priv->irq[0]) {
Kim Phillipsc3e337f2011-11-21 16:13:27 +08002933 dev_err(dev, "failed to map irq\n");
2934 return -EINVAL;
2935 }
LEROY Christophedd3c0982015-04-17 16:32:13 +02002936 if (is_sec1) {
2937 err = request_irq(priv->irq[0], talitos1_interrupt_4ch, 0,
2938 dev_driver_string(dev), dev);
2939 goto primary_out;
2940 }
Kim Phillipsc3e337f2011-11-21 16:13:27 +08002941
2942 priv->irq[1] = irq_of_parse_and_map(np, 1);
2943
2944 /* get the primary irq line */
Kim Phillips2cdba3c2011-12-12 14:59:11 -06002945 if (!priv->irq[1]) {
LEROY Christophedd3c0982015-04-17 16:32:13 +02002946 err = request_irq(priv->irq[0], talitos2_interrupt_4ch, 0,
Kim Phillipsc3e337f2011-11-21 16:13:27 +08002947 dev_driver_string(dev), dev);
2948 goto primary_out;
2949 }
2950
LEROY Christophedd3c0982015-04-17 16:32:13 +02002951 err = request_irq(priv->irq[0], talitos2_interrupt_ch0_2, 0,
Kim Phillipsc3e337f2011-11-21 16:13:27 +08002952 dev_driver_string(dev), dev);
2953 if (err)
2954 goto primary_out;
2955
2956 /* get the secondary irq line */
LEROY Christophedd3c0982015-04-17 16:32:13 +02002957 err = request_irq(priv->irq[1], talitos2_interrupt_ch1_3, 0,
Kim Phillipsc3e337f2011-11-21 16:13:27 +08002958 dev_driver_string(dev), dev);
2959 if (err) {
2960 dev_err(dev, "failed to request secondary irq\n");
2961 irq_dispose_mapping(priv->irq[1]);
Kim Phillips2cdba3c2011-12-12 14:59:11 -06002962 priv->irq[1] = 0;
Kim Phillipsc3e337f2011-11-21 16:13:27 +08002963 }
2964
2965 return err;
2966
2967primary_out:
2968 if (err) {
2969 dev_err(dev, "failed to request primary irq\n");
2970 irq_dispose_mapping(priv->irq[0]);
Kim Phillips2cdba3c2011-12-12 14:59:11 -06002971 priv->irq[0] = 0;
Kim Phillipsc3e337f2011-11-21 16:13:27 +08002972 }
2973
2974 return err;
2975}
2976
Grant Likely1c48a5c2011-02-17 02:43:24 -07002977static int talitos_probe(struct platform_device *ofdev)
Kim Phillips9c4a7962008-06-23 19:50:15 +08002978{
2979 struct device *dev = &ofdev->dev;
Grant Likely61c7a082010-04-13 16:12:29 -07002980 struct device_node *np = ofdev->dev.of_node;
Kim Phillips9c4a7962008-06-23 19:50:15 +08002981 struct talitos_private *priv;
2982 const unsigned int *prop;
2983 int i, err;
LEROY Christophe5fa7fa12015-04-17 16:32:11 +02002984 int stride;
Kim Phillips9c4a7962008-06-23 19:50:15 +08002985
2986 priv = kzalloc(sizeof(struct talitos_private), GFP_KERNEL);
2987 if (!priv)
2988 return -ENOMEM;
2989
Kevin Haof3de9cb2014-01-28 20:17:23 +08002990 INIT_LIST_HEAD(&priv->alg_list);
2991
Kim Phillips9c4a7962008-06-23 19:50:15 +08002992 dev_set_drvdata(dev, priv);
2993
2994 priv->ofdev = ofdev;
2995
Horia Geanta511d63c2012-03-30 17:49:53 +03002996 spin_lock_init(&priv->reg_lock);
2997
Kim Phillips9c4a7962008-06-23 19:50:15 +08002998 priv->reg = of_iomap(np, 0);
2999 if (!priv->reg) {
3000 dev_err(dev, "failed to of_iomap\n");
3001 err = -ENOMEM;
3002 goto err_out;
3003 }
3004
3005 /* get SEC version capabilities from device tree */
3006 prop = of_get_property(np, "fsl,num-channels", NULL);
3007 if (prop)
3008 priv->num_channels = *prop;
3009
3010 prop = of_get_property(np, "fsl,channel-fifo-len", NULL);
3011 if (prop)
3012 priv->chfifo_len = *prop;
3013
3014 prop = of_get_property(np, "fsl,exec-units-mask", NULL);
3015 if (prop)
3016 priv->exec_units = *prop;
3017
3018 prop = of_get_property(np, "fsl,descriptor-types-mask", NULL);
3019 if (prop)
3020 priv->desc_types = *prop;
3021
3022 if (!is_power_of_2(priv->num_channels) || !priv->chfifo_len ||
3023 !priv->exec_units || !priv->desc_types) {
3024 dev_err(dev, "invalid property data in device tree node\n");
3025 err = -EINVAL;
3026 goto err_out;
3027 }
3028
Lee Nipperf3c85bc2008-07-30 16:26:57 +08003029 if (of_device_is_compatible(np, "fsl,sec3.0"))
3030 priv->features |= TALITOS_FTR_SRC_LINK_TBL_LEN_INCLUDES_EXTENT;
3031
Kim Phillipsfe5720e2008-10-12 20:33:14 +08003032 if (of_device_is_compatible(np, "fsl,sec2.1"))
Kim Phillips60f208d2010-05-19 19:21:53 +10003033 priv->features |= TALITOS_FTR_HW_AUTH_CHECK |
Lee Nipper79b3a412011-11-21 16:13:25 +08003034 TALITOS_FTR_SHA224_HWINIT |
3035 TALITOS_FTR_HMAC_OK;
Kim Phillipsfe5720e2008-10-12 20:33:14 +08003036
LEROY Christophe21590882015-04-17 16:32:05 +02003037 if (of_device_is_compatible(np, "fsl,sec1.0"))
3038 priv->features |= TALITOS_FTR_SEC1;
3039
LEROY Christophe5fa7fa12015-04-17 16:32:11 +02003040 if (of_device_is_compatible(np, "fsl,sec1.2")) {
3041 priv->reg_deu = priv->reg + TALITOS12_DEU;
3042 priv->reg_aesu = priv->reg + TALITOS12_AESU;
3043 priv->reg_mdeu = priv->reg + TALITOS12_MDEU;
3044 stride = TALITOS1_CH_STRIDE;
3045 } else if (of_device_is_compatible(np, "fsl,sec1.0")) {
3046 priv->reg_deu = priv->reg + TALITOS10_DEU;
3047 priv->reg_aesu = priv->reg + TALITOS10_AESU;
3048 priv->reg_mdeu = priv->reg + TALITOS10_MDEU;
3049 priv->reg_afeu = priv->reg + TALITOS10_AFEU;
3050 priv->reg_rngu = priv->reg + TALITOS10_RNGU;
3051 priv->reg_pkeu = priv->reg + TALITOS10_PKEU;
3052 stride = TALITOS1_CH_STRIDE;
3053 } else {
3054 priv->reg_deu = priv->reg + TALITOS2_DEU;
3055 priv->reg_aesu = priv->reg + TALITOS2_AESU;
3056 priv->reg_mdeu = priv->reg + TALITOS2_MDEU;
3057 priv->reg_afeu = priv->reg + TALITOS2_AFEU;
3058 priv->reg_rngu = priv->reg + TALITOS2_RNGU;
3059 priv->reg_pkeu = priv->reg + TALITOS2_PKEU;
3060 priv->reg_keu = priv->reg + TALITOS2_KEU;
3061 priv->reg_crcu = priv->reg + TALITOS2_CRCU;
3062 stride = TALITOS2_CH_STRIDE;
3063 }
3064
LEROY Christophedd3c0982015-04-17 16:32:13 +02003065 err = talitos_probe_irq(ofdev);
3066 if (err)
3067 goto err_out;
3068
3069 if (of_device_is_compatible(np, "fsl,sec1.0")) {
3070 tasklet_init(&priv->done_task[0], talitos1_done_4ch,
3071 (unsigned long)dev);
3072 } else {
3073 if (!priv->irq[1]) {
3074 tasklet_init(&priv->done_task[0], talitos2_done_4ch,
3075 (unsigned long)dev);
3076 } else {
3077 tasklet_init(&priv->done_task[0], talitos2_done_ch0_2,
3078 (unsigned long)dev);
3079 tasklet_init(&priv->done_task[1], talitos2_done_ch1_3,
3080 (unsigned long)dev);
3081 }
3082 }
3083
Kim Phillips4b9926282009-08-13 11:50:38 +10003084 priv->chan = kzalloc(sizeof(struct talitos_channel) *
3085 priv->num_channels, GFP_KERNEL);
3086 if (!priv->chan) {
3087 dev_err(dev, "failed to allocate channel management space\n");
Kim Phillips9c4a7962008-06-23 19:50:15 +08003088 err = -ENOMEM;
3089 goto err_out;
3090 }
3091
Martin Hicksf641ddd2015-03-03 08:21:33 -05003092 priv->fifo_len = roundup_pow_of_two(priv->chfifo_len);
3093
Kim Phillipsc3e337f2011-11-21 16:13:27 +08003094 for (i = 0; i < priv->num_channels; i++) {
LEROY Christophe5fa7fa12015-04-17 16:32:11 +02003095 priv->chan[i].reg = priv->reg + stride * (i + 1);
Kim Phillips2cdba3c2011-12-12 14:59:11 -06003096 if (!priv->irq[1] || !(i & 1))
Kim Phillipsc3e337f2011-11-21 16:13:27 +08003097 priv->chan[i].reg += TALITOS_CH_BASE_OFFSET;
Kim Phillipsad42d5f2011-11-21 16:13:27 +08003098
Kim Phillips4b9926282009-08-13 11:50:38 +10003099 spin_lock_init(&priv->chan[i].head_lock);
3100 spin_lock_init(&priv->chan[i].tail_lock);
Kim Phillips9c4a7962008-06-23 19:50:15 +08003101
Kim Phillips4b9926282009-08-13 11:50:38 +10003102 priv->chan[i].fifo = kzalloc(sizeof(struct talitos_request) *
3103 priv->fifo_len, GFP_KERNEL);
3104 if (!priv->chan[i].fifo) {
Kim Phillips9c4a7962008-06-23 19:50:15 +08003105 dev_err(dev, "failed to allocate request fifo %d\n", i);
3106 err = -ENOMEM;
3107 goto err_out;
3108 }
Kim Phillips9c4a7962008-06-23 19:50:15 +08003109
Kim Phillips4b9926282009-08-13 11:50:38 +10003110 atomic_set(&priv->chan[i].submit_count,
3111 -(priv->chfifo_len - 1));
Martin Hicksf641ddd2015-03-03 08:21:33 -05003112 }
Kim Phillips9c4a7962008-06-23 19:50:15 +08003113
Kim Phillips81eb0242009-08-13 11:51:51 +10003114 dma_set_mask(dev, DMA_BIT_MASK(36));
3115
Kim Phillips9c4a7962008-06-23 19:50:15 +08003116 /* reset and initialize the h/w */
3117 err = init_device(dev);
3118 if (err) {
3119 dev_err(dev, "failed to initialize device\n");
3120 goto err_out;
3121 }
3122
3123 /* register the RNG, if available */
3124 if (hw_supports(dev, DESC_HDR_SEL0_RNG)) {
3125 err = talitos_register_rng(dev);
3126 if (err) {
3127 dev_err(dev, "failed to register hwrng: %d\n", err);
3128 goto err_out;
3129 } else
3130 dev_info(dev, "hwrng\n");
3131 }
3132
3133 /* register crypto algorithms the device supports */
Kim Phillips9c4a7962008-06-23 19:50:15 +08003134 for (i = 0; i < ARRAY_SIZE(driver_algs); i++) {
3135 if (hw_supports(dev, driver_algs[i].desc_hdr_template)) {
3136 struct talitos_crypto_alg *t_alg;
Herbert Xuaeb4c132015-07-30 17:53:22 +08003137 struct crypto_alg *alg = NULL;
Kim Phillips9c4a7962008-06-23 19:50:15 +08003138
3139 t_alg = talitos_alg_alloc(dev, &driver_algs[i]);
3140 if (IS_ERR(t_alg)) {
3141 err = PTR_ERR(t_alg);
Kim Phillips0b2730d2011-12-12 14:59:10 -06003142 if (err == -ENOTSUPP)
Lee Nipper79b3a412011-11-21 16:13:25 +08003143 continue;
Kim Phillips9c4a7962008-06-23 19:50:15 +08003144 goto err_out;
3145 }
3146
Lee Nipperacbf7c622010-05-19 19:19:33 +10003147 switch (t_alg->algt.type) {
3148 case CRYPTO_ALG_TYPE_ABLKCIPHER:
Lee Nipperacbf7c622010-05-19 19:19:33 +10003149 err = crypto_register_alg(
3150 &t_alg->algt.alg.crypto);
Herbert Xuaeb4c132015-07-30 17:53:22 +08003151 alg = &t_alg->algt.alg.crypto;
Lee Nipperacbf7c622010-05-19 19:19:33 +10003152 break;
Herbert Xuaeb4c132015-07-30 17:53:22 +08003153
3154 case CRYPTO_ALG_TYPE_AEAD:
3155 err = crypto_register_aead(
3156 &t_alg->algt.alg.aead);
3157 alg = &t_alg->algt.alg.aead.base;
3158 break;
3159
Lee Nipperacbf7c622010-05-19 19:19:33 +10003160 case CRYPTO_ALG_TYPE_AHASH:
3161 err = crypto_register_ahash(
3162 &t_alg->algt.alg.hash);
Herbert Xuaeb4c132015-07-30 17:53:22 +08003163 alg = &t_alg->algt.alg.hash.halg.base;
Lee Nipperacbf7c622010-05-19 19:19:33 +10003164 break;
3165 }
Kim Phillips9c4a7962008-06-23 19:50:15 +08003166 if (err) {
3167 dev_err(dev, "%s alg registration failed\n",
Herbert Xuaeb4c132015-07-30 17:53:22 +08003168 alg->cra_driver_name);
Kim Phillips9c4a7962008-06-23 19:50:15 +08003169 kfree(t_alg);
Horia Geanta991155b2013-03-20 16:31:38 +02003170 } else
Kim Phillips9c4a7962008-06-23 19:50:15 +08003171 list_add_tail(&t_alg->entry, &priv->alg_list);
Kim Phillips9c4a7962008-06-23 19:50:15 +08003172 }
3173 }
Kim Phillips5b859b6e2011-11-21 16:13:26 +08003174 if (!list_empty(&priv->alg_list))
3175 dev_info(dev, "%s algorithms registered in /proc/crypto\n",
3176 (char *)of_get_property(np, "compatible", NULL));
Kim Phillips9c4a7962008-06-23 19:50:15 +08003177
3178 return 0;
3179
3180err_out:
3181 talitos_remove(ofdev);
Kim Phillips9c4a7962008-06-23 19:50:15 +08003182
3183 return err;
3184}
3185
Márton Németh6c3f9752010-01-17 21:54:01 +11003186static const struct of_device_id talitos_match[] = {
LEROY Christophe0635b7d2015-04-17 16:32:20 +02003187#ifdef CONFIG_CRYPTO_DEV_TALITOS1
3188 {
3189 .compatible = "fsl,sec1.0",
3190 },
3191#endif
3192#ifdef CONFIG_CRYPTO_DEV_TALITOS2
Kim Phillips9c4a7962008-06-23 19:50:15 +08003193 {
3194 .compatible = "fsl,sec2.0",
3195 },
LEROY Christophe0635b7d2015-04-17 16:32:20 +02003196#endif
Kim Phillips9c4a7962008-06-23 19:50:15 +08003197 {},
3198};
3199MODULE_DEVICE_TABLE(of, talitos_match);
3200
Grant Likely1c48a5c2011-02-17 02:43:24 -07003201static struct platform_driver talitos_driver = {
Grant Likely40182942010-04-13 16:13:02 -07003202 .driver = {
3203 .name = "talitos",
Grant Likely40182942010-04-13 16:13:02 -07003204 .of_match_table = talitos_match,
3205 },
Kim Phillips9c4a7962008-06-23 19:50:15 +08003206 .probe = talitos_probe,
Al Viro596f1032008-11-22 17:34:24 +00003207 .remove = talitos_remove,
Kim Phillips9c4a7962008-06-23 19:50:15 +08003208};
3209
Axel Lin741e8c22011-11-26 21:26:19 +08003210module_platform_driver(talitos_driver);
Kim Phillips9c4a7962008-06-23 19:50:15 +08003211
3212MODULE_LICENSE("GPL");
3213MODULE_AUTHOR("Kim Phillips <kim.phillips@freescale.com>");
3214MODULE_DESCRIPTION("Freescale integrated security engine (SEC) driver");