blob: 7cebf0a6ffbca83201f88a20a00c40924ed3f52f [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,
LEROY Christopheda9de142017-10-06 15:04:57 +020059 unsigned int len, 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 Christopheda9de142017-10-06 15:04:57 +020062 if (is_sec1) {
63 ptr->len1 = cpu_to_be16(len);
64 } else {
65 ptr->len = cpu_to_be16(len);
LEROY Christophe922f9dc2015-04-17 16:32:07 +020066 ptr->eptr = upper_32_bits(dma_addr);
LEROY Christopheda9de142017-10-06 15:04:57 +020067 }
Kim Phillips81eb0242009-08-13 11:51:51 +100068}
69
Horia Geant?340ff602016-04-19 20:33:48 +030070static void copy_talitos_ptr(struct talitos_ptr *dst_ptr,
71 struct talitos_ptr *src_ptr, bool is_sec1)
72{
73 dst_ptr->ptr = src_ptr->ptr;
LEROY Christophe922f9dc2015-04-17 16:32:07 +020074 if (is_sec1) {
LEROY Christopheda9de142017-10-06 15:04:57 +020075 dst_ptr->len1 = src_ptr->len1;
LEROY Christophe922f9dc2015-04-17 16:32:07 +020076 } else {
LEROY Christopheda9de142017-10-06 15:04:57 +020077 dst_ptr->len = src_ptr->len;
78 dst_ptr->eptr = src_ptr->eptr;
LEROY Christophe922f9dc2015-04-17 16:32:07 +020079 }
LEROY Christophe538caf82015-04-17 16:31:59 +020080}
81
LEROY Christophe922f9dc2015-04-17 16:32:07 +020082static unsigned short from_talitos_ptr_len(struct talitos_ptr *ptr,
83 bool is_sec1)
LEROY Christophe538caf82015-04-17 16:31:59 +020084{
LEROY Christophe922f9dc2015-04-17 16:32:07 +020085 if (is_sec1)
86 return be16_to_cpu(ptr->len1);
87 else
88 return be16_to_cpu(ptr->len);
LEROY Christophe538caf82015-04-17 16:31:59 +020089}
90
LEROY Christopheb096b542016-06-06 13:20:34 +020091static void to_talitos_ptr_ext_set(struct talitos_ptr *ptr, u8 val,
92 bool is_sec1)
LEROY Christophe185eb792015-04-17 16:31:55 +020093{
LEROY Christophe922f9dc2015-04-17 16:32:07 +020094 if (!is_sec1)
LEROY Christopheb096b542016-06-06 13:20:34 +020095 ptr->j_extent = val;
96}
97
98static void to_talitos_ptr_ext_or(struct talitos_ptr *ptr, u8 val, bool is_sec1)
99{
100 if (!is_sec1)
101 ptr->j_extent |= val;
LEROY Christophe185eb792015-04-17 16:31:55 +0200102}
103
Kim Phillips9c4a7962008-06-23 19:50:15 +0800104/*
105 * map virtual single (contiguous) pointer to h/w descriptor pointer
106 */
LEROY Christophe6a4967c2018-02-26 17:40:06 +0100107static void __map_single_talitos_ptr(struct device *dev,
108 struct talitos_ptr *ptr,
109 unsigned int len, void *data,
110 enum dma_data_direction dir,
111 unsigned long attrs)
112{
113 dma_addr_t dma_addr = dma_map_single_attrs(dev, data, len, dir, attrs);
114 struct talitos_private *priv = dev_get_drvdata(dev);
115 bool is_sec1 = has_ftr_sec1(priv);
116
117 to_talitos_ptr(ptr, dma_addr, len, is_sec1);
118}
119
Kim Phillips9c4a7962008-06-23 19:50:15 +0800120static void map_single_talitos_ptr(struct device *dev,
LEROY Christopheedc6bd62015-04-17 16:31:53 +0200121 struct talitos_ptr *ptr,
Horia Geant?42e8b0d2015-05-11 20:04:56 +0300122 unsigned int len, void *data,
Kim Phillips9c4a7962008-06-23 19:50:15 +0800123 enum dma_data_direction dir)
124{
LEROY Christophe6a4967c2018-02-26 17:40:06 +0100125 __map_single_talitos_ptr(dev, ptr, len, data, dir, 0);
126}
Kim Phillips81eb0242009-08-13 11:51:51 +1000127
LEROY Christophe6a4967c2018-02-26 17:40:06 +0100128static void map_single_talitos_ptr_nosync(struct device *dev,
129 struct talitos_ptr *ptr,
130 unsigned int len, void *data,
131 enum dma_data_direction dir)
132{
133 __map_single_talitos_ptr(dev, ptr, len, data, dir,
134 DMA_ATTR_SKIP_CPU_SYNC);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800135}
136
137/*
138 * unmap bus single (contiguous) h/w descriptor pointer
139 */
140static void unmap_single_talitos_ptr(struct device *dev,
LEROY Christopheedc6bd62015-04-17 16:31:53 +0200141 struct talitos_ptr *ptr,
Kim Phillips9c4a7962008-06-23 19:50:15 +0800142 enum dma_data_direction dir)
143{
LEROY Christophe922f9dc2015-04-17 16:32:07 +0200144 struct talitos_private *priv = dev_get_drvdata(dev);
145 bool is_sec1 = has_ftr_sec1(priv);
146
LEROY Christopheedc6bd62015-04-17 16:31:53 +0200147 dma_unmap_single(dev, be32_to_cpu(ptr->ptr),
LEROY Christophe922f9dc2015-04-17 16:32:07 +0200148 from_talitos_ptr_len(ptr, is_sec1), dir);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800149}
150
151static int reset_channel(struct device *dev, int ch)
152{
153 struct talitos_private *priv = dev_get_drvdata(dev);
154 unsigned int timeout = TALITOS_TIMEOUT;
LEROY Christophedd3c0982015-04-17 16:32:13 +0200155 bool is_sec1 = has_ftr_sec1(priv);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800156
LEROY Christophedd3c0982015-04-17 16:32:13 +0200157 if (is_sec1) {
158 setbits32(priv->chan[ch].reg + TALITOS_CCCR_LO,
159 TALITOS1_CCCR_LO_RESET);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800160
LEROY Christophedd3c0982015-04-17 16:32:13 +0200161 while ((in_be32(priv->chan[ch].reg + TALITOS_CCCR_LO) &
162 TALITOS1_CCCR_LO_RESET) && --timeout)
163 cpu_relax();
164 } else {
165 setbits32(priv->chan[ch].reg + TALITOS_CCCR,
166 TALITOS2_CCCR_RESET);
167
168 while ((in_be32(priv->chan[ch].reg + TALITOS_CCCR) &
169 TALITOS2_CCCR_RESET) && --timeout)
170 cpu_relax();
171 }
Kim Phillips9c4a7962008-06-23 19:50:15 +0800172
173 if (timeout == 0) {
174 dev_err(dev, "failed to reset channel %d\n", ch);
175 return -EIO;
176 }
177
Kim Phillips81eb0242009-08-13 11:51:51 +1000178 /* set 36-bit addressing, done writeback enable and done IRQ enable */
Kim Phillipsad42d5f2011-11-21 16:13:27 +0800179 setbits32(priv->chan[ch].reg + TALITOS_CCCR_LO, TALITOS_CCCR_LO_EAE |
Kim Phillips81eb0242009-08-13 11:51:51 +1000180 TALITOS_CCCR_LO_CDWE | TALITOS_CCCR_LO_CDIE);
LEROY Christophe37b5e882017-10-06 15:05:06 +0200181 /* enable chaining descriptors */
182 if (is_sec1)
183 setbits32(priv->chan[ch].reg + TALITOS_CCCR_LO,
184 TALITOS_CCCR_LO_NE);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800185
Kim Phillipsfe5720e2008-10-12 20:33:14 +0800186 /* and ICCR writeback, if available */
187 if (priv->features & TALITOS_FTR_HW_AUTH_CHECK)
Kim Phillipsad42d5f2011-11-21 16:13:27 +0800188 setbits32(priv->chan[ch].reg + TALITOS_CCCR_LO,
Kim Phillipsfe5720e2008-10-12 20:33:14 +0800189 TALITOS_CCCR_LO_IWSE);
190
Kim Phillips9c4a7962008-06-23 19:50:15 +0800191 return 0;
192}
193
194static int reset_device(struct device *dev)
195{
196 struct talitos_private *priv = dev_get_drvdata(dev);
197 unsigned int timeout = TALITOS_TIMEOUT;
LEROY Christophedd3c0982015-04-17 16:32:13 +0200198 bool is_sec1 = has_ftr_sec1(priv);
199 u32 mcr = is_sec1 ? TALITOS1_MCR_SWR : TALITOS2_MCR_SWR;
Kim Phillips9c4a7962008-06-23 19:50:15 +0800200
Kim Phillipsc3e337f2011-11-21 16:13:27 +0800201 setbits32(priv->reg + TALITOS_MCR, mcr);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800202
LEROY Christophedd3c0982015-04-17 16:32:13 +0200203 while ((in_be32(priv->reg + TALITOS_MCR) & mcr)
Kim Phillips9c4a7962008-06-23 19:50:15 +0800204 && --timeout)
205 cpu_relax();
206
Kim Phillips2cdba3c2011-12-12 14:59:11 -0600207 if (priv->irq[1]) {
Kim Phillipsc3e337f2011-11-21 16:13:27 +0800208 mcr = TALITOS_MCR_RCA1 | TALITOS_MCR_RCA3;
209 setbits32(priv->reg + TALITOS_MCR, mcr);
210 }
211
Kim Phillips9c4a7962008-06-23 19:50:15 +0800212 if (timeout == 0) {
213 dev_err(dev, "failed to reset device\n");
214 return -EIO;
215 }
216
217 return 0;
218}
219
220/*
221 * Reset and initialize the device
222 */
223static int init_device(struct device *dev)
224{
225 struct talitos_private *priv = dev_get_drvdata(dev);
226 int ch, err;
LEROY Christophedd3c0982015-04-17 16:32:13 +0200227 bool is_sec1 = has_ftr_sec1(priv);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800228
229 /*
230 * Master reset
231 * errata documentation: warning: certain SEC interrupts
232 * are not fully cleared by writing the MCR:SWR bit,
233 * set bit twice to completely reset
234 */
235 err = reset_device(dev);
236 if (err)
237 return err;
238
239 err = reset_device(dev);
240 if (err)
241 return err;
242
243 /* reset channels */
244 for (ch = 0; ch < priv->num_channels; ch++) {
245 err = reset_channel(dev, ch);
246 if (err)
247 return err;
248 }
249
250 /* enable channel done and error interrupts */
LEROY Christophedd3c0982015-04-17 16:32:13 +0200251 if (is_sec1) {
252 clrbits32(priv->reg + TALITOS_IMR, TALITOS1_IMR_INIT);
253 clrbits32(priv->reg + TALITOS_IMR_LO, TALITOS1_IMR_LO_INIT);
254 /* disable parity error check in DEU (erroneous? test vect.) */
255 setbits32(priv->reg_deu + TALITOS_EUICR, TALITOS1_DEUICR_KPE);
256 } else {
257 setbits32(priv->reg + TALITOS_IMR, TALITOS2_IMR_INIT);
258 setbits32(priv->reg + TALITOS_IMR_LO, TALITOS2_IMR_LO_INIT);
259 }
Kim Phillips9c4a7962008-06-23 19:50:15 +0800260
Kim Phillipsfe5720e2008-10-12 20:33:14 +0800261 /* disable integrity check error interrupts (use writeback instead) */
262 if (priv->features & TALITOS_FTR_HW_AUTH_CHECK)
LEROY Christophe5fa7fa12015-04-17 16:32:11 +0200263 setbits32(priv->reg_mdeu + TALITOS_EUICR_LO,
Kim Phillipsfe5720e2008-10-12 20:33:14 +0800264 TALITOS_MDEUICR_LO_ICE);
265
Kim Phillips9c4a7962008-06-23 19:50:15 +0800266 return 0;
267}
268
269/**
270 * talitos_submit - submits a descriptor to the device for processing
271 * @dev: the SEC device to be used
Kim Phillips5228f0f2011-07-15 11:21:38 +0800272 * @ch: the SEC device channel to be used
Kim Phillips9c4a7962008-06-23 19:50:15 +0800273 * @desc: the descriptor to be processed by the device
274 * @callback: whom to call when processing is complete
275 * @context: a handle for use by caller (optional)
276 *
277 * desc must contain valid dma-mapped (bus physical) address pointers.
278 * callback must check err and feedback in descriptor header
279 * for device processing status.
280 */
Horia Geanta865d5062012-07-03 19:16:52 +0300281int talitos_submit(struct device *dev, int ch, struct talitos_desc *desc,
282 void (*callback)(struct device *dev,
283 struct talitos_desc *desc,
284 void *context, int error),
285 void *context)
Kim Phillips9c4a7962008-06-23 19:50:15 +0800286{
287 struct talitos_private *priv = dev_get_drvdata(dev);
288 struct talitos_request *request;
Kim Phillips5228f0f2011-07-15 11:21:38 +0800289 unsigned long flags;
Kim Phillips9c4a7962008-06-23 19:50:15 +0800290 int head;
LEROY Christophe7d607c6a2015-04-17 16:32:09 +0200291 bool is_sec1 = has_ftr_sec1(priv);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800292
Kim Phillips4b9926282009-08-13 11:50:38 +1000293 spin_lock_irqsave(&priv->chan[ch].head_lock, flags);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800294
Kim Phillips4b9926282009-08-13 11:50:38 +1000295 if (!atomic_inc_not_zero(&priv->chan[ch].submit_count)) {
Kim Phillipsec6644d2008-07-17 20:16:40 +0800296 /* h/w fifo is full */
Kim Phillips4b9926282009-08-13 11:50:38 +1000297 spin_unlock_irqrestore(&priv->chan[ch].head_lock, flags);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800298 return -EAGAIN;
299 }
300
Kim Phillips4b9926282009-08-13 11:50:38 +1000301 head = priv->chan[ch].head;
302 request = &priv->chan[ch].fifo[head];
Kim Phillipsec6644d2008-07-17 20:16:40 +0800303
Kim Phillips9c4a7962008-06-23 19:50:15 +0800304 /* map descriptor and save caller data */
LEROY Christophe7d607c6a2015-04-17 16:32:09 +0200305 if (is_sec1) {
306 desc->hdr1 = desc->hdr;
LEROY Christophe7d607c6a2015-04-17 16:32:09 +0200307 request->dma_desc = dma_map_single(dev, &desc->hdr1,
308 TALITOS_DESC_SIZE,
309 DMA_BIDIRECTIONAL);
310 } else {
311 request->dma_desc = dma_map_single(dev, desc,
312 TALITOS_DESC_SIZE,
313 DMA_BIDIRECTIONAL);
314 }
Kim Phillips9c4a7962008-06-23 19:50:15 +0800315 request->callback = callback;
316 request->context = context;
317
318 /* increment fifo head */
Kim Phillips4b9926282009-08-13 11:50:38 +1000319 priv->chan[ch].head = (priv->chan[ch].head + 1) & (priv->fifo_len - 1);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800320
321 smp_wmb();
322 request->desc = desc;
323
324 /* GO! */
325 wmb();
Kim Phillipsad42d5f2011-11-21 16:13:27 +0800326 out_be32(priv->chan[ch].reg + TALITOS_FF,
327 upper_32_bits(request->dma_desc));
328 out_be32(priv->chan[ch].reg + TALITOS_FF_LO,
Kim Phillipsa7524472010-09-23 15:56:38 +0800329 lower_32_bits(request->dma_desc));
Kim Phillips9c4a7962008-06-23 19:50:15 +0800330
Kim Phillips4b9926282009-08-13 11:50:38 +1000331 spin_unlock_irqrestore(&priv->chan[ch].head_lock, flags);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800332
333 return -EINPROGRESS;
334}
Horia Geanta865d5062012-07-03 19:16:52 +0300335EXPORT_SYMBOL(talitos_submit);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800336
337/*
338 * process what was done, notify callback of error if not
339 */
340static void flush_channel(struct device *dev, int ch, int error, int reset_ch)
341{
342 struct talitos_private *priv = dev_get_drvdata(dev);
343 struct talitos_request *request, saved_req;
344 unsigned long flags;
345 int tail, status;
LEROY Christophe7d607c6a2015-04-17 16:32:09 +0200346 bool is_sec1 = has_ftr_sec1(priv);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800347
Kim Phillips4b9926282009-08-13 11:50:38 +1000348 spin_lock_irqsave(&priv->chan[ch].tail_lock, flags);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800349
Kim Phillips4b9926282009-08-13 11:50:38 +1000350 tail = priv->chan[ch].tail;
351 while (priv->chan[ch].fifo[tail].desc) {
LEROY Christophe7d607c6a2015-04-17 16:32:09 +0200352 __be32 hdr;
353
Kim Phillips4b9926282009-08-13 11:50:38 +1000354 request = &priv->chan[ch].fifo[tail];
Kim Phillips9c4a7962008-06-23 19:50:15 +0800355
356 /* descriptors with their done bits set don't get the error */
357 rmb();
LEROY Christophe37b5e882017-10-06 15:05:06 +0200358 if (!is_sec1)
359 hdr = request->desc->hdr;
360 else if (request->desc->next_desc)
361 hdr = (request->desc + 1)->hdr1;
362 else
363 hdr = request->desc->hdr1;
LEROY Christophe7d607c6a2015-04-17 16:32:09 +0200364
365 if ((hdr & DESC_HDR_DONE) == DESC_HDR_DONE)
Kim Phillips9c4a7962008-06-23 19:50:15 +0800366 status = 0;
Lee Nipperca38a812008-12-20 17:09:25 +1100367 else
Kim Phillips9c4a7962008-06-23 19:50:15 +0800368 if (!error)
369 break;
370 else
371 status = error;
372
373 dma_unmap_single(dev, request->dma_desc,
LEROY Christophe7d607c6a2015-04-17 16:32:09 +0200374 TALITOS_DESC_SIZE,
Kim Phillipse938e462009-03-29 15:53:23 +0800375 DMA_BIDIRECTIONAL);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800376
377 /* copy entries so we can call callback outside lock */
378 saved_req.desc = request->desc;
379 saved_req.callback = request->callback;
380 saved_req.context = request->context;
381
382 /* release request entry in fifo */
383 smp_wmb();
384 request->desc = NULL;
385
386 /* increment fifo tail */
Kim Phillips4b9926282009-08-13 11:50:38 +1000387 priv->chan[ch].tail = (tail + 1) & (priv->fifo_len - 1);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800388
Kim Phillips4b9926282009-08-13 11:50:38 +1000389 spin_unlock_irqrestore(&priv->chan[ch].tail_lock, flags);
Kim Phillipsec6644d2008-07-17 20:16:40 +0800390
Kim Phillips4b9926282009-08-13 11:50:38 +1000391 atomic_dec(&priv->chan[ch].submit_count);
Kim Phillipsec6644d2008-07-17 20:16:40 +0800392
Kim Phillips9c4a7962008-06-23 19:50:15 +0800393 saved_req.callback(dev, saved_req.desc, saved_req.context,
394 status);
395 /* channel may resume processing in single desc error case */
396 if (error && !reset_ch && status == error)
397 return;
Kim Phillips4b9926282009-08-13 11:50:38 +1000398 spin_lock_irqsave(&priv->chan[ch].tail_lock, flags);
399 tail = priv->chan[ch].tail;
Kim Phillips9c4a7962008-06-23 19:50:15 +0800400 }
401
Kim Phillips4b9926282009-08-13 11:50:38 +1000402 spin_unlock_irqrestore(&priv->chan[ch].tail_lock, flags);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800403}
404
405/*
406 * process completed requests for channels that have done status
407 */
LEROY Christophedd3c0982015-04-17 16:32:13 +0200408#define DEF_TALITOS1_DONE(name, ch_done_mask) \
409static void talitos1_done_##name(unsigned long data) \
410{ \
411 struct device *dev = (struct device *)data; \
412 struct talitos_private *priv = dev_get_drvdata(dev); \
413 unsigned long flags; \
414 \
415 if (ch_done_mask & 0x10000000) \
416 flush_channel(dev, 0, 0, 0); \
LEROY Christophedd3c0982015-04-17 16:32:13 +0200417 if (ch_done_mask & 0x40000000) \
418 flush_channel(dev, 1, 0, 0); \
419 if (ch_done_mask & 0x00010000) \
420 flush_channel(dev, 2, 0, 0); \
421 if (ch_done_mask & 0x00040000) \
422 flush_channel(dev, 3, 0, 0); \
423 \
LEROY Christophedd3c0982015-04-17 16:32:13 +0200424 /* At this point, all completed channels have been processed */ \
425 /* Unmask done interrupts for channels completed later on. */ \
426 spin_lock_irqsave(&priv->reg_lock, flags); \
427 clrbits32(priv->reg + TALITOS_IMR, ch_done_mask); \
428 clrbits32(priv->reg + TALITOS_IMR_LO, TALITOS1_IMR_LO_INIT); \
429 spin_unlock_irqrestore(&priv->reg_lock, flags); \
430}
431
432DEF_TALITOS1_DONE(4ch, TALITOS1_ISR_4CHDONE)
LEROY Christophe9c02e282017-10-06 15:04:55 +0200433DEF_TALITOS1_DONE(ch0, TALITOS1_ISR_CH_0_DONE)
LEROY Christophedd3c0982015-04-17 16:32:13 +0200434
435#define DEF_TALITOS2_DONE(name, ch_done_mask) \
436static void talitos2_done_##name(unsigned long data) \
Kim Phillipsc3e337f2011-11-21 16:13:27 +0800437{ \
438 struct device *dev = (struct device *)data; \
439 struct talitos_private *priv = dev_get_drvdata(dev); \
Horia Geanta511d63c2012-03-30 17:49:53 +0300440 unsigned long flags; \
Kim Phillipsc3e337f2011-11-21 16:13:27 +0800441 \
442 if (ch_done_mask & 1) \
443 flush_channel(dev, 0, 0, 0); \
Kim Phillipsc3e337f2011-11-21 16:13:27 +0800444 if (ch_done_mask & (1 << 2)) \
445 flush_channel(dev, 1, 0, 0); \
446 if (ch_done_mask & (1 << 4)) \
447 flush_channel(dev, 2, 0, 0); \
448 if (ch_done_mask & (1 << 6)) \
449 flush_channel(dev, 3, 0, 0); \
450 \
Kim Phillipsc3e337f2011-11-21 16:13:27 +0800451 /* At this point, all completed channels have been processed */ \
452 /* Unmask done interrupts for channels completed later on. */ \
Horia Geanta511d63c2012-03-30 17:49:53 +0300453 spin_lock_irqsave(&priv->reg_lock, flags); \
Kim Phillipsc3e337f2011-11-21 16:13:27 +0800454 setbits32(priv->reg + TALITOS_IMR, ch_done_mask); \
LEROY Christophedd3c0982015-04-17 16:32:13 +0200455 setbits32(priv->reg + TALITOS_IMR_LO, TALITOS2_IMR_LO_INIT); \
Horia Geanta511d63c2012-03-30 17:49:53 +0300456 spin_unlock_irqrestore(&priv->reg_lock, flags); \
Kim Phillips9c4a7962008-06-23 19:50:15 +0800457}
LEROY Christophedd3c0982015-04-17 16:32:13 +0200458
459DEF_TALITOS2_DONE(4ch, TALITOS2_ISR_4CHDONE)
LEROY Christophe9c02e282017-10-06 15:04:55 +0200460DEF_TALITOS2_DONE(ch0, TALITOS2_ISR_CH_0_DONE)
LEROY Christophedd3c0982015-04-17 16:32:13 +0200461DEF_TALITOS2_DONE(ch0_2, TALITOS2_ISR_CH_0_2_DONE)
462DEF_TALITOS2_DONE(ch1_3, TALITOS2_ISR_CH_1_3_DONE)
Kim Phillips9c4a7962008-06-23 19:50:15 +0800463
464/*
465 * locate current (offending) descriptor
466 */
Kim Phillips3e721ae2011-10-21 15:20:28 +0200467static u32 current_desc_hdr(struct device *dev, int ch)
Kim Phillips9c4a7962008-06-23 19:50:15 +0800468{
469 struct talitos_private *priv = dev_get_drvdata(dev);
Horia Geantab62ffd82013-11-13 12:20:37 +0200470 int tail, iter;
Kim Phillips9c4a7962008-06-23 19:50:15 +0800471 dma_addr_t cur_desc;
472
Horia Geantab62ffd82013-11-13 12:20:37 +0200473 cur_desc = ((u64)in_be32(priv->chan[ch].reg + TALITOS_CDPR)) << 32;
474 cur_desc |= in_be32(priv->chan[ch].reg + TALITOS_CDPR_LO);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800475
Horia Geantab62ffd82013-11-13 12:20:37 +0200476 if (!cur_desc) {
477 dev_err(dev, "CDPR is NULL, giving up search for offending descriptor\n");
478 return 0;
479 }
480
481 tail = priv->chan[ch].tail;
482
483 iter = tail;
LEROY Christophe37b5e882017-10-06 15:05:06 +0200484 while (priv->chan[ch].fifo[iter].dma_desc != cur_desc &&
485 priv->chan[ch].fifo[iter].desc->next_desc != cur_desc) {
Horia Geantab62ffd82013-11-13 12:20:37 +0200486 iter = (iter + 1) & (priv->fifo_len - 1);
487 if (iter == tail) {
Kim Phillips9c4a7962008-06-23 19:50:15 +0800488 dev_err(dev, "couldn't locate current descriptor\n");
Kim Phillips3e721ae2011-10-21 15:20:28 +0200489 return 0;
Kim Phillips9c4a7962008-06-23 19:50:15 +0800490 }
491 }
492
LEROY Christophe37b5e882017-10-06 15:05:06 +0200493 if (priv->chan[ch].fifo[iter].desc->next_desc == cur_desc)
494 return (priv->chan[ch].fifo[iter].desc + 1)->hdr;
495
Horia Geantab62ffd82013-11-13 12:20:37 +0200496 return priv->chan[ch].fifo[iter].desc->hdr;
Kim Phillips9c4a7962008-06-23 19:50:15 +0800497}
498
499/*
500 * user diagnostics; report root cause of error based on execution unit status
501 */
Kim Phillips3e721ae2011-10-21 15:20:28 +0200502static void report_eu_error(struct device *dev, int ch, u32 desc_hdr)
Kim Phillips9c4a7962008-06-23 19:50:15 +0800503{
504 struct talitos_private *priv = dev_get_drvdata(dev);
505 int i;
506
Kim Phillips3e721ae2011-10-21 15:20:28 +0200507 if (!desc_hdr)
Kim Phillipsad42d5f2011-11-21 16:13:27 +0800508 desc_hdr = in_be32(priv->chan[ch].reg + TALITOS_DESCBUF);
Kim Phillips3e721ae2011-10-21 15:20:28 +0200509
510 switch (desc_hdr & DESC_HDR_SEL0_MASK) {
Kim Phillips9c4a7962008-06-23 19:50:15 +0800511 case DESC_HDR_SEL0_AFEU:
512 dev_err(dev, "AFEUISR 0x%08x_%08x\n",
LEROY Christophe5fa7fa12015-04-17 16:32:11 +0200513 in_be32(priv->reg_afeu + TALITOS_EUISR),
514 in_be32(priv->reg_afeu + TALITOS_EUISR_LO));
Kim Phillips9c4a7962008-06-23 19:50:15 +0800515 break;
516 case DESC_HDR_SEL0_DEU:
517 dev_err(dev, "DEUISR 0x%08x_%08x\n",
LEROY Christophe5fa7fa12015-04-17 16:32:11 +0200518 in_be32(priv->reg_deu + TALITOS_EUISR),
519 in_be32(priv->reg_deu + TALITOS_EUISR_LO));
Kim Phillips9c4a7962008-06-23 19:50:15 +0800520 break;
521 case DESC_HDR_SEL0_MDEUA:
522 case DESC_HDR_SEL0_MDEUB:
523 dev_err(dev, "MDEUISR 0x%08x_%08x\n",
LEROY Christophe5fa7fa12015-04-17 16:32:11 +0200524 in_be32(priv->reg_mdeu + TALITOS_EUISR),
525 in_be32(priv->reg_mdeu + TALITOS_EUISR_LO));
Kim Phillips9c4a7962008-06-23 19:50:15 +0800526 break;
527 case DESC_HDR_SEL0_RNG:
528 dev_err(dev, "RNGUISR 0x%08x_%08x\n",
LEROY Christophe5fa7fa12015-04-17 16:32:11 +0200529 in_be32(priv->reg_rngu + TALITOS_ISR),
530 in_be32(priv->reg_rngu + TALITOS_ISR_LO));
Kim Phillips9c4a7962008-06-23 19:50:15 +0800531 break;
532 case DESC_HDR_SEL0_PKEU:
533 dev_err(dev, "PKEUISR 0x%08x_%08x\n",
LEROY Christophe5fa7fa12015-04-17 16:32:11 +0200534 in_be32(priv->reg_pkeu + TALITOS_EUISR),
535 in_be32(priv->reg_pkeu + TALITOS_EUISR_LO));
Kim Phillips9c4a7962008-06-23 19:50:15 +0800536 break;
537 case DESC_HDR_SEL0_AESU:
538 dev_err(dev, "AESUISR 0x%08x_%08x\n",
LEROY Christophe5fa7fa12015-04-17 16:32:11 +0200539 in_be32(priv->reg_aesu + TALITOS_EUISR),
540 in_be32(priv->reg_aesu + TALITOS_EUISR_LO));
Kim Phillips9c4a7962008-06-23 19:50:15 +0800541 break;
542 case DESC_HDR_SEL0_CRCU:
543 dev_err(dev, "CRCUISR 0x%08x_%08x\n",
LEROY Christophe5fa7fa12015-04-17 16:32:11 +0200544 in_be32(priv->reg_crcu + TALITOS_EUISR),
545 in_be32(priv->reg_crcu + TALITOS_EUISR_LO));
Kim Phillips9c4a7962008-06-23 19:50:15 +0800546 break;
547 case DESC_HDR_SEL0_KEU:
548 dev_err(dev, "KEUISR 0x%08x_%08x\n",
LEROY Christophe5fa7fa12015-04-17 16:32:11 +0200549 in_be32(priv->reg_pkeu + TALITOS_EUISR),
550 in_be32(priv->reg_pkeu + TALITOS_EUISR_LO));
Kim Phillips9c4a7962008-06-23 19:50:15 +0800551 break;
552 }
553
Kim Phillips3e721ae2011-10-21 15:20:28 +0200554 switch (desc_hdr & DESC_HDR_SEL1_MASK) {
Kim Phillips9c4a7962008-06-23 19:50:15 +0800555 case DESC_HDR_SEL1_MDEUA:
556 case DESC_HDR_SEL1_MDEUB:
557 dev_err(dev, "MDEUISR 0x%08x_%08x\n",
LEROY Christophe5fa7fa12015-04-17 16:32:11 +0200558 in_be32(priv->reg_mdeu + TALITOS_EUISR),
559 in_be32(priv->reg_mdeu + TALITOS_EUISR_LO));
Kim Phillips9c4a7962008-06-23 19:50:15 +0800560 break;
561 case DESC_HDR_SEL1_CRCU:
562 dev_err(dev, "CRCUISR 0x%08x_%08x\n",
LEROY Christophe5fa7fa12015-04-17 16:32:11 +0200563 in_be32(priv->reg_crcu + TALITOS_EUISR),
564 in_be32(priv->reg_crcu + TALITOS_EUISR_LO));
Kim Phillips9c4a7962008-06-23 19:50:15 +0800565 break;
566 }
567
568 for (i = 0; i < 8; i++)
569 dev_err(dev, "DESCBUF 0x%08x_%08x\n",
Kim Phillipsad42d5f2011-11-21 16:13:27 +0800570 in_be32(priv->chan[ch].reg + TALITOS_DESCBUF + 8*i),
571 in_be32(priv->chan[ch].reg + TALITOS_DESCBUF_LO + 8*i));
Kim Phillips9c4a7962008-06-23 19:50:15 +0800572}
573
574/*
575 * recover from error interrupts
576 */
Kim Phillips5e718a02011-12-12 14:59:12 -0600577static void talitos_error(struct device *dev, u32 isr, u32 isr_lo)
Kim Phillips9c4a7962008-06-23 19:50:15 +0800578{
Kim Phillips9c4a7962008-06-23 19:50:15 +0800579 struct talitos_private *priv = dev_get_drvdata(dev);
580 unsigned int timeout = TALITOS_TIMEOUT;
LEROY Christophedd3c0982015-04-17 16:32:13 +0200581 int ch, error, reset_dev = 0;
Horia Geant?42e8b0d2015-05-11 20:04:56 +0300582 u32 v_lo;
LEROY Christophedd3c0982015-04-17 16:32:13 +0200583 bool is_sec1 = has_ftr_sec1(priv);
584 int reset_ch = is_sec1 ? 1 : 0; /* only SEC2 supports continuation */
Kim Phillips9c4a7962008-06-23 19:50:15 +0800585
586 for (ch = 0; ch < priv->num_channels; ch++) {
587 /* skip channels without errors */
LEROY Christophedd3c0982015-04-17 16:32:13 +0200588 if (is_sec1) {
589 /* bits 29, 31, 17, 19 */
590 if (!(isr & (1 << (29 + (ch & 1) * 2 - (ch & 2) * 6))))
591 continue;
592 } else {
593 if (!(isr & (1 << (ch * 2 + 1))))
594 continue;
595 }
Kim Phillips9c4a7962008-06-23 19:50:15 +0800596
597 error = -EINVAL;
598
Kim Phillipsad42d5f2011-11-21 16:13:27 +0800599 v_lo = in_be32(priv->chan[ch].reg + TALITOS_CCPSR_LO);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800600
601 if (v_lo & TALITOS_CCPSR_LO_DOF) {
602 dev_err(dev, "double fetch fifo overflow error\n");
603 error = -EAGAIN;
604 reset_ch = 1;
605 }
606 if (v_lo & TALITOS_CCPSR_LO_SOF) {
607 /* h/w dropped descriptor */
608 dev_err(dev, "single fetch fifo overflow error\n");
609 error = -EAGAIN;
610 }
611 if (v_lo & TALITOS_CCPSR_LO_MDTE)
612 dev_err(dev, "master data transfer error\n");
613 if (v_lo & TALITOS_CCPSR_LO_SGDLZ)
Colin Ian King4d9b3a52016-11-01 20:14:04 -0600614 dev_err(dev, is_sec1 ? "pointer not complete error\n"
LEROY Christophedd3c0982015-04-17 16:32:13 +0200615 : "s/g data length zero error\n");
Kim Phillips9c4a7962008-06-23 19:50:15 +0800616 if (v_lo & TALITOS_CCPSR_LO_FPZ)
LEROY Christophedd3c0982015-04-17 16:32:13 +0200617 dev_err(dev, is_sec1 ? "parity error\n"
618 : "fetch pointer zero error\n");
Kim Phillips9c4a7962008-06-23 19:50:15 +0800619 if (v_lo & TALITOS_CCPSR_LO_IDH)
620 dev_err(dev, "illegal descriptor header error\n");
621 if (v_lo & TALITOS_CCPSR_LO_IEU)
LEROY Christophedd3c0982015-04-17 16:32:13 +0200622 dev_err(dev, is_sec1 ? "static assignment error\n"
623 : "invalid exec unit error\n");
Kim Phillips9c4a7962008-06-23 19:50:15 +0800624 if (v_lo & TALITOS_CCPSR_LO_EU)
Kim Phillips3e721ae2011-10-21 15:20:28 +0200625 report_eu_error(dev, ch, current_desc_hdr(dev, ch));
LEROY Christophedd3c0982015-04-17 16:32:13 +0200626 if (!is_sec1) {
627 if (v_lo & TALITOS_CCPSR_LO_GB)
628 dev_err(dev, "gather boundary error\n");
629 if (v_lo & TALITOS_CCPSR_LO_GRL)
630 dev_err(dev, "gather return/length error\n");
631 if (v_lo & TALITOS_CCPSR_LO_SB)
632 dev_err(dev, "scatter boundary error\n");
633 if (v_lo & TALITOS_CCPSR_LO_SRL)
634 dev_err(dev, "scatter return/length error\n");
635 }
Kim Phillips9c4a7962008-06-23 19:50:15 +0800636
637 flush_channel(dev, ch, error, reset_ch);
638
639 if (reset_ch) {
640 reset_channel(dev, ch);
641 } else {
Kim Phillipsad42d5f2011-11-21 16:13:27 +0800642 setbits32(priv->chan[ch].reg + TALITOS_CCCR,
LEROY Christophedd3c0982015-04-17 16:32:13 +0200643 TALITOS2_CCCR_CONT);
Kim Phillipsad42d5f2011-11-21 16:13:27 +0800644 setbits32(priv->chan[ch].reg + TALITOS_CCCR_LO, 0);
645 while ((in_be32(priv->chan[ch].reg + TALITOS_CCCR) &
LEROY Christophedd3c0982015-04-17 16:32:13 +0200646 TALITOS2_CCCR_CONT) && --timeout)
Kim Phillips9c4a7962008-06-23 19:50:15 +0800647 cpu_relax();
648 if (timeout == 0) {
649 dev_err(dev, "failed to restart channel %d\n",
650 ch);
651 reset_dev = 1;
652 }
653 }
654 }
LEROY Christophedd3c0982015-04-17 16:32:13 +0200655 if (reset_dev || (is_sec1 && isr & ~TALITOS1_ISR_4CHERR) ||
656 (!is_sec1 && isr & ~TALITOS2_ISR_4CHERR) || isr_lo) {
657 if (is_sec1 && (isr_lo & TALITOS1_ISR_TEA_ERR))
658 dev_err(dev, "TEA error: ISR 0x%08x_%08x\n",
659 isr, isr_lo);
660 else
661 dev_err(dev, "done overflow, internal time out, or "
662 "rngu error: ISR 0x%08x_%08x\n", isr, isr_lo);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800663
664 /* purge request queues */
665 for (ch = 0; ch < priv->num_channels; ch++)
666 flush_channel(dev, ch, -EIO, 1);
667
668 /* reset and reinitialize the device */
669 init_device(dev);
670 }
671}
672
LEROY Christophedd3c0982015-04-17 16:32:13 +0200673#define DEF_TALITOS1_INTERRUPT(name, ch_done_mask, ch_err_mask, tlet) \
674static irqreturn_t talitos1_interrupt_##name(int irq, void *data) \
675{ \
676 struct device *dev = data; \
677 struct talitos_private *priv = dev_get_drvdata(dev); \
678 u32 isr, isr_lo; \
679 unsigned long flags; \
680 \
681 spin_lock_irqsave(&priv->reg_lock, flags); \
682 isr = in_be32(priv->reg + TALITOS_ISR); \
683 isr_lo = in_be32(priv->reg + TALITOS_ISR_LO); \
684 /* Acknowledge interrupt */ \
685 out_be32(priv->reg + TALITOS_ICR, isr & (ch_done_mask | ch_err_mask)); \
686 out_be32(priv->reg + TALITOS_ICR_LO, isr_lo); \
687 \
688 if (unlikely(isr & ch_err_mask || isr_lo & TALITOS1_IMR_LO_INIT)) { \
689 spin_unlock_irqrestore(&priv->reg_lock, flags); \
690 talitos_error(dev, isr & ch_err_mask, isr_lo); \
691 } \
692 else { \
693 if (likely(isr & ch_done_mask)) { \
694 /* mask further done interrupts. */ \
695 setbits32(priv->reg + TALITOS_IMR, ch_done_mask); \
696 /* done_task will unmask done interrupts at exit */ \
697 tasklet_schedule(&priv->done_task[tlet]); \
698 } \
699 spin_unlock_irqrestore(&priv->reg_lock, flags); \
700 } \
701 \
702 return (isr & (ch_done_mask | ch_err_mask) || isr_lo) ? IRQ_HANDLED : \
703 IRQ_NONE; \
704}
705
706DEF_TALITOS1_INTERRUPT(4ch, TALITOS1_ISR_4CHDONE, TALITOS1_ISR_4CHERR, 0)
707
708#define DEF_TALITOS2_INTERRUPT(name, ch_done_mask, ch_err_mask, tlet) \
709static irqreturn_t talitos2_interrupt_##name(int irq, void *data) \
Kim Phillipsc3e337f2011-11-21 16:13:27 +0800710{ \
711 struct device *dev = data; \
712 struct talitos_private *priv = dev_get_drvdata(dev); \
713 u32 isr, isr_lo; \
Horia Geanta511d63c2012-03-30 17:49:53 +0300714 unsigned long flags; \
Kim Phillipsc3e337f2011-11-21 16:13:27 +0800715 \
Horia Geanta511d63c2012-03-30 17:49:53 +0300716 spin_lock_irqsave(&priv->reg_lock, flags); \
Kim Phillipsc3e337f2011-11-21 16:13:27 +0800717 isr = in_be32(priv->reg + TALITOS_ISR); \
718 isr_lo = in_be32(priv->reg + TALITOS_ISR_LO); \
719 /* Acknowledge interrupt */ \
720 out_be32(priv->reg + TALITOS_ICR, isr & (ch_done_mask | ch_err_mask)); \
721 out_be32(priv->reg + TALITOS_ICR_LO, isr_lo); \
722 \
Horia Geanta511d63c2012-03-30 17:49:53 +0300723 if (unlikely(isr & ch_err_mask || isr_lo)) { \
724 spin_unlock_irqrestore(&priv->reg_lock, flags); \
725 talitos_error(dev, isr & ch_err_mask, isr_lo); \
726 } \
727 else { \
Kim Phillipsc3e337f2011-11-21 16:13:27 +0800728 if (likely(isr & ch_done_mask)) { \
729 /* mask further done interrupts. */ \
730 clrbits32(priv->reg + TALITOS_IMR, ch_done_mask); \
731 /* done_task will unmask done interrupts at exit */ \
732 tasklet_schedule(&priv->done_task[tlet]); \
733 } \
Horia Geanta511d63c2012-03-30 17:49:53 +0300734 spin_unlock_irqrestore(&priv->reg_lock, flags); \
735 } \
Kim Phillipsc3e337f2011-11-21 16:13:27 +0800736 \
737 return (isr & (ch_done_mask | ch_err_mask) || isr_lo) ? IRQ_HANDLED : \
738 IRQ_NONE; \
Kim Phillips9c4a7962008-06-23 19:50:15 +0800739}
LEROY Christophedd3c0982015-04-17 16:32:13 +0200740
741DEF_TALITOS2_INTERRUPT(4ch, TALITOS2_ISR_4CHDONE, TALITOS2_ISR_4CHERR, 0)
742DEF_TALITOS2_INTERRUPT(ch0_2, TALITOS2_ISR_CH_0_2_DONE, TALITOS2_ISR_CH_0_2_ERR,
743 0)
744DEF_TALITOS2_INTERRUPT(ch1_3, TALITOS2_ISR_CH_1_3_DONE, TALITOS2_ISR_CH_1_3_ERR,
745 1)
Kim Phillips9c4a7962008-06-23 19:50:15 +0800746
747/*
748 * hwrng
749 */
750static int talitos_rng_data_present(struct hwrng *rng, int wait)
751{
752 struct device *dev = (struct device *)rng->priv;
753 struct talitos_private *priv = dev_get_drvdata(dev);
754 u32 ofl;
755 int i;
756
757 for (i = 0; i < 20; i++) {
LEROY Christophe5fa7fa12015-04-17 16:32:11 +0200758 ofl = in_be32(priv->reg_rngu + TALITOS_EUSR_LO) &
Kim Phillips9c4a7962008-06-23 19:50:15 +0800759 TALITOS_RNGUSR_LO_OFL;
760 if (ofl || !wait)
761 break;
762 udelay(10);
763 }
764
765 return !!ofl;
766}
767
768static int talitos_rng_data_read(struct hwrng *rng, u32 *data)
769{
770 struct device *dev = (struct device *)rng->priv;
771 struct talitos_private *priv = dev_get_drvdata(dev);
772
773 /* rng fifo requires 64-bit accesses */
LEROY Christophe5fa7fa12015-04-17 16:32:11 +0200774 *data = in_be32(priv->reg_rngu + TALITOS_EU_FIFO);
775 *data = in_be32(priv->reg_rngu + TALITOS_EU_FIFO_LO);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800776
777 return sizeof(u32);
778}
779
780static int talitos_rng_init(struct hwrng *rng)
781{
782 struct device *dev = (struct device *)rng->priv;
783 struct talitos_private *priv = dev_get_drvdata(dev);
784 unsigned int timeout = TALITOS_TIMEOUT;
785
LEROY Christophe5fa7fa12015-04-17 16:32:11 +0200786 setbits32(priv->reg_rngu + TALITOS_EURCR_LO, TALITOS_RNGURCR_LO_SR);
787 while (!(in_be32(priv->reg_rngu + TALITOS_EUSR_LO)
788 & TALITOS_RNGUSR_LO_RD)
Kim Phillips9c4a7962008-06-23 19:50:15 +0800789 && --timeout)
790 cpu_relax();
791 if (timeout == 0) {
792 dev_err(dev, "failed to reset rng hw\n");
793 return -ENODEV;
794 }
795
796 /* start generating */
LEROY Christophe5fa7fa12015-04-17 16:32:11 +0200797 setbits32(priv->reg_rngu + TALITOS_EUDSR_LO, 0);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800798
799 return 0;
800}
801
802static int talitos_register_rng(struct device *dev)
803{
804 struct talitos_private *priv = dev_get_drvdata(dev);
Aaron Sierra35a3bb32015-08-05 16:52:08 -0500805 int err;
Kim Phillips9c4a7962008-06-23 19:50:15 +0800806
807 priv->rng.name = dev_driver_string(dev),
808 priv->rng.init = talitos_rng_init,
809 priv->rng.data_present = talitos_rng_data_present,
810 priv->rng.data_read = talitos_rng_data_read,
811 priv->rng.priv = (unsigned long)dev;
812
Aaron Sierra35a3bb32015-08-05 16:52:08 -0500813 err = hwrng_register(&priv->rng);
814 if (!err)
815 priv->rng_registered = true;
816
817 return err;
Kim Phillips9c4a7962008-06-23 19:50:15 +0800818}
819
820static void talitos_unregister_rng(struct device *dev)
821{
822 struct talitos_private *priv = dev_get_drvdata(dev);
823
Aaron Sierra35a3bb32015-08-05 16:52:08 -0500824 if (!priv->rng_registered)
825 return;
826
Kim Phillips9c4a7962008-06-23 19:50:15 +0800827 hwrng_unregister(&priv->rng);
Aaron Sierra35a3bb32015-08-05 16:52:08 -0500828 priv->rng_registered = false;
Kim Phillips9c4a7962008-06-23 19:50:15 +0800829}
830
831/*
832 * crypto alg
833 */
834#define TALITOS_CRA_PRIORITY 3000
LEROY Christophe7405c8d2016-06-06 13:20:46 +0200835/*
836 * Defines a priority for doing AEAD with descriptors type
837 * HMAC_SNOOP_NO_AFEA (HSNA) instead of type IPSEC_ESP
838 */
839#define TALITOS_CRA_PRIORITY_AEAD_HSNA (TALITOS_CRA_PRIORITY - 1)
Martin Hicks03d2c512017-05-02 09:38:35 -0400840#define TALITOS_MAX_KEY_SIZE (AES_MAX_KEY_SIZE + SHA512_BLOCK_SIZE)
Lee Nipper3952f172008-07-10 18:29:18 +0800841#define TALITOS_MAX_IV_LENGTH 16 /* max of AES_BLOCK_SIZE, DES3_EDE_BLOCK_SIZE */
Lee Nipper70bcaca2008-07-03 19:08:46 +0800842
Kim Phillips9c4a7962008-06-23 19:50:15 +0800843struct talitos_ctx {
844 struct device *dev;
Kim Phillips5228f0f2011-07-15 11:21:38 +0800845 int ch;
Kim Phillips9c4a7962008-06-23 19:50:15 +0800846 __be32 desc_hdr_template;
847 u8 key[TALITOS_MAX_KEY_SIZE];
Lee Nipper70bcaca2008-07-03 19:08:46 +0800848 u8 iv[TALITOS_MAX_IV_LENGTH];
LEROY Christophe2e13ce02017-10-06 15:05:02 +0200849 dma_addr_t dma_key;
Kim Phillips9c4a7962008-06-23 19:50:15 +0800850 unsigned int keylen;
851 unsigned int enckeylen;
852 unsigned int authkeylen;
Kim Phillips9c4a7962008-06-23 19:50:15 +0800853};
854
Lee Nipper497f2e62010-05-19 19:20:36 +1000855#define HASH_MAX_BLOCK_SIZE SHA512_BLOCK_SIZE
856#define TALITOS_MDEU_MAX_CONTEXT_SIZE TALITOS_MDEU_CONTEXT_SIZE_SHA384_SHA512
857
858struct talitos_ahash_req_ctx {
Kim Phillips60f208d2010-05-19 19:21:53 +1000859 u32 hw_context[TALITOS_MDEU_MAX_CONTEXT_SIZE / sizeof(u32)];
Lee Nipper497f2e62010-05-19 19:20:36 +1000860 unsigned int hw_context_size;
LEROY Christophe3c0dd192017-10-06 15:05:08 +0200861 u8 buf[2][HASH_MAX_BLOCK_SIZE];
862 int buf_idx;
Kim Phillips60f208d2010-05-19 19:21:53 +1000863 unsigned int swinit;
Lee Nipper497f2e62010-05-19 19:20:36 +1000864 unsigned int first;
865 unsigned int last;
866 unsigned int to_hash_later;
Horia Geant?42e8b0d2015-05-11 20:04:56 +0300867 unsigned int nbuf;
Lee Nipper497f2e62010-05-19 19:20:36 +1000868 struct scatterlist bufsl[2];
869 struct scatterlist *psrc;
870};
871
Horia Geant?3639ca82016-04-21 19:24:55 +0300872struct talitos_export_state {
873 u32 hw_context[TALITOS_MDEU_MAX_CONTEXT_SIZE / sizeof(u32)];
874 u8 buf[HASH_MAX_BLOCK_SIZE];
875 unsigned int swinit;
876 unsigned int first;
877 unsigned int last;
878 unsigned int to_hash_later;
879 unsigned int nbuf;
880};
881
Lee Nipper56af8cd2009-03-29 15:50:50 +0800882static int aead_setkey(struct crypto_aead *authenc,
883 const u8 *key, unsigned int keylen)
Kim Phillips9c4a7962008-06-23 19:50:15 +0800884{
885 struct talitos_ctx *ctx = crypto_aead_ctx(authenc);
LEROY Christophe2e13ce02017-10-06 15:05:02 +0200886 struct device *dev = ctx->dev;
Mathias Krausec306a982013-10-15 13:49:34 +0200887 struct crypto_authenc_keys keys;
Kim Phillips9c4a7962008-06-23 19:50:15 +0800888
Mathias Krausec306a982013-10-15 13:49:34 +0200889 if (crypto_authenc_extractkeys(&keys, key, keylen) != 0)
Kim Phillips9c4a7962008-06-23 19:50:15 +0800890 goto badkey;
891
Mathias Krausec306a982013-10-15 13:49:34 +0200892 if (keys.authkeylen + keys.enckeylen > TALITOS_MAX_KEY_SIZE)
Kim Phillips9c4a7962008-06-23 19:50:15 +0800893 goto badkey;
894
LEROY Christophe2e13ce02017-10-06 15:05:02 +0200895 if (ctx->keylen)
896 dma_unmap_single(dev, ctx->dma_key, ctx->keylen, DMA_TO_DEVICE);
897
Mathias Krausec306a982013-10-15 13:49:34 +0200898 memcpy(ctx->key, keys.authkey, keys.authkeylen);
899 memcpy(&ctx->key[keys.authkeylen], keys.enckey, keys.enckeylen);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800900
Mathias Krausec306a982013-10-15 13:49:34 +0200901 ctx->keylen = keys.authkeylen + keys.enckeylen;
902 ctx->enckeylen = keys.enckeylen;
903 ctx->authkeylen = keys.authkeylen;
LEROY Christophe2e13ce02017-10-06 15:05:02 +0200904 ctx->dma_key = dma_map_single(dev, ctx->key, ctx->keylen,
905 DMA_TO_DEVICE);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800906
Tudor-Dan Ambarus8f0691f2018-03-23 12:42:24 +0200907 memzero_explicit(&keys, sizeof(keys));
Kim Phillips9c4a7962008-06-23 19:50:15 +0800908 return 0;
909
910badkey:
911 crypto_aead_set_flags(authenc, CRYPTO_TFM_RES_BAD_KEY_LEN);
Tudor-Dan Ambarus8f0691f2018-03-23 12:42:24 +0200912 memzero_explicit(&keys, sizeof(keys));
Kim Phillips9c4a7962008-06-23 19:50:15 +0800913 return -EINVAL;
914}
915
916/*
Lee Nipper56af8cd2009-03-29 15:50:50 +0800917 * talitos_edesc - s/w-extended descriptor
Kim Phillips9c4a7962008-06-23 19:50:15 +0800918 * @src_nents: number of segments in input scatterlist
919 * @dst_nents: number of segments in output scatterlist
Herbert Xuaeb4c132015-07-30 17:53:22 +0800920 * @icv_ool: whether ICV is out-of-line
Horia Geanta79fd31d2012-08-02 17:16:40 +0300921 * @iv_dma: dma address of iv for checking continuity and link table
Kim Phillips9c4a7962008-06-23 19:50:15 +0800922 * @dma_len: length of dma mapped link_tbl space
LEROY Christophe6f65f6a2015-04-17 16:32:15 +0200923 * @dma_link_tbl: bus physical address of link_tbl/buf
Kim Phillips9c4a7962008-06-23 19:50:15 +0800924 * @desc: h/w descriptor
LEROY Christophe6f65f6a2015-04-17 16:32:15 +0200925 * @link_tbl: input and output h/w link tables (if {src,dst}_nents > 1) (SEC2)
926 * @buf: input and output buffeur (if {src,dst}_nents > 1) (SEC1)
Kim Phillips9c4a7962008-06-23 19:50:15 +0800927 *
928 * if decrypting (with authcheck), or either one of src_nents or dst_nents
929 * is greater than 1, an integrity check value is concatenated to the end
930 * of link_tbl data
931 */
Lee Nipper56af8cd2009-03-29 15:50:50 +0800932struct talitos_edesc {
Kim Phillips9c4a7962008-06-23 19:50:15 +0800933 int src_nents;
934 int dst_nents;
Herbert Xuaeb4c132015-07-30 17:53:22 +0800935 bool icv_ool;
Horia Geanta79fd31d2012-08-02 17:16:40 +0300936 dma_addr_t iv_dma;
Kim Phillips9c4a7962008-06-23 19:50:15 +0800937 int dma_len;
938 dma_addr_t dma_link_tbl;
939 struct talitos_desc desc;
LEROY Christophe6f65f6a2015-04-17 16:32:15 +0200940 union {
941 struct talitos_ptr link_tbl[0];
942 u8 buf[0];
943 };
Kim Phillips9c4a7962008-06-23 19:50:15 +0800944};
945
Lee Nipper4de9d0b2009-03-29 15:52:32 +0800946static void talitos_sg_unmap(struct device *dev,
947 struct talitos_edesc *edesc,
948 struct scatterlist *src,
LEROY Christophe6a1e8d12016-06-06 13:20:38 +0200949 struct scatterlist *dst,
950 unsigned int len, unsigned int offset)
LEROY Christophe246a87c2016-06-06 13:20:36 +0200951{
952 struct talitos_private *priv = dev_get_drvdata(dev);
953 bool is_sec1 = has_ftr_sec1(priv);
LEROY Christophe6a1e8d12016-06-06 13:20:38 +0200954 unsigned int src_nents = edesc->src_nents ? : 1;
955 unsigned int dst_nents = edesc->dst_nents ? : 1;
LEROY Christophe246a87c2016-06-06 13:20:36 +0200956
LEROY Christophe6a1e8d12016-06-06 13:20:38 +0200957 if (is_sec1 && dst && dst_nents > 1) {
958 dma_sync_single_for_device(dev, edesc->dma_link_tbl + offset,
959 len, DMA_FROM_DEVICE);
960 sg_pcopy_from_buffer(dst, dst_nents, edesc->buf + offset, len,
961 offset);
962 }
963 if (src != dst) {
964 if (src_nents == 1 || !is_sec1)
965 dma_unmap_sg(dev, src, src_nents, DMA_TO_DEVICE);
966
967 if (dst && (dst_nents == 1 || !is_sec1))
968 dma_unmap_sg(dev, dst, dst_nents, DMA_FROM_DEVICE);
969 } else if (src_nents == 1 || !is_sec1) {
970 dma_unmap_sg(dev, src, src_nents, DMA_BIDIRECTIONAL);
LEROY Christophe246a87c2016-06-06 13:20:36 +0200971 }
972}
973
Kim Phillips9c4a7962008-06-23 19:50:15 +0800974static void ipsec_esp_unmap(struct device *dev,
Lee Nipper56af8cd2009-03-29 15:50:50 +0800975 struct talitos_edesc *edesc,
Kim Phillips9c4a7962008-06-23 19:50:15 +0800976 struct aead_request *areq)
977{
LEROY Christophe549bd8b2016-06-06 13:20:40 +0200978 struct crypto_aead *aead = crypto_aead_reqtfm(areq);
979 struct talitos_ctx *ctx = crypto_aead_ctx(aead);
980 unsigned int ivsize = crypto_aead_ivsize(aead);
LEROY Christophe9a655602017-10-06 15:04:59 +0200981 bool is_ipsec_esp = edesc->desc.hdr & DESC_HDR_TYPE_IPSEC_ESP;
982 struct talitos_ptr *civ_ptr = &edesc->desc.ptr[is_ipsec_esp ? 2 : 3];
LEROY Christophe549bd8b2016-06-06 13:20:40 +0200983
LEROY Christophe9a655602017-10-06 15:04:59 +0200984 if (is_ipsec_esp)
LEROY Christophe549bd8b2016-06-06 13:20:40 +0200985 unmap_single_talitos_ptr(dev, &edesc->desc.ptr[6],
986 DMA_FROM_DEVICE);
LEROY Christophe9a655602017-10-06 15:04:59 +0200987 unmap_single_talitos_ptr(dev, civ_ptr, DMA_TO_DEVICE);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800988
LEROY Christophe6a1e8d12016-06-06 13:20:38 +0200989 talitos_sg_unmap(dev, edesc, areq->src, areq->dst, areq->cryptlen,
990 areq->assoclen);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800991
992 if (edesc->dma_len)
993 dma_unmap_single(dev, edesc->dma_link_tbl, edesc->dma_len,
994 DMA_BIDIRECTIONAL);
LEROY Christophe549bd8b2016-06-06 13:20:40 +0200995
LEROY Christophe9a655602017-10-06 15:04:59 +0200996 if (!is_ipsec_esp) {
LEROY Christophe549bd8b2016-06-06 13:20:40 +0200997 unsigned int dst_nents = edesc->dst_nents ? : 1;
998
999 sg_pcopy_to_buffer(areq->dst, dst_nents, ctx->iv, ivsize,
1000 areq->assoclen + areq->cryptlen - ivsize);
1001 }
Kim Phillips9c4a7962008-06-23 19:50:15 +08001002}
1003
1004/*
1005 * ipsec_esp descriptor callbacks
1006 */
1007static void ipsec_esp_encrypt_done(struct device *dev,
1008 struct talitos_desc *desc, void *context,
1009 int err)
1010{
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001011 struct talitos_private *priv = dev_get_drvdata(dev);
1012 bool is_sec1 = has_ftr_sec1(priv);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001013 struct aead_request *areq = context;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001014 struct crypto_aead *authenc = crypto_aead_reqtfm(areq);
Herbert Xuaeb4c132015-07-30 17:53:22 +08001015 unsigned int authsize = crypto_aead_authsize(authenc);
LEROY Christophe2e13ce02017-10-06 15:05:02 +02001016 unsigned int ivsize = crypto_aead_ivsize(authenc);
Kim Phillips19bbbc62009-03-29 15:53:59 +08001017 struct talitos_edesc *edesc;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001018 struct scatterlist *sg;
1019 void *icvdata;
1020
Kim Phillips19bbbc62009-03-29 15:53:59 +08001021 edesc = container_of(desc, struct talitos_edesc, desc);
1022
Kim Phillips9c4a7962008-06-23 19:50:15 +08001023 ipsec_esp_unmap(dev, edesc, areq);
1024
1025 /* copy the generated ICV to dst */
Herbert Xuaeb4c132015-07-30 17:53:22 +08001026 if (edesc->icv_ool) {
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001027 if (is_sec1)
1028 icvdata = edesc->buf + areq->assoclen + areq->cryptlen;
1029 else
1030 icvdata = &edesc->link_tbl[edesc->src_nents +
1031 edesc->dst_nents + 2];
Kim Phillips9c4a7962008-06-23 19:50:15 +08001032 sg = sg_last(areq->dst, edesc->dst_nents);
Herbert Xuaeb4c132015-07-30 17:53:22 +08001033 memcpy((char *)sg_virt(sg) + sg->length - authsize,
1034 icvdata, authsize);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001035 }
1036
LEROY Christophe2e13ce02017-10-06 15:05:02 +02001037 dma_unmap_single(dev, edesc->iv_dma, ivsize, DMA_TO_DEVICE);
1038
Kim Phillips9c4a7962008-06-23 19:50:15 +08001039 kfree(edesc);
1040
1041 aead_request_complete(areq, err);
1042}
1043
Kim Phillipsfe5720e2008-10-12 20:33:14 +08001044static void ipsec_esp_decrypt_swauth_done(struct device *dev,
Kim Phillipse938e462009-03-29 15:53:23 +08001045 struct talitos_desc *desc,
1046 void *context, int err)
Kim Phillips9c4a7962008-06-23 19:50:15 +08001047{
1048 struct aead_request *req = context;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001049 struct crypto_aead *authenc = crypto_aead_reqtfm(req);
Herbert Xuaeb4c132015-07-30 17:53:22 +08001050 unsigned int authsize = crypto_aead_authsize(authenc);
Kim Phillips19bbbc62009-03-29 15:53:59 +08001051 struct talitos_edesc *edesc;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001052 struct scatterlist *sg;
Herbert Xuaeb4c132015-07-30 17:53:22 +08001053 char *oicv, *icv;
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001054 struct talitos_private *priv = dev_get_drvdata(dev);
1055 bool is_sec1 = has_ftr_sec1(priv);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001056
Kim Phillips19bbbc62009-03-29 15:53:59 +08001057 edesc = container_of(desc, struct talitos_edesc, desc);
1058
Kim Phillips9c4a7962008-06-23 19:50:15 +08001059 ipsec_esp_unmap(dev, edesc, req);
1060
1061 if (!err) {
1062 /* auth check */
Kim Phillips9c4a7962008-06-23 19:50:15 +08001063 sg = sg_last(req->dst, edesc->dst_nents ? : 1);
Herbert Xuaeb4c132015-07-30 17:53:22 +08001064 icv = (char *)sg_virt(sg) + sg->length - authsize;
1065
1066 if (edesc->dma_len) {
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001067 if (is_sec1)
1068 oicv = (char *)&edesc->dma_link_tbl +
1069 req->assoclen + req->cryptlen;
1070 else
1071 oicv = (char *)
1072 &edesc->link_tbl[edesc->src_nents +
Herbert Xuaeb4c132015-07-30 17:53:22 +08001073 edesc->dst_nents + 2];
1074 if (edesc->icv_ool)
1075 icv = oicv + authsize;
1076 } else
1077 oicv = (char *)&edesc->link_tbl[0];
1078
David Gstir79960942015-11-15 17:14:42 +01001079 err = crypto_memneq(oicv, icv, authsize) ? -EBADMSG : 0;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001080 }
1081
1082 kfree(edesc);
1083
1084 aead_request_complete(req, err);
1085}
1086
Kim Phillipsfe5720e2008-10-12 20:33:14 +08001087static void ipsec_esp_decrypt_hwauth_done(struct device *dev,
Kim Phillipse938e462009-03-29 15:53:23 +08001088 struct talitos_desc *desc,
1089 void *context, int err)
Kim Phillipsfe5720e2008-10-12 20:33:14 +08001090{
1091 struct aead_request *req = context;
Kim Phillips19bbbc62009-03-29 15:53:59 +08001092 struct talitos_edesc *edesc;
1093
1094 edesc = container_of(desc, struct talitos_edesc, desc);
Kim Phillipsfe5720e2008-10-12 20:33:14 +08001095
1096 ipsec_esp_unmap(dev, edesc, req);
1097
1098 /* check ICV auth status */
Kim Phillipse938e462009-03-29 15:53:23 +08001099 if (!err && ((desc->hdr_lo & DESC_HDR_LO_ICCR1_MASK) !=
1100 DESC_HDR_LO_ICCR1_PASS))
1101 err = -EBADMSG;
Kim Phillipsfe5720e2008-10-12 20:33:14 +08001102
1103 kfree(edesc);
1104
1105 aead_request_complete(req, err);
1106}
1107
Kim Phillips9c4a7962008-06-23 19:50:15 +08001108/*
1109 * convert scatterlist to SEC h/w link table format
1110 * stop at cryptlen bytes
1111 */
Herbert Xuaeb4c132015-07-30 17:53:22 +08001112static int sg_to_link_tbl_offset(struct scatterlist *sg, int sg_count,
1113 unsigned int offset, int cryptlen,
1114 struct talitos_ptr *link_tbl_ptr)
Kim Phillips9c4a7962008-06-23 19:50:15 +08001115{
Lee Nipper70bcaca2008-07-03 19:08:46 +08001116 int n_sg = sg_count;
Herbert Xuaeb4c132015-07-30 17:53:22 +08001117 int count = 0;
Lee Nipper70bcaca2008-07-03 19:08:46 +08001118
Herbert Xuaeb4c132015-07-30 17:53:22 +08001119 while (cryptlen && sg && n_sg--) {
1120 unsigned int len = sg_dma_len(sg);
1121
1122 if (offset >= len) {
1123 offset -= len;
1124 goto next;
1125 }
1126
1127 len -= offset;
1128
1129 if (len > cryptlen)
1130 len = cryptlen;
1131
1132 to_talitos_ptr(link_tbl_ptr + count,
LEROY Christopheda9de142017-10-06 15:04:57 +02001133 sg_dma_address(sg) + offset, len, 0);
LEROY Christopheb096b542016-06-06 13:20:34 +02001134 to_talitos_ptr_ext_set(link_tbl_ptr + count, 0, 0);
Herbert Xuaeb4c132015-07-30 17:53:22 +08001135 count++;
1136 cryptlen -= len;
1137 offset = 0;
1138
1139next:
Cristian Stoica5be4d4c2015-01-20 10:06:16 +02001140 sg = sg_next(sg);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001141 }
1142
Kim Phillips9c4a7962008-06-23 19:50:15 +08001143 /* tag end of link table */
Herbert Xuaeb4c132015-07-30 17:53:22 +08001144 if (count > 0)
LEROY Christopheb096b542016-06-06 13:20:34 +02001145 to_talitos_ptr_ext_set(link_tbl_ptr + count - 1,
1146 DESC_PTR_LNKTBL_RETURN, 0);
Lee Nipper70bcaca2008-07-03 19:08:46 +08001147
Herbert Xuaeb4c132015-07-30 17:53:22 +08001148 return count;
1149}
1150
LEROY Christophe2b122732018-03-22 10:57:01 +01001151static int talitos_sg_map_ext(struct device *dev, struct scatterlist *src,
1152 unsigned int len, struct talitos_edesc *edesc,
1153 struct talitos_ptr *ptr, int sg_count,
1154 unsigned int offset, int tbl_off, int elen)
LEROY Christophe246a87c2016-06-06 13:20:36 +02001155{
LEROY Christophe246a87c2016-06-06 13:20:36 +02001156 struct talitos_private *priv = dev_get_drvdata(dev);
1157 bool is_sec1 = has_ftr_sec1(priv);
1158
LEROY Christophe87a81dc2018-01-26 17:09:59 +01001159 if (!src) {
1160 to_talitos_ptr(ptr, 0, 0, is_sec1);
1161 return 1;
1162 }
LEROY Christophe2b122732018-03-22 10:57:01 +01001163 to_talitos_ptr_ext_set(ptr, elen, is_sec1);
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001164 if (sg_count == 1) {
LEROY Christopheda9de142017-10-06 15:04:57 +02001165 to_talitos_ptr(ptr, sg_dma_address(src) + offset, len, is_sec1);
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001166 return sg_count;
LEROY Christophe246a87c2016-06-06 13:20:36 +02001167 }
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001168 if (is_sec1) {
LEROY Christopheda9de142017-10-06 15:04:57 +02001169 to_talitos_ptr(ptr, edesc->dma_link_tbl + offset, len, is_sec1);
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001170 return sg_count;
1171 }
LEROY Christophe2b122732018-03-22 10:57:01 +01001172 sg_count = sg_to_link_tbl_offset(src, sg_count, offset, len + elen,
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001173 &edesc->link_tbl[tbl_off]);
1174 if (sg_count == 1) {
1175 /* Only one segment now, so no link tbl needed*/
1176 copy_talitos_ptr(ptr, &edesc->link_tbl[tbl_off], is_sec1);
1177 return sg_count;
1178 }
1179 to_talitos_ptr(ptr, edesc->dma_link_tbl +
LEROY Christopheda9de142017-10-06 15:04:57 +02001180 tbl_off * sizeof(struct talitos_ptr), len, is_sec1);
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001181 to_talitos_ptr_ext_or(ptr, DESC_PTR_LNKTBL_JUMP, is_sec1);
1182
LEROY Christophe246a87c2016-06-06 13:20:36 +02001183 return sg_count;
1184}
1185
LEROY Christophe2b122732018-03-22 10:57:01 +01001186static int talitos_sg_map(struct device *dev, struct scatterlist *src,
1187 unsigned int len, struct talitos_edesc *edesc,
1188 struct talitos_ptr *ptr, int sg_count,
1189 unsigned int offset, int tbl_off)
1190{
1191 return talitos_sg_map_ext(dev, src, len, edesc, ptr, sg_count, offset,
1192 tbl_off, 0);
1193}
1194
Kim Phillips9c4a7962008-06-23 19:50:15 +08001195/*
1196 * fill in and submit ipsec_esp descriptor
1197 */
Lee Nipper56af8cd2009-03-29 15:50:50 +08001198static int ipsec_esp(struct talitos_edesc *edesc, struct aead_request *areq,
Herbert Xuaeb4c132015-07-30 17:53:22 +08001199 void (*callback)(struct device *dev,
1200 struct talitos_desc *desc,
1201 void *context, int error))
Kim Phillips9c4a7962008-06-23 19:50:15 +08001202{
1203 struct crypto_aead *aead = crypto_aead_reqtfm(areq);
Herbert Xuaeb4c132015-07-30 17:53:22 +08001204 unsigned int authsize = crypto_aead_authsize(aead);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001205 struct talitos_ctx *ctx = crypto_aead_ctx(aead);
1206 struct device *dev = ctx->dev;
1207 struct talitos_desc *desc = &edesc->desc;
1208 unsigned int cryptlen = areq->cryptlen;
Kim Phillipse41256f2009-08-13 11:49:06 +10001209 unsigned int ivsize = crypto_aead_ivsize(aead);
Herbert Xuaeb4c132015-07-30 17:53:22 +08001210 int tbl_off = 0;
Kim Phillipsfa86a262008-07-17 20:20:06 +08001211 int sg_count, ret;
LEROY Christophe2b122732018-03-22 10:57:01 +01001212 int elen = 0;
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001213 bool sync_needed = false;
1214 struct talitos_private *priv = dev_get_drvdata(dev);
1215 bool is_sec1 = has_ftr_sec1(priv);
LEROY Christophe9a655602017-10-06 15:04:59 +02001216 bool is_ipsec_esp = desc->hdr & DESC_HDR_TYPE_IPSEC_ESP;
1217 struct talitos_ptr *civ_ptr = &desc->ptr[is_ipsec_esp ? 2 : 3];
1218 struct talitos_ptr *ckey_ptr = &desc->ptr[is_ipsec_esp ? 3 : 2];
Kim Phillips9c4a7962008-06-23 19:50:15 +08001219
1220 /* hmac key */
LEROY Christophe2e13ce02017-10-06 15:05:02 +02001221 to_talitos_ptr(&desc->ptr[0], ctx->dma_key, ctx->authkeylen, is_sec1);
Horia Geanta79fd31d2012-08-02 17:16:40 +03001222
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001223 sg_count = edesc->src_nents ?: 1;
1224 if (is_sec1 && sg_count > 1)
1225 sg_copy_to_buffer(areq->src, sg_count, edesc->buf,
1226 areq->assoclen + cryptlen);
1227 else
1228 sg_count = dma_map_sg(dev, areq->src, sg_count,
1229 (areq->src == areq->dst) ?
1230 DMA_BIDIRECTIONAL : DMA_TO_DEVICE);
1231
Kim Phillips9c4a7962008-06-23 19:50:15 +08001232 /* hmac data */
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001233 ret = talitos_sg_map(dev, areq->src, areq->assoclen, edesc,
1234 &desc->ptr[1], sg_count, 0, tbl_off);
Horia Geanta79fd31d2012-08-02 17:16:40 +03001235
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001236 if (ret > 1) {
Horia Geant?340ff602016-04-19 20:33:48 +03001237 tbl_off += ret;
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001238 sync_needed = true;
Horia Geanta79fd31d2012-08-02 17:16:40 +03001239 }
1240
Kim Phillips9c4a7962008-06-23 19:50:15 +08001241 /* cipher iv */
LEROY Christophe9a655602017-10-06 15:04:59 +02001242 to_talitos_ptr(civ_ptr, edesc->iv_dma, ivsize, is_sec1);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001243
1244 /* cipher key */
LEROY Christophe2e13ce02017-10-06 15:05:02 +02001245 to_talitos_ptr(ckey_ptr, ctx->dma_key + ctx->authkeylen,
1246 ctx->enckeylen, is_sec1);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001247
1248 /*
1249 * cipher in
1250 * map and adjust cipher len to aead request cryptlen.
1251 * extent is bytes of HMAC postpended to ciphertext,
1252 * typically 12 for ipsec
1253 */
LEROY Christophe2b122732018-03-22 10:57:01 +01001254 if (is_ipsec_esp && (desc->hdr & DESC_HDR_MODE1_MDEU_CICV))
1255 elen = authsize;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001256
LEROY Christophe2b122732018-03-22 10:57:01 +01001257 ret = talitos_sg_map_ext(dev, areq->src, cryptlen, edesc, &desc->ptr[4],
1258 sg_count, areq->assoclen, tbl_off, elen);
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001259
LEROY Christopheec8c7d12017-10-06 15:04:33 +02001260 if (ret > 1) {
1261 tbl_off += ret;
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001262 sync_needed = true;
Horia Geant?340ff602016-04-19 20:33:48 +03001263 }
Kim Phillips9c4a7962008-06-23 19:50:15 +08001264
1265 /* cipher out */
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001266 if (areq->src != areq->dst) {
1267 sg_count = edesc->dst_nents ? : 1;
1268 if (!is_sec1 || sg_count == 1)
1269 dma_map_sg(dev, areq->dst, sg_count, DMA_FROM_DEVICE);
1270 }
Kim Phillips9c4a7962008-06-23 19:50:15 +08001271
LEROY Christophee04a61b2017-10-06 15:04:35 +02001272 ret = talitos_sg_map(dev, areq->dst, cryptlen, edesc, &desc->ptr[5],
1273 sg_count, areq->assoclen, tbl_off);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001274
LEROY Christophe9a655602017-10-06 15:04:59 +02001275 if (is_ipsec_esp)
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001276 to_talitos_ptr_ext_or(&desc->ptr[5], authsize, is_sec1);
Herbert Xuaeb4c132015-07-30 17:53:22 +08001277
LEROY Christophee04a61b2017-10-06 15:04:35 +02001278 /* ICV data */
1279 if (ret > 1) {
1280 tbl_off += ret;
Herbert Xuaeb4c132015-07-30 17:53:22 +08001281 edesc->icv_ool = true;
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001282 sync_needed = true;
1283
LEROY Christophe9a655602017-10-06 15:04:59 +02001284 if (is_ipsec_esp) {
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001285 struct talitos_ptr *tbl_ptr = &edesc->link_tbl[tbl_off];
1286 int offset = (edesc->src_nents + edesc->dst_nents + 2) *
1287 sizeof(struct talitos_ptr) + authsize;
1288
1289 /* Add an entry to the link table for ICV data */
LEROY Christophee04a61b2017-10-06 15:04:35 +02001290 to_talitos_ptr_ext_set(tbl_ptr - 1, 0, is_sec1);
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001291 to_talitos_ptr_ext_set(tbl_ptr, DESC_PTR_LNKTBL_RETURN,
1292 is_sec1);
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001293
1294 /* icv data follows link tables */
1295 to_talitos_ptr(tbl_ptr, edesc->dma_link_tbl + offset,
LEROY Christopheda9de142017-10-06 15:04:57 +02001296 authsize, is_sec1);
LEROY Christophee04a61b2017-10-06 15:04:35 +02001297 } else {
1298 dma_addr_t addr = edesc->dma_link_tbl;
1299
1300 if (is_sec1)
1301 addr += areq->assoclen + cryptlen;
1302 else
1303 addr += sizeof(struct talitos_ptr) * tbl_off;
1304
LEROY Christopheda9de142017-10-06 15:04:57 +02001305 to_talitos_ptr(&desc->ptr[6], addr, authsize, is_sec1);
LEROY Christophee04a61b2017-10-06 15:04:35 +02001306 }
LEROY Christophe9a655602017-10-06 15:04:59 +02001307 } else if (!is_ipsec_esp) {
LEROY Christophee04a61b2017-10-06 15:04:35 +02001308 ret = talitos_sg_map(dev, areq->dst, authsize, edesc,
1309 &desc->ptr[6], sg_count, areq->assoclen +
1310 cryptlen,
1311 tbl_off);
1312 if (ret > 1) {
1313 tbl_off += ret;
1314 edesc->icv_ool = true;
1315 sync_needed = true;
1316 } else {
1317 edesc->icv_ool = false;
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001318 }
Horia Geant?340ff602016-04-19 20:33:48 +03001319 } else {
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001320 edesc->icv_ool = false;
1321 }
1322
Kim Phillips9c4a7962008-06-23 19:50:15 +08001323 /* iv out */
LEROY Christophe9a655602017-10-06 15:04:59 +02001324 if (is_ipsec_esp)
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001325 map_single_talitos_ptr(dev, &desc->ptr[6], ivsize, ctx->iv,
1326 DMA_FROM_DEVICE);
1327
1328 if (sync_needed)
1329 dma_sync_single_for_device(dev, edesc->dma_link_tbl,
1330 edesc->dma_len,
1331 DMA_BIDIRECTIONAL);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001332
Kim Phillips5228f0f2011-07-15 11:21:38 +08001333 ret = talitos_submit(dev, ctx->ch, desc, callback, areq);
Kim Phillipsfa86a262008-07-17 20:20:06 +08001334 if (ret != -EINPROGRESS) {
1335 ipsec_esp_unmap(dev, edesc, areq);
1336 kfree(edesc);
1337 }
1338 return ret;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001339}
1340
Kim Phillips9c4a7962008-06-23 19:50:15 +08001341/*
Lee Nipper56af8cd2009-03-29 15:50:50 +08001342 * allocate and map the extended descriptor
Kim Phillips9c4a7962008-06-23 19:50:15 +08001343 */
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001344static struct talitos_edesc *talitos_edesc_alloc(struct device *dev,
1345 struct scatterlist *src,
1346 struct scatterlist *dst,
Horia Geanta79fd31d2012-08-02 17:16:40 +03001347 u8 *iv,
1348 unsigned int assoclen,
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001349 unsigned int cryptlen,
1350 unsigned int authsize,
Horia Geanta79fd31d2012-08-02 17:16:40 +03001351 unsigned int ivsize,
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001352 int icv_stashing,
Horia Geanta62293a32013-11-28 15:11:17 +02001353 u32 cryptoflags,
1354 bool encrypt)
Kim Phillips9c4a7962008-06-23 19:50:15 +08001355{
Lee Nipper56af8cd2009-03-29 15:50:50 +08001356 struct talitos_edesc *edesc;
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001357 int src_nents, dst_nents, alloc_len, dma_len, src_len, dst_len;
Horia Geanta79fd31d2012-08-02 17:16:40 +03001358 dma_addr_t iv_dma = 0;
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001359 gfp_t flags = cryptoflags & CRYPTO_TFM_REQ_MAY_SLEEP ? GFP_KERNEL :
Kim Phillips586725f2008-07-17 20:19:18 +08001360 GFP_ATOMIC;
LEROY Christophe6f65f6a2015-04-17 16:32:15 +02001361 struct talitos_private *priv = dev_get_drvdata(dev);
1362 bool is_sec1 = has_ftr_sec1(priv);
1363 int max_len = is_sec1 ? TALITOS1_MAX_DATA_LEN : TALITOS2_MAX_DATA_LEN;
LABBE Corentin8e409fe2015-11-04 21:13:34 +01001364 void *err;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001365
LEROY Christophe6f65f6a2015-04-17 16:32:15 +02001366 if (cryptlen + authsize > max_len) {
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001367 dev_err(dev, "length exceeds h/w max limit\n");
Kim Phillips9c4a7962008-06-23 19:50:15 +08001368 return ERR_PTR(-EINVAL);
1369 }
1370
Horia Geanta935e99a2013-11-19 14:57:49 +02001371 if (ivsize)
Horia Geanta79fd31d2012-08-02 17:16:40 +03001372 iv_dma = dma_map_single(dev, iv, ivsize, DMA_TO_DEVICE);
1373
Horia Geanta62293a32013-11-28 15:11:17 +02001374 if (!dst || dst == src) {
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001375 src_len = assoclen + cryptlen + authsize;
1376 src_nents = sg_nents_for_len(src, src_len);
LABBE Corentin8e409fe2015-11-04 21:13:34 +01001377 if (src_nents < 0) {
1378 dev_err(dev, "Invalid number of src SG.\n");
1379 err = ERR_PTR(-EINVAL);
1380 goto error_sg;
1381 }
Horia Geanta62293a32013-11-28 15:11:17 +02001382 src_nents = (src_nents == 1) ? 0 : src_nents;
1383 dst_nents = dst ? src_nents : 0;
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001384 dst_len = 0;
Horia Geanta62293a32013-11-28 15:11:17 +02001385 } else { /* dst && dst != src*/
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001386 src_len = assoclen + cryptlen + (encrypt ? 0 : authsize);
1387 src_nents = sg_nents_for_len(src, src_len);
LABBE Corentin8e409fe2015-11-04 21:13:34 +01001388 if (src_nents < 0) {
1389 dev_err(dev, "Invalid number of src SG.\n");
1390 err = ERR_PTR(-EINVAL);
1391 goto error_sg;
1392 }
Horia Geanta62293a32013-11-28 15:11:17 +02001393 src_nents = (src_nents == 1) ? 0 : src_nents;
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001394 dst_len = assoclen + cryptlen + (encrypt ? authsize : 0);
1395 dst_nents = sg_nents_for_len(dst, dst_len);
LABBE Corentin8e409fe2015-11-04 21:13:34 +01001396 if (dst_nents < 0) {
1397 dev_err(dev, "Invalid number of dst SG.\n");
1398 err = ERR_PTR(-EINVAL);
1399 goto error_sg;
1400 }
Horia Geanta62293a32013-11-28 15:11:17 +02001401 dst_nents = (dst_nents == 1) ? 0 : dst_nents;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001402 }
1403
1404 /*
1405 * allocate space for base edesc plus the link tables,
Herbert Xuaeb4c132015-07-30 17:53:22 +08001406 * allowing for two separate entries for AD and generated ICV (+ 2),
1407 * and space for two sets of ICVs (stashed and generated)
Kim Phillips9c4a7962008-06-23 19:50:15 +08001408 */
Lee Nipper56af8cd2009-03-29 15:50:50 +08001409 alloc_len = sizeof(struct talitos_edesc);
Herbert Xuaeb4c132015-07-30 17:53:22 +08001410 if (src_nents || dst_nents) {
LEROY Christophe6f65f6a2015-04-17 16:32:15 +02001411 if (is_sec1)
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001412 dma_len = (src_nents ? src_len : 0) +
1413 (dst_nents ? dst_len : 0);
LEROY Christophe6f65f6a2015-04-17 16:32:15 +02001414 else
Herbert Xuaeb4c132015-07-30 17:53:22 +08001415 dma_len = (src_nents + dst_nents + 2) *
1416 sizeof(struct talitos_ptr) + authsize * 2;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001417 alloc_len += dma_len;
1418 } else {
1419 dma_len = 0;
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001420 alloc_len += icv_stashing ? authsize : 0;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001421 }
1422
LEROY Christophe37b5e882017-10-06 15:05:06 +02001423 /* if its a ahash, add space for a second desc next to the first one */
1424 if (is_sec1 && !dst)
1425 alloc_len += sizeof(struct talitos_desc);
1426
Kim Phillips586725f2008-07-17 20:19:18 +08001427 edesc = kmalloc(alloc_len, GFP_DMA | flags);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001428 if (!edesc) {
LABBE Corentin8e409fe2015-11-04 21:13:34 +01001429 err = ERR_PTR(-ENOMEM);
1430 goto error_sg;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001431 }
LEROY Christophee4a647c2017-10-06 15:04:45 +02001432 memset(&edesc->desc, 0, sizeof(edesc->desc));
Kim Phillips9c4a7962008-06-23 19:50:15 +08001433
1434 edesc->src_nents = src_nents;
1435 edesc->dst_nents = dst_nents;
Horia Geanta79fd31d2012-08-02 17:16:40 +03001436 edesc->iv_dma = iv_dma;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001437 edesc->dma_len = dma_len;
LEROY Christophe37b5e882017-10-06 15:05:06 +02001438 if (dma_len) {
1439 void *addr = &edesc->link_tbl[0];
1440
1441 if (is_sec1 && !dst)
1442 addr += sizeof(struct talitos_desc);
1443 edesc->dma_link_tbl = dma_map_single(dev, addr,
Lee Nipper497f2e62010-05-19 19:20:36 +10001444 edesc->dma_len,
1445 DMA_BIDIRECTIONAL);
LEROY Christophe37b5e882017-10-06 15:05:06 +02001446 }
Kim Phillips9c4a7962008-06-23 19:50:15 +08001447 return edesc;
LABBE Corentin8e409fe2015-11-04 21:13:34 +01001448error_sg:
1449 if (iv_dma)
1450 dma_unmap_single(dev, iv_dma, ivsize, DMA_TO_DEVICE);
1451 return err;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001452}
1453
Horia Geanta79fd31d2012-08-02 17:16:40 +03001454static struct talitos_edesc *aead_edesc_alloc(struct aead_request *areq, u8 *iv,
Horia Geanta62293a32013-11-28 15:11:17 +02001455 int icv_stashing, bool encrypt)
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001456{
1457 struct crypto_aead *authenc = crypto_aead_reqtfm(areq);
Herbert Xuaeb4c132015-07-30 17:53:22 +08001458 unsigned int authsize = crypto_aead_authsize(authenc);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001459 struct talitos_ctx *ctx = crypto_aead_ctx(authenc);
Horia Geanta79fd31d2012-08-02 17:16:40 +03001460 unsigned int ivsize = crypto_aead_ivsize(authenc);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001461
Herbert Xuaeb4c132015-07-30 17:53:22 +08001462 return talitos_edesc_alloc(ctx->dev, areq->src, areq->dst,
Horia Geanta79fd31d2012-08-02 17:16:40 +03001463 iv, areq->assoclen, areq->cryptlen,
Herbert Xuaeb4c132015-07-30 17:53:22 +08001464 authsize, ivsize, icv_stashing,
Horia Geanta62293a32013-11-28 15:11:17 +02001465 areq->base.flags, encrypt);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001466}
1467
Lee Nipper56af8cd2009-03-29 15:50:50 +08001468static int aead_encrypt(struct aead_request *req)
Kim Phillips9c4a7962008-06-23 19:50:15 +08001469{
1470 struct crypto_aead *authenc = crypto_aead_reqtfm(req);
1471 struct talitos_ctx *ctx = crypto_aead_ctx(authenc);
Lee Nipper56af8cd2009-03-29 15:50:50 +08001472 struct talitos_edesc *edesc;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001473
1474 /* allocate extended descriptor */
Horia Geanta62293a32013-11-28 15:11:17 +02001475 edesc = aead_edesc_alloc(req, req->iv, 0, true);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001476 if (IS_ERR(edesc))
1477 return PTR_ERR(edesc);
1478
1479 /* set encrypt */
Lee Nipper70bcaca2008-07-03 19:08:46 +08001480 edesc->desc.hdr = ctx->desc_hdr_template | DESC_HDR_MODE0_ENCRYPT;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001481
Herbert Xuaeb4c132015-07-30 17:53:22 +08001482 return ipsec_esp(edesc, req, ipsec_esp_encrypt_done);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001483}
1484
Lee Nipper56af8cd2009-03-29 15:50:50 +08001485static int aead_decrypt(struct aead_request *req)
Kim Phillips9c4a7962008-06-23 19:50:15 +08001486{
1487 struct crypto_aead *authenc = crypto_aead_reqtfm(req);
Herbert Xuaeb4c132015-07-30 17:53:22 +08001488 unsigned int authsize = crypto_aead_authsize(authenc);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001489 struct talitos_ctx *ctx = crypto_aead_ctx(authenc);
Kim Phillipsfe5720e2008-10-12 20:33:14 +08001490 struct talitos_private *priv = dev_get_drvdata(ctx->dev);
Lee Nipper56af8cd2009-03-29 15:50:50 +08001491 struct talitos_edesc *edesc;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001492 struct scatterlist *sg;
1493 void *icvdata;
1494
1495 req->cryptlen -= authsize;
1496
1497 /* allocate extended descriptor */
Horia Geanta62293a32013-11-28 15:11:17 +02001498 edesc = aead_edesc_alloc(req, req->iv, 1, false);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001499 if (IS_ERR(edesc))
1500 return PTR_ERR(edesc);
1501
Kim Phillipsfe5720e2008-10-12 20:33:14 +08001502 if ((priv->features & TALITOS_FTR_HW_AUTH_CHECK) &&
Kim Phillipse938e462009-03-29 15:53:23 +08001503 ((!edesc->src_nents && !edesc->dst_nents) ||
1504 priv->features & TALITOS_FTR_SRC_LINK_TBL_LEN_INCLUDES_EXTENT)) {
Kim Phillips9c4a7962008-06-23 19:50:15 +08001505
Kim Phillipsfe5720e2008-10-12 20:33:14 +08001506 /* decrypt and check the ICV */
Kim Phillipse938e462009-03-29 15:53:23 +08001507 edesc->desc.hdr = ctx->desc_hdr_template |
1508 DESC_HDR_DIR_INBOUND |
Kim Phillipsfe5720e2008-10-12 20:33:14 +08001509 DESC_HDR_MODE1_MDEU_CICV;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001510
Kim Phillipsfe5720e2008-10-12 20:33:14 +08001511 /* reset integrity check result bits */
Kim Phillips9c4a7962008-06-23 19:50:15 +08001512
Herbert Xuaeb4c132015-07-30 17:53:22 +08001513 return ipsec_esp(edesc, req, ipsec_esp_decrypt_hwauth_done);
Kim Phillipsfe5720e2008-10-12 20:33:14 +08001514 }
Kim Phillipse938e462009-03-29 15:53:23 +08001515
1516 /* Have to check the ICV with software */
1517 edesc->desc.hdr = ctx->desc_hdr_template | DESC_HDR_DIR_INBOUND;
1518
1519 /* stash incoming ICV for later cmp with ICV generated by the h/w */
1520 if (edesc->dma_len)
Herbert Xuaeb4c132015-07-30 17:53:22 +08001521 icvdata = (char *)&edesc->link_tbl[edesc->src_nents +
1522 edesc->dst_nents + 2];
Kim Phillipse938e462009-03-29 15:53:23 +08001523 else
1524 icvdata = &edesc->link_tbl[0];
1525
1526 sg = sg_last(req->src, edesc->src_nents ? : 1);
1527
Herbert Xuaeb4c132015-07-30 17:53:22 +08001528 memcpy(icvdata, (char *)sg_virt(sg) + sg->length - authsize, authsize);
Kim Phillipse938e462009-03-29 15:53:23 +08001529
Herbert Xuaeb4c132015-07-30 17:53:22 +08001530 return ipsec_esp(edesc, req, ipsec_esp_decrypt_swauth_done);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001531}
1532
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001533static int ablkcipher_setkey(struct crypto_ablkcipher *cipher,
1534 const u8 *key, unsigned int keylen)
1535{
1536 struct talitos_ctx *ctx = crypto_ablkcipher_ctx(cipher);
LEROY Christophe2e13ce02017-10-06 15:05:02 +02001537 struct device *dev = ctx->dev;
LEROY Christophef384cdc2017-10-06 15:04:37 +02001538 u32 tmp[DES_EXPKEY_WORDS];
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001539
Martin Hicks03d2c512017-05-02 09:38:35 -04001540 if (keylen > TALITOS_MAX_KEY_SIZE) {
1541 crypto_ablkcipher_set_flags(cipher, CRYPTO_TFM_RES_BAD_KEY_LEN);
1542 return -EINVAL;
1543 }
1544
LEROY Christophef384cdc2017-10-06 15:04:37 +02001545 if (unlikely(crypto_ablkcipher_get_flags(cipher) &
1546 CRYPTO_TFM_REQ_WEAK_KEY) &&
1547 !des_ekey(tmp, key)) {
1548 crypto_ablkcipher_set_flags(cipher, CRYPTO_TFM_RES_WEAK_KEY);
1549 return -EINVAL;
1550 }
1551
LEROY Christophe2e13ce02017-10-06 15:05:02 +02001552 if (ctx->keylen)
1553 dma_unmap_single(dev, ctx->dma_key, ctx->keylen, DMA_TO_DEVICE);
1554
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001555 memcpy(&ctx->key, key, keylen);
1556 ctx->keylen = keylen;
1557
LEROY Christophe2e13ce02017-10-06 15:05:02 +02001558 ctx->dma_key = dma_map_single(dev, ctx->key, keylen, DMA_TO_DEVICE);
1559
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001560 return 0;
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001561}
1562
1563static void common_nonsnoop_unmap(struct device *dev,
1564 struct talitos_edesc *edesc,
1565 struct ablkcipher_request *areq)
1566{
1567 unmap_single_talitos_ptr(dev, &edesc->desc.ptr[5], DMA_FROM_DEVICE);
LEROY Christophe032d1972015-04-17 16:31:51 +02001568
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001569 talitos_sg_unmap(dev, edesc, areq->src, areq->dst, areq->nbytes, 0);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001570 unmap_single_talitos_ptr(dev, &edesc->desc.ptr[1], DMA_TO_DEVICE);
1571
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001572 if (edesc->dma_len)
1573 dma_unmap_single(dev, edesc->dma_link_tbl, edesc->dma_len,
1574 DMA_BIDIRECTIONAL);
1575}
1576
1577static void ablkcipher_done(struct device *dev,
1578 struct talitos_desc *desc, void *context,
1579 int err)
1580{
1581 struct ablkcipher_request *areq = context;
Kim Phillips19bbbc62009-03-29 15:53:59 +08001582 struct talitos_edesc *edesc;
1583
1584 edesc = container_of(desc, struct talitos_edesc, desc);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001585
1586 common_nonsnoop_unmap(dev, edesc, areq);
1587
1588 kfree(edesc);
1589
1590 areq->base.complete(&areq->base, err);
1591}
1592
1593static int common_nonsnoop(struct talitos_edesc *edesc,
1594 struct ablkcipher_request *areq,
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001595 void (*callback) (struct device *dev,
1596 struct talitos_desc *desc,
1597 void *context, int error))
1598{
1599 struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(areq);
1600 struct talitos_ctx *ctx = crypto_ablkcipher_ctx(cipher);
1601 struct device *dev = ctx->dev;
1602 struct talitos_desc *desc = &edesc->desc;
1603 unsigned int cryptlen = areq->nbytes;
Horia Geanta79fd31d2012-08-02 17:16:40 +03001604 unsigned int ivsize = crypto_ablkcipher_ivsize(cipher);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001605 int sg_count, ret;
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001606 bool sync_needed = false;
LEROY Christophe922f9dc2015-04-17 16:32:07 +02001607 struct talitos_private *priv = dev_get_drvdata(dev);
1608 bool is_sec1 = has_ftr_sec1(priv);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001609
1610 /* first DWORD empty */
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001611
1612 /* cipher iv */
LEROY Christopheda9de142017-10-06 15:04:57 +02001613 to_talitos_ptr(&desc->ptr[1], edesc->iv_dma, ivsize, is_sec1);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001614
1615 /* cipher key */
LEROY Christophe2e13ce02017-10-06 15:05:02 +02001616 to_talitos_ptr(&desc->ptr[2], ctx->dma_key, ctx->keylen, is_sec1);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001617
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001618 sg_count = edesc->src_nents ?: 1;
1619 if (is_sec1 && sg_count > 1)
1620 sg_copy_to_buffer(areq->src, sg_count, edesc->buf,
1621 cryptlen);
1622 else
1623 sg_count = dma_map_sg(dev, areq->src, sg_count,
1624 (areq->src == areq->dst) ?
1625 DMA_BIDIRECTIONAL : DMA_TO_DEVICE);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001626 /*
1627 * cipher in
1628 */
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001629 sg_count = talitos_sg_map(dev, areq->src, cryptlen, edesc,
1630 &desc->ptr[3], sg_count, 0, 0);
1631 if (sg_count > 1)
1632 sync_needed = true;
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001633
1634 /* cipher out */
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001635 if (areq->src != areq->dst) {
1636 sg_count = edesc->dst_nents ? : 1;
1637 if (!is_sec1 || sg_count == 1)
1638 dma_map_sg(dev, areq->dst, sg_count, DMA_FROM_DEVICE);
1639 }
1640
1641 ret = talitos_sg_map(dev, areq->dst, cryptlen, edesc, &desc->ptr[4],
1642 sg_count, 0, (edesc->src_nents + 1));
1643 if (ret > 1)
1644 sync_needed = true;
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001645
1646 /* iv out */
LEROY Christophea2b35aa2015-04-17 16:31:57 +02001647 map_single_talitos_ptr(dev, &desc->ptr[5], ivsize, ctx->iv,
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001648 DMA_FROM_DEVICE);
1649
1650 /* last DWORD empty */
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001651
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001652 if (sync_needed)
1653 dma_sync_single_for_device(dev, edesc->dma_link_tbl,
1654 edesc->dma_len, DMA_BIDIRECTIONAL);
1655
Kim Phillips5228f0f2011-07-15 11:21:38 +08001656 ret = talitos_submit(dev, ctx->ch, desc, callback, areq);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001657 if (ret != -EINPROGRESS) {
1658 common_nonsnoop_unmap(dev, edesc, areq);
1659 kfree(edesc);
1660 }
1661 return ret;
1662}
1663
Kim Phillipse938e462009-03-29 15:53:23 +08001664static struct talitos_edesc *ablkcipher_edesc_alloc(struct ablkcipher_request *
Horia Geanta62293a32013-11-28 15:11:17 +02001665 areq, bool encrypt)
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001666{
1667 struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(areq);
1668 struct talitos_ctx *ctx = crypto_ablkcipher_ctx(cipher);
Horia Geanta79fd31d2012-08-02 17:16:40 +03001669 unsigned int ivsize = crypto_ablkcipher_ivsize(cipher);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001670
Herbert Xuaeb4c132015-07-30 17:53:22 +08001671 return talitos_edesc_alloc(ctx->dev, areq->src, areq->dst,
Horia Geanta79fd31d2012-08-02 17:16:40 +03001672 areq->info, 0, areq->nbytes, 0, ivsize, 0,
Horia Geanta62293a32013-11-28 15:11:17 +02001673 areq->base.flags, encrypt);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001674}
1675
1676static int ablkcipher_encrypt(struct ablkcipher_request *areq)
1677{
1678 struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(areq);
1679 struct talitos_ctx *ctx = crypto_ablkcipher_ctx(cipher);
1680 struct talitos_edesc *edesc;
1681
1682 /* allocate extended descriptor */
Horia Geanta62293a32013-11-28 15:11:17 +02001683 edesc = ablkcipher_edesc_alloc(areq, true);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001684 if (IS_ERR(edesc))
1685 return PTR_ERR(edesc);
1686
1687 /* set encrypt */
1688 edesc->desc.hdr = ctx->desc_hdr_template | DESC_HDR_MODE0_ENCRYPT;
1689
Kim Phillipsfebec542011-07-15 11:21:39 +08001690 return common_nonsnoop(edesc, areq, ablkcipher_done);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001691}
1692
1693static int ablkcipher_decrypt(struct ablkcipher_request *areq)
1694{
1695 struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(areq);
1696 struct talitos_ctx *ctx = crypto_ablkcipher_ctx(cipher);
1697 struct talitos_edesc *edesc;
1698
1699 /* allocate extended descriptor */
Horia Geanta62293a32013-11-28 15:11:17 +02001700 edesc = ablkcipher_edesc_alloc(areq, false);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001701 if (IS_ERR(edesc))
1702 return PTR_ERR(edesc);
1703
1704 edesc->desc.hdr = ctx->desc_hdr_template | DESC_HDR_DIR_INBOUND;
1705
Kim Phillipsfebec542011-07-15 11:21:39 +08001706 return common_nonsnoop(edesc, areq, ablkcipher_done);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001707}
1708
Lee Nipper497f2e62010-05-19 19:20:36 +10001709static void common_nonsnoop_hash_unmap(struct device *dev,
1710 struct talitos_edesc *edesc,
1711 struct ahash_request *areq)
1712{
1713 struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
LEROY Christophead4cd512018-02-26 17:40:04 +01001714 struct talitos_private *priv = dev_get_drvdata(dev);
1715 bool is_sec1 = has_ftr_sec1(priv);
1716 struct talitos_desc *desc = &edesc->desc;
1717 struct talitos_desc *desc2 = desc + 1;
1718
1719 unmap_single_talitos_ptr(dev, &edesc->desc.ptr[5], DMA_FROM_DEVICE);
1720 if (desc->next_desc &&
1721 desc->ptr[5].ptr != desc2->ptr[5].ptr)
1722 unmap_single_talitos_ptr(dev, &desc2->ptr[5], DMA_FROM_DEVICE);
Lee Nipper497f2e62010-05-19 19:20:36 +10001723
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001724 talitos_sg_unmap(dev, edesc, req_ctx->psrc, NULL, 0, 0);
LEROY Christophe032d1972015-04-17 16:31:51 +02001725
LEROY Christophead4cd512018-02-26 17:40:04 +01001726 /* When using hashctx-in, must unmap it. */
1727 if (from_talitos_ptr_len(&edesc->desc.ptr[1], is_sec1))
1728 unmap_single_talitos_ptr(dev, &edesc->desc.ptr[1],
1729 DMA_TO_DEVICE);
1730 else if (desc->next_desc)
1731 unmap_single_talitos_ptr(dev, &desc2->ptr[1],
1732 DMA_TO_DEVICE);
1733
1734 if (is_sec1 && req_ctx->nbuf)
1735 unmap_single_talitos_ptr(dev, &desc->ptr[3],
1736 DMA_TO_DEVICE);
1737
Lee Nipper497f2e62010-05-19 19:20:36 +10001738 if (edesc->dma_len)
1739 dma_unmap_single(dev, edesc->dma_link_tbl, edesc->dma_len,
1740 DMA_BIDIRECTIONAL);
1741
LEROY Christophe37b5e882017-10-06 15:05:06 +02001742 if (edesc->desc.next_desc)
1743 dma_unmap_single(dev, be32_to_cpu(edesc->desc.next_desc),
1744 TALITOS_DESC_SIZE, DMA_BIDIRECTIONAL);
Lee Nipper497f2e62010-05-19 19:20:36 +10001745}
1746
1747static void ahash_done(struct device *dev,
1748 struct talitos_desc *desc, void *context,
1749 int err)
1750{
1751 struct ahash_request *areq = context;
1752 struct talitos_edesc *edesc =
1753 container_of(desc, struct talitos_edesc, desc);
1754 struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
1755
1756 if (!req_ctx->last && req_ctx->to_hash_later) {
1757 /* Position any partial block for next update/final/finup */
LEROY Christophe3c0dd192017-10-06 15:05:08 +02001758 req_ctx->buf_idx = (req_ctx->buf_idx + 1) & 1;
Lee Nipper5e833bc2010-06-16 15:29:15 +10001759 req_ctx->nbuf = req_ctx->to_hash_later;
Lee Nipper497f2e62010-05-19 19:20:36 +10001760 }
1761 common_nonsnoop_hash_unmap(dev, edesc, areq);
1762
1763 kfree(edesc);
1764
1765 areq->base.complete(&areq->base, err);
1766}
1767
LEROY Christophe2d029052015-04-17 16:32:18 +02001768/*
1769 * SEC1 doesn't like hashing of 0 sized message, so we do the padding
1770 * ourself and submit a padded block
1771 */
LEROY Christophe5b2cf262017-10-06 15:04:47 +02001772static void talitos_handle_buggy_hash(struct talitos_ctx *ctx,
LEROY Christophe2d029052015-04-17 16:32:18 +02001773 struct talitos_edesc *edesc,
1774 struct talitos_ptr *ptr)
1775{
1776 static u8 padded_hash[64] = {
1777 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1778 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1779 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1780 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1781 };
1782
1783 pr_err_once("Bug in SEC1, padding ourself\n");
1784 edesc->desc.hdr &= ~DESC_HDR_MODE0_MDEU_PAD;
1785 map_single_talitos_ptr(ctx->dev, ptr, sizeof(padded_hash),
1786 (char *)padded_hash, DMA_TO_DEVICE);
1787}
1788
Lee Nipper497f2e62010-05-19 19:20:36 +10001789static int common_nonsnoop_hash(struct talitos_edesc *edesc,
1790 struct ahash_request *areq, unsigned int length,
LEROY Christophe37b5e882017-10-06 15:05:06 +02001791 unsigned int offset,
Lee Nipper497f2e62010-05-19 19:20:36 +10001792 void (*callback) (struct device *dev,
1793 struct talitos_desc *desc,
1794 void *context, int error))
1795{
1796 struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
1797 struct talitos_ctx *ctx = crypto_ahash_ctx(tfm);
1798 struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
1799 struct device *dev = ctx->dev;
1800 struct talitos_desc *desc = &edesc->desc;
LEROY Christophe032d1972015-04-17 16:31:51 +02001801 int ret;
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001802 bool sync_needed = false;
LEROY Christophe922f9dc2015-04-17 16:32:07 +02001803 struct talitos_private *priv = dev_get_drvdata(dev);
1804 bool is_sec1 = has_ftr_sec1(priv);
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001805 int sg_count;
Lee Nipper497f2e62010-05-19 19:20:36 +10001806
1807 /* first DWORD empty */
Lee Nipper497f2e62010-05-19 19:20:36 +10001808
Kim Phillips60f208d2010-05-19 19:21:53 +10001809 /* hash context in */
1810 if (!req_ctx->first || req_ctx->swinit) {
LEROY Christophe6a4967c2018-02-26 17:40:06 +01001811 map_single_talitos_ptr_nosync(dev, &desc->ptr[1],
1812 req_ctx->hw_context_size,
1813 req_ctx->hw_context,
1814 DMA_TO_DEVICE);
Kim Phillips60f208d2010-05-19 19:21:53 +10001815 req_ctx->swinit = 0;
Lee Nipper497f2e62010-05-19 19:20:36 +10001816 }
LEROY Christopheafd62fa2017-09-13 12:44:51 +02001817 /* Indicate next op is not the first. */
1818 req_ctx->first = 0;
Lee Nipper497f2e62010-05-19 19:20:36 +10001819
1820 /* HMAC key */
1821 if (ctx->keylen)
LEROY Christophe2e13ce02017-10-06 15:05:02 +02001822 to_talitos_ptr(&desc->ptr[2], ctx->dma_key, ctx->keylen,
1823 is_sec1);
Lee Nipper497f2e62010-05-19 19:20:36 +10001824
LEROY Christophe37b5e882017-10-06 15:05:06 +02001825 if (is_sec1 && req_ctx->nbuf)
1826 length -= req_ctx->nbuf;
1827
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001828 sg_count = edesc->src_nents ?: 1;
1829 if (is_sec1 && sg_count > 1)
LEROY Christophe37b5e882017-10-06 15:05:06 +02001830 sg_pcopy_to_buffer(req_ctx->psrc, sg_count,
1831 edesc->buf + sizeof(struct talitos_desc),
1832 length, req_ctx->nbuf);
1833 else if (length)
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001834 sg_count = dma_map_sg(dev, req_ctx->psrc, sg_count,
1835 DMA_TO_DEVICE);
Lee Nipper497f2e62010-05-19 19:20:36 +10001836 /*
1837 * data in
1838 */
LEROY Christophe37b5e882017-10-06 15:05:06 +02001839 if (is_sec1 && req_ctx->nbuf) {
LEROY Christophead4cd512018-02-26 17:40:04 +01001840 map_single_talitos_ptr(dev, &desc->ptr[3], req_ctx->nbuf,
1841 req_ctx->buf[req_ctx->buf_idx],
1842 DMA_TO_DEVICE);
LEROY Christophe37b5e882017-10-06 15:05:06 +02001843 } else {
1844 sg_count = talitos_sg_map(dev, req_ctx->psrc, length, edesc,
1845 &desc->ptr[3], sg_count, offset, 0);
1846 if (sg_count > 1)
1847 sync_needed = true;
1848 }
Lee Nipper497f2e62010-05-19 19:20:36 +10001849
1850 /* fifth DWORD empty */
Lee Nipper497f2e62010-05-19 19:20:36 +10001851
1852 /* hash/HMAC out -or- hash context out */
1853 if (req_ctx->last)
1854 map_single_talitos_ptr(dev, &desc->ptr[5],
1855 crypto_ahash_digestsize(tfm),
LEROY Christophea2b35aa2015-04-17 16:31:57 +02001856 areq->result, DMA_FROM_DEVICE);
Lee Nipper497f2e62010-05-19 19:20:36 +10001857 else
LEROY Christophe6a4967c2018-02-26 17:40:06 +01001858 map_single_talitos_ptr_nosync(dev, &desc->ptr[5],
1859 req_ctx->hw_context_size,
1860 req_ctx->hw_context,
1861 DMA_FROM_DEVICE);
Lee Nipper497f2e62010-05-19 19:20:36 +10001862
1863 /* last DWORD empty */
Lee Nipper497f2e62010-05-19 19:20:36 +10001864
LEROY Christophe2d029052015-04-17 16:32:18 +02001865 if (is_sec1 && from_talitos_ptr_len(&desc->ptr[3], true) == 0)
1866 talitos_handle_buggy_hash(ctx, edesc, &desc->ptr[3]);
1867
LEROY Christophe37b5e882017-10-06 15:05:06 +02001868 if (is_sec1 && req_ctx->nbuf && length) {
1869 struct talitos_desc *desc2 = desc + 1;
1870 dma_addr_t next_desc;
1871
1872 memset(desc2, 0, sizeof(*desc2));
1873 desc2->hdr = desc->hdr;
1874 desc2->hdr &= ~DESC_HDR_MODE0_MDEU_INIT;
1875 desc2->hdr1 = desc2->hdr;
1876 desc->hdr &= ~DESC_HDR_MODE0_MDEU_PAD;
1877 desc->hdr |= DESC_HDR_MODE0_MDEU_CONT;
1878 desc->hdr &= ~DESC_HDR_DONE_NOTIFY;
1879
LEROY Christophead4cd512018-02-26 17:40:04 +01001880 if (desc->ptr[1].ptr)
1881 copy_talitos_ptr(&desc2->ptr[1], &desc->ptr[1],
1882 is_sec1);
1883 else
LEROY Christophe6a4967c2018-02-26 17:40:06 +01001884 map_single_talitos_ptr_nosync(dev, &desc2->ptr[1],
1885 req_ctx->hw_context_size,
1886 req_ctx->hw_context,
1887 DMA_TO_DEVICE);
LEROY Christophe37b5e882017-10-06 15:05:06 +02001888 copy_talitos_ptr(&desc2->ptr[2], &desc->ptr[2], is_sec1);
1889 sg_count = talitos_sg_map(dev, req_ctx->psrc, length, edesc,
1890 &desc2->ptr[3], sg_count, offset, 0);
1891 if (sg_count > 1)
1892 sync_needed = true;
1893 copy_talitos_ptr(&desc2->ptr[5], &desc->ptr[5], is_sec1);
1894 if (req_ctx->last)
LEROY Christophe6a4967c2018-02-26 17:40:06 +01001895 map_single_talitos_ptr_nosync(dev, &desc->ptr[5],
1896 req_ctx->hw_context_size,
1897 req_ctx->hw_context,
1898 DMA_FROM_DEVICE);
LEROY Christophe37b5e882017-10-06 15:05:06 +02001899
1900 next_desc = dma_map_single(dev, &desc2->hdr1, TALITOS_DESC_SIZE,
1901 DMA_BIDIRECTIONAL);
1902 desc->next_desc = cpu_to_be32(next_desc);
1903 }
1904
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001905 if (sync_needed)
1906 dma_sync_single_for_device(dev, edesc->dma_link_tbl,
1907 edesc->dma_len, DMA_BIDIRECTIONAL);
1908
Kim Phillips5228f0f2011-07-15 11:21:38 +08001909 ret = talitos_submit(dev, ctx->ch, desc, callback, areq);
Lee Nipper497f2e62010-05-19 19:20:36 +10001910 if (ret != -EINPROGRESS) {
1911 common_nonsnoop_hash_unmap(dev, edesc, areq);
1912 kfree(edesc);
1913 }
1914 return ret;
1915}
1916
1917static struct talitos_edesc *ahash_edesc_alloc(struct ahash_request *areq,
1918 unsigned int nbytes)
1919{
1920 struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
1921 struct talitos_ctx *ctx = crypto_ahash_ctx(tfm);
1922 struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
LEROY Christophe37b5e882017-10-06 15:05:06 +02001923 struct talitos_private *priv = dev_get_drvdata(ctx->dev);
1924 bool is_sec1 = has_ftr_sec1(priv);
1925
1926 if (is_sec1)
1927 nbytes -= req_ctx->nbuf;
Lee Nipper497f2e62010-05-19 19:20:36 +10001928
Herbert Xuaeb4c132015-07-30 17:53:22 +08001929 return talitos_edesc_alloc(ctx->dev, req_ctx->psrc, NULL, NULL, 0,
Horia Geanta62293a32013-11-28 15:11:17 +02001930 nbytes, 0, 0, 0, areq->base.flags, false);
Lee Nipper497f2e62010-05-19 19:20:36 +10001931}
1932
1933static int ahash_init(struct ahash_request *areq)
1934{
1935 struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
LEROY Christophe6a4967c2018-02-26 17:40:06 +01001936 struct talitos_ctx *ctx = crypto_ahash_ctx(tfm);
1937 struct device *dev = ctx->dev;
Lee Nipper497f2e62010-05-19 19:20:36 +10001938 struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
LEROY Christophe49f97832017-10-06 15:05:04 +02001939 unsigned int size;
LEROY Christophe6a4967c2018-02-26 17:40:06 +01001940 dma_addr_t dma;
Lee Nipper497f2e62010-05-19 19:20:36 +10001941
1942 /* Initialize the context */
LEROY Christophe3c0dd192017-10-06 15:05:08 +02001943 req_ctx->buf_idx = 0;
Lee Nipper5e833bc2010-06-16 15:29:15 +10001944 req_ctx->nbuf = 0;
Kim Phillips60f208d2010-05-19 19:21:53 +10001945 req_ctx->first = 1; /* first indicates h/w must init its context */
1946 req_ctx->swinit = 0; /* assume h/w init of context */
LEROY Christophe49f97832017-10-06 15:05:04 +02001947 size = (crypto_ahash_digestsize(tfm) <= SHA256_DIGEST_SIZE)
Lee Nipper497f2e62010-05-19 19:20:36 +10001948 ? TALITOS_MDEU_CONTEXT_SIZE_MD5_SHA1_SHA256
1949 : TALITOS_MDEU_CONTEXT_SIZE_SHA384_SHA512;
LEROY Christophe49f97832017-10-06 15:05:04 +02001950 req_ctx->hw_context_size = size;
Lee Nipper497f2e62010-05-19 19:20:36 +10001951
LEROY Christophe6a4967c2018-02-26 17:40:06 +01001952 dma = dma_map_single(dev, req_ctx->hw_context, req_ctx->hw_context_size,
1953 DMA_TO_DEVICE);
1954 dma_unmap_single(dev, dma, req_ctx->hw_context_size, DMA_TO_DEVICE);
1955
Lee Nipper497f2e62010-05-19 19:20:36 +10001956 return 0;
1957}
1958
Kim Phillips60f208d2010-05-19 19:21:53 +10001959/*
1960 * on h/w without explicit sha224 support, we initialize h/w context
1961 * manually with sha224 constants, and tell it to run sha256.
1962 */
1963static int ahash_init_sha224_swinit(struct ahash_request *areq)
1964{
1965 struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
1966
Kim Phillipsa7524472010-09-23 15:56:38 +08001967 req_ctx->hw_context[0] = SHA224_H0;
1968 req_ctx->hw_context[1] = SHA224_H1;
1969 req_ctx->hw_context[2] = SHA224_H2;
1970 req_ctx->hw_context[3] = SHA224_H3;
1971 req_ctx->hw_context[4] = SHA224_H4;
1972 req_ctx->hw_context[5] = SHA224_H5;
1973 req_ctx->hw_context[6] = SHA224_H6;
1974 req_ctx->hw_context[7] = SHA224_H7;
Kim Phillips60f208d2010-05-19 19:21:53 +10001975
1976 /* init 64-bit count */
1977 req_ctx->hw_context[8] = 0;
1978 req_ctx->hw_context[9] = 0;
1979
LEROY Christophe6a4967c2018-02-26 17:40:06 +01001980 ahash_init(areq);
1981 req_ctx->swinit = 1;/* prevent h/w initting context with sha256 values*/
1982
Kim Phillips60f208d2010-05-19 19:21:53 +10001983 return 0;
1984}
1985
Lee Nipper497f2e62010-05-19 19:20:36 +10001986static int ahash_process_req(struct ahash_request *areq, unsigned int nbytes)
1987{
1988 struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
1989 struct talitos_ctx *ctx = crypto_ahash_ctx(tfm);
1990 struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
1991 struct talitos_edesc *edesc;
1992 unsigned int blocksize =
1993 crypto_tfm_alg_blocksize(crypto_ahash_tfm(tfm));
1994 unsigned int nbytes_to_hash;
1995 unsigned int to_hash_later;
Lee Nipper5e833bc2010-06-16 15:29:15 +10001996 unsigned int nsg;
LABBE Corentin8e409fe2015-11-04 21:13:34 +01001997 int nents;
LEROY Christophe37b5e882017-10-06 15:05:06 +02001998 struct device *dev = ctx->dev;
1999 struct talitos_private *priv = dev_get_drvdata(dev);
2000 bool is_sec1 = has_ftr_sec1(priv);
2001 int offset = 0;
LEROY Christophe3c0dd192017-10-06 15:05:08 +02002002 u8 *ctx_buf = req_ctx->buf[req_ctx->buf_idx];
Lee Nipper497f2e62010-05-19 19:20:36 +10002003
Lee Nipper5e833bc2010-06-16 15:29:15 +10002004 if (!req_ctx->last && (nbytes + req_ctx->nbuf <= blocksize)) {
2005 /* Buffer up to one whole block */
LABBE Corentin8e409fe2015-11-04 21:13:34 +01002006 nents = sg_nents_for_len(areq->src, nbytes);
2007 if (nents < 0) {
2008 dev_err(ctx->dev, "Invalid number of src SG.\n");
2009 return nents;
2010 }
2011 sg_copy_to_buffer(areq->src, nents,
LEROY Christophe3c0dd192017-10-06 15:05:08 +02002012 ctx_buf + req_ctx->nbuf, nbytes);
Lee Nipper5e833bc2010-06-16 15:29:15 +10002013 req_ctx->nbuf += nbytes;
Lee Nipper497f2e62010-05-19 19:20:36 +10002014 return 0;
2015 }
2016
Lee Nipper5e833bc2010-06-16 15:29:15 +10002017 /* At least (blocksize + 1) bytes are available to hash */
2018 nbytes_to_hash = nbytes + req_ctx->nbuf;
2019 to_hash_later = nbytes_to_hash & (blocksize - 1);
2020
2021 if (req_ctx->last)
2022 to_hash_later = 0;
2023 else if (to_hash_later)
2024 /* There is a partial block. Hash the full block(s) now */
2025 nbytes_to_hash -= to_hash_later;
2026 else {
2027 /* Keep one block buffered */
2028 nbytes_to_hash -= blocksize;
2029 to_hash_later = blocksize;
2030 }
2031
2032 /* Chain in any previously buffered data */
LEROY Christophe37b5e882017-10-06 15:05:06 +02002033 if (!is_sec1 && req_ctx->nbuf) {
Lee Nipper5e833bc2010-06-16 15:29:15 +10002034 nsg = (req_ctx->nbuf < nbytes_to_hash) ? 2 : 1;
2035 sg_init_table(req_ctx->bufsl, nsg);
LEROY Christophe3c0dd192017-10-06 15:05:08 +02002036 sg_set_buf(req_ctx->bufsl, ctx_buf, req_ctx->nbuf);
Lee Nipper5e833bc2010-06-16 15:29:15 +10002037 if (nsg > 1)
Dan Williamsc56f6d12015-08-07 18:15:13 +02002038 sg_chain(req_ctx->bufsl, 2, areq->src);
Lee Nipper497f2e62010-05-19 19:20:36 +10002039 req_ctx->psrc = req_ctx->bufsl;
LEROY Christophe37b5e882017-10-06 15:05:06 +02002040 } else if (is_sec1 && req_ctx->nbuf && req_ctx->nbuf < blocksize) {
2041 if (nbytes_to_hash > blocksize)
2042 offset = blocksize - req_ctx->nbuf;
2043 else
2044 offset = nbytes_to_hash - req_ctx->nbuf;
2045 nents = sg_nents_for_len(areq->src, offset);
2046 if (nents < 0) {
2047 dev_err(ctx->dev, "Invalid number of src SG.\n");
2048 return nents;
2049 }
2050 sg_copy_to_buffer(areq->src, nents,
LEROY Christophe3c0dd192017-10-06 15:05:08 +02002051 ctx_buf + req_ctx->nbuf, offset);
LEROY Christophe37b5e882017-10-06 15:05:06 +02002052 req_ctx->nbuf += offset;
2053 req_ctx->psrc = areq->src;
Lee Nipper5e833bc2010-06-16 15:29:15 +10002054 } else
Lee Nipper497f2e62010-05-19 19:20:36 +10002055 req_ctx->psrc = areq->src;
Lee Nipper497f2e62010-05-19 19:20:36 +10002056
Lee Nipper5e833bc2010-06-16 15:29:15 +10002057 if (to_hash_later) {
LABBE Corentin8e409fe2015-11-04 21:13:34 +01002058 nents = sg_nents_for_len(areq->src, nbytes);
2059 if (nents < 0) {
2060 dev_err(ctx->dev, "Invalid number of src SG.\n");
2061 return nents;
2062 }
Akinobu Mitad0525722013-07-08 16:01:55 -07002063 sg_pcopy_to_buffer(areq->src, nents,
LEROY Christophe3c0dd192017-10-06 15:05:08 +02002064 req_ctx->buf[(req_ctx->buf_idx + 1) & 1],
Lee Nipper5e833bc2010-06-16 15:29:15 +10002065 to_hash_later,
2066 nbytes - to_hash_later);
Lee Nipper497f2e62010-05-19 19:20:36 +10002067 }
Lee Nipper5e833bc2010-06-16 15:29:15 +10002068 req_ctx->to_hash_later = to_hash_later;
Lee Nipper497f2e62010-05-19 19:20:36 +10002069
Lee Nipper5e833bc2010-06-16 15:29:15 +10002070 /* Allocate extended descriptor */
Lee Nipper497f2e62010-05-19 19:20:36 +10002071 edesc = ahash_edesc_alloc(areq, nbytes_to_hash);
2072 if (IS_ERR(edesc))
2073 return PTR_ERR(edesc);
2074
2075 edesc->desc.hdr = ctx->desc_hdr_template;
2076
2077 /* On last one, request SEC to pad; otherwise continue */
2078 if (req_ctx->last)
2079 edesc->desc.hdr |= DESC_HDR_MODE0_MDEU_PAD;
2080 else
2081 edesc->desc.hdr |= DESC_HDR_MODE0_MDEU_CONT;
2082
Kim Phillips60f208d2010-05-19 19:21:53 +10002083 /* request SEC to INIT hash. */
2084 if (req_ctx->first && !req_ctx->swinit)
Lee Nipper497f2e62010-05-19 19:20:36 +10002085 edesc->desc.hdr |= DESC_HDR_MODE0_MDEU_INIT;
2086
2087 /* When the tfm context has a keylen, it's an HMAC.
2088 * A first or last (ie. not middle) descriptor must request HMAC.
2089 */
2090 if (ctx->keylen && (req_ctx->first || req_ctx->last))
2091 edesc->desc.hdr |= DESC_HDR_MODE0_MDEU_HMAC;
2092
LEROY Christophe37b5e882017-10-06 15:05:06 +02002093 return common_nonsnoop_hash(edesc, areq, nbytes_to_hash, offset,
Lee Nipper497f2e62010-05-19 19:20:36 +10002094 ahash_done);
2095}
2096
2097static int ahash_update(struct ahash_request *areq)
2098{
2099 struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
2100
2101 req_ctx->last = 0;
2102
2103 return ahash_process_req(areq, areq->nbytes);
2104}
2105
2106static int ahash_final(struct ahash_request *areq)
2107{
2108 struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
2109
2110 req_ctx->last = 1;
2111
2112 return ahash_process_req(areq, 0);
2113}
2114
2115static int ahash_finup(struct ahash_request *areq)
2116{
2117 struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
2118
2119 req_ctx->last = 1;
2120
2121 return ahash_process_req(areq, areq->nbytes);
2122}
2123
2124static int ahash_digest(struct ahash_request *areq)
2125{
2126 struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
Kim Phillips60f208d2010-05-19 19:21:53 +10002127 struct crypto_ahash *ahash = crypto_ahash_reqtfm(areq);
Lee Nipper497f2e62010-05-19 19:20:36 +10002128
Kim Phillips60f208d2010-05-19 19:21:53 +10002129 ahash->init(areq);
Lee Nipper497f2e62010-05-19 19:20:36 +10002130 req_ctx->last = 1;
2131
2132 return ahash_process_req(areq, areq->nbytes);
2133}
2134
Horia Geant?3639ca82016-04-21 19:24:55 +03002135static int ahash_export(struct ahash_request *areq, void *out)
2136{
2137 struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
2138 struct talitos_export_state *export = out;
LEROY Christophe6a4967c2018-02-26 17:40:06 +01002139 struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
2140 struct talitos_ctx *ctx = crypto_ahash_ctx(tfm);
2141 struct device *dev = ctx->dev;
2142 dma_addr_t dma;
2143
2144 dma = dma_map_single(dev, req_ctx->hw_context, req_ctx->hw_context_size,
2145 DMA_FROM_DEVICE);
2146 dma_unmap_single(dev, dma, req_ctx->hw_context_size, DMA_FROM_DEVICE);
Horia Geant?3639ca82016-04-21 19:24:55 +03002147
2148 memcpy(export->hw_context, req_ctx->hw_context,
2149 req_ctx->hw_context_size);
LEROY Christophe3c0dd192017-10-06 15:05:08 +02002150 memcpy(export->buf, req_ctx->buf[req_ctx->buf_idx], req_ctx->nbuf);
Horia Geant?3639ca82016-04-21 19:24:55 +03002151 export->swinit = req_ctx->swinit;
2152 export->first = req_ctx->first;
2153 export->last = req_ctx->last;
2154 export->to_hash_later = req_ctx->to_hash_later;
2155 export->nbuf = req_ctx->nbuf;
2156
2157 return 0;
2158}
2159
2160static int ahash_import(struct ahash_request *areq, const void *in)
2161{
2162 struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
2163 struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
LEROY Christophe6a4967c2018-02-26 17:40:06 +01002164 struct talitos_ctx *ctx = crypto_ahash_ctx(tfm);
2165 struct device *dev = ctx->dev;
Horia Geant?3639ca82016-04-21 19:24:55 +03002166 const struct talitos_export_state *export = in;
LEROY Christophe49f97832017-10-06 15:05:04 +02002167 unsigned int size;
LEROY Christophe6a4967c2018-02-26 17:40:06 +01002168 dma_addr_t dma;
Horia Geant?3639ca82016-04-21 19:24:55 +03002169
2170 memset(req_ctx, 0, sizeof(*req_ctx));
LEROY Christophe49f97832017-10-06 15:05:04 +02002171 size = (crypto_ahash_digestsize(tfm) <= SHA256_DIGEST_SIZE)
Horia Geant?3639ca82016-04-21 19:24:55 +03002172 ? TALITOS_MDEU_CONTEXT_SIZE_MD5_SHA1_SHA256
2173 : TALITOS_MDEU_CONTEXT_SIZE_SHA384_SHA512;
LEROY Christophe49f97832017-10-06 15:05:04 +02002174 req_ctx->hw_context_size = size;
LEROY Christophe49f97832017-10-06 15:05:04 +02002175 memcpy(req_ctx->hw_context, export->hw_context, size);
LEROY Christophe3c0dd192017-10-06 15:05:08 +02002176 memcpy(req_ctx->buf[0], export->buf, export->nbuf);
Horia Geant?3639ca82016-04-21 19:24:55 +03002177 req_ctx->swinit = export->swinit;
2178 req_ctx->first = export->first;
2179 req_ctx->last = export->last;
2180 req_ctx->to_hash_later = export->to_hash_later;
2181 req_ctx->nbuf = export->nbuf;
2182
LEROY Christophe6a4967c2018-02-26 17:40:06 +01002183 dma = dma_map_single(dev, req_ctx->hw_context, req_ctx->hw_context_size,
2184 DMA_TO_DEVICE);
2185 dma_unmap_single(dev, dma, req_ctx->hw_context_size, DMA_TO_DEVICE);
2186
Horia Geant?3639ca82016-04-21 19:24:55 +03002187 return 0;
2188}
2189
Lee Nipper79b3a412011-11-21 16:13:25 +08002190static int keyhash(struct crypto_ahash *tfm, const u8 *key, unsigned int keylen,
2191 u8 *hash)
2192{
2193 struct talitos_ctx *ctx = crypto_tfm_ctx(crypto_ahash_tfm(tfm));
2194
2195 struct scatterlist sg[1];
2196 struct ahash_request *req;
Gilad Ben-Yosseff1c90ac32017-10-18 08:00:49 +01002197 struct crypto_wait wait;
Lee Nipper79b3a412011-11-21 16:13:25 +08002198 int ret;
2199
Gilad Ben-Yosseff1c90ac32017-10-18 08:00:49 +01002200 crypto_init_wait(&wait);
Lee Nipper79b3a412011-11-21 16:13:25 +08002201
2202 req = ahash_request_alloc(tfm, GFP_KERNEL);
2203 if (!req)
2204 return -ENOMEM;
2205
2206 /* Keep tfm keylen == 0 during hash of the long key */
2207 ctx->keylen = 0;
2208 ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
Gilad Ben-Yosseff1c90ac32017-10-18 08:00:49 +01002209 crypto_req_done, &wait);
Lee Nipper79b3a412011-11-21 16:13:25 +08002210
2211 sg_init_one(&sg[0], key, keylen);
2212
2213 ahash_request_set_crypt(req, sg, hash, keylen);
Gilad Ben-Yosseff1c90ac32017-10-18 08:00:49 +01002214 ret = crypto_wait_req(crypto_ahash_digest(req), &wait);
2215
Lee Nipper79b3a412011-11-21 16:13:25 +08002216 ahash_request_free(req);
2217
2218 return ret;
2219}
2220
2221static int ahash_setkey(struct crypto_ahash *tfm, const u8 *key,
2222 unsigned int keylen)
2223{
2224 struct talitos_ctx *ctx = crypto_tfm_ctx(crypto_ahash_tfm(tfm));
LEROY Christophe2e13ce02017-10-06 15:05:02 +02002225 struct device *dev = ctx->dev;
Lee Nipper79b3a412011-11-21 16:13:25 +08002226 unsigned int blocksize =
2227 crypto_tfm_alg_blocksize(crypto_ahash_tfm(tfm));
2228 unsigned int digestsize = crypto_ahash_digestsize(tfm);
2229 unsigned int keysize = keylen;
2230 u8 hash[SHA512_DIGEST_SIZE];
2231 int ret;
2232
2233 if (keylen <= blocksize)
2234 memcpy(ctx->key, key, keysize);
2235 else {
2236 /* Must get the hash of the long key */
2237 ret = keyhash(tfm, key, keylen, hash);
2238
2239 if (ret) {
2240 crypto_ahash_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN);
2241 return -EINVAL;
2242 }
2243
2244 keysize = digestsize;
2245 memcpy(ctx->key, hash, digestsize);
2246 }
2247
LEROY Christophe2e13ce02017-10-06 15:05:02 +02002248 if (ctx->keylen)
2249 dma_unmap_single(dev, ctx->dma_key, ctx->keylen, DMA_TO_DEVICE);
2250
Lee Nipper79b3a412011-11-21 16:13:25 +08002251 ctx->keylen = keysize;
LEROY Christophe2e13ce02017-10-06 15:05:02 +02002252 ctx->dma_key = dma_map_single(dev, ctx->key, keysize, DMA_TO_DEVICE);
Lee Nipper79b3a412011-11-21 16:13:25 +08002253
2254 return 0;
2255}
2256
2257
Kim Phillips9c4a7962008-06-23 19:50:15 +08002258struct talitos_alg_template {
Lee Nipperd5e4aae2010-05-19 19:18:38 +10002259 u32 type;
LEROY Christopheb0057762016-06-06 13:20:44 +02002260 u32 priority;
Lee Nipperd5e4aae2010-05-19 19:18:38 +10002261 union {
2262 struct crypto_alg crypto;
Lee Nipperacbf7c622010-05-19 19:19:33 +10002263 struct ahash_alg hash;
Herbert Xuaeb4c132015-07-30 17:53:22 +08002264 struct aead_alg aead;
Lee Nipperd5e4aae2010-05-19 19:18:38 +10002265 } alg;
Kim Phillips9c4a7962008-06-23 19:50:15 +08002266 __be32 desc_hdr_template;
2267};
2268
2269static struct talitos_alg_template driver_algs[] = {
Horia Geanta991155b2013-03-20 16:31:38 +02002270 /* AEAD algorithms. These use a single-pass ipsec_esp descriptor */
Lee Nipperd5e4aae2010-05-19 19:18:38 +10002271 { .type = CRYPTO_ALG_TYPE_AEAD,
Herbert Xuaeb4c132015-07-30 17:53:22 +08002272 .alg.aead = {
2273 .base = {
2274 .cra_name = "authenc(hmac(sha1),cbc(aes))",
2275 .cra_driver_name = "authenc-hmac-sha1-"
2276 "cbc-aes-talitos",
2277 .cra_blocksize = AES_BLOCK_SIZE,
2278 .cra_flags = CRYPTO_ALG_ASYNC,
2279 },
2280 .ivsize = AES_BLOCK_SIZE,
2281 .maxauthsize = SHA1_DIGEST_SIZE,
Lee Nipper56af8cd2009-03-29 15:50:50 +08002282 },
Kim Phillips9c4a7962008-06-23 19:50:15 +08002283 .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
2284 DESC_HDR_SEL0_AESU |
2285 DESC_HDR_MODE0_AESU_CBC |
2286 DESC_HDR_SEL1_MDEUA |
2287 DESC_HDR_MODE1_MDEU_INIT |
2288 DESC_HDR_MODE1_MDEU_PAD |
2289 DESC_HDR_MODE1_MDEU_SHA1_HMAC,
Lee Nipper70bcaca2008-07-03 19:08:46 +08002290 },
Lee Nipperd5e4aae2010-05-19 19:18:38 +10002291 { .type = CRYPTO_ALG_TYPE_AEAD,
LEROY Christophe7405c8d2016-06-06 13:20:46 +02002292 .priority = TALITOS_CRA_PRIORITY_AEAD_HSNA,
2293 .alg.aead = {
2294 .base = {
2295 .cra_name = "authenc(hmac(sha1),cbc(aes))",
2296 .cra_driver_name = "authenc-hmac-sha1-"
2297 "cbc-aes-talitos",
2298 .cra_blocksize = AES_BLOCK_SIZE,
2299 .cra_flags = CRYPTO_ALG_ASYNC,
2300 },
2301 .ivsize = AES_BLOCK_SIZE,
2302 .maxauthsize = SHA1_DIGEST_SIZE,
2303 },
2304 .desc_hdr_template = DESC_HDR_TYPE_HMAC_SNOOP_NO_AFEU |
2305 DESC_HDR_SEL0_AESU |
2306 DESC_HDR_MODE0_AESU_CBC |
2307 DESC_HDR_SEL1_MDEUA |
2308 DESC_HDR_MODE1_MDEU_INIT |
2309 DESC_HDR_MODE1_MDEU_PAD |
2310 DESC_HDR_MODE1_MDEU_SHA1_HMAC,
2311 },
2312 { .type = CRYPTO_ALG_TYPE_AEAD,
Herbert Xuaeb4c132015-07-30 17:53:22 +08002313 .alg.aead = {
2314 .base = {
2315 .cra_name = "authenc(hmac(sha1),"
2316 "cbc(des3_ede))",
2317 .cra_driver_name = "authenc-hmac-sha1-"
2318 "cbc-3des-talitos",
2319 .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2320 .cra_flags = CRYPTO_ALG_ASYNC,
2321 },
2322 .ivsize = DES3_EDE_BLOCK_SIZE,
2323 .maxauthsize = SHA1_DIGEST_SIZE,
Lee Nipper56af8cd2009-03-29 15:50:50 +08002324 },
Lee Nipper70bcaca2008-07-03 19:08:46 +08002325 .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
2326 DESC_HDR_SEL0_DEU |
2327 DESC_HDR_MODE0_DEU_CBC |
2328 DESC_HDR_MODE0_DEU_3DES |
2329 DESC_HDR_SEL1_MDEUA |
2330 DESC_HDR_MODE1_MDEU_INIT |
2331 DESC_HDR_MODE1_MDEU_PAD |
2332 DESC_HDR_MODE1_MDEU_SHA1_HMAC,
Lee Nipper3952f172008-07-10 18:29:18 +08002333 },
LEROY Christophe7405c8d2016-06-06 13:20:46 +02002334 { .type = CRYPTO_ALG_TYPE_AEAD,
2335 .priority = TALITOS_CRA_PRIORITY_AEAD_HSNA,
2336 .alg.aead = {
2337 .base = {
2338 .cra_name = "authenc(hmac(sha1),"
2339 "cbc(des3_ede))",
2340 .cra_driver_name = "authenc-hmac-sha1-"
2341 "cbc-3des-talitos",
2342 .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2343 .cra_flags = CRYPTO_ALG_ASYNC,
2344 },
2345 .ivsize = DES3_EDE_BLOCK_SIZE,
2346 .maxauthsize = SHA1_DIGEST_SIZE,
2347 },
2348 .desc_hdr_template = DESC_HDR_TYPE_HMAC_SNOOP_NO_AFEU |
2349 DESC_HDR_SEL0_DEU |
2350 DESC_HDR_MODE0_DEU_CBC |
2351 DESC_HDR_MODE0_DEU_3DES |
2352 DESC_HDR_SEL1_MDEUA |
2353 DESC_HDR_MODE1_MDEU_INIT |
2354 DESC_HDR_MODE1_MDEU_PAD |
2355 DESC_HDR_MODE1_MDEU_SHA1_HMAC,
2356 },
Horia Geanta357fb602012-07-03 19:16:53 +03002357 { .type = CRYPTO_ALG_TYPE_AEAD,
Herbert Xuaeb4c132015-07-30 17:53:22 +08002358 .alg.aead = {
2359 .base = {
2360 .cra_name = "authenc(hmac(sha224),cbc(aes))",
2361 .cra_driver_name = "authenc-hmac-sha224-"
2362 "cbc-aes-talitos",
2363 .cra_blocksize = AES_BLOCK_SIZE,
2364 .cra_flags = CRYPTO_ALG_ASYNC,
2365 },
2366 .ivsize = AES_BLOCK_SIZE,
2367 .maxauthsize = SHA224_DIGEST_SIZE,
Horia Geanta357fb602012-07-03 19:16:53 +03002368 },
2369 .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
2370 DESC_HDR_SEL0_AESU |
2371 DESC_HDR_MODE0_AESU_CBC |
2372 DESC_HDR_SEL1_MDEUA |
2373 DESC_HDR_MODE1_MDEU_INIT |
2374 DESC_HDR_MODE1_MDEU_PAD |
2375 DESC_HDR_MODE1_MDEU_SHA224_HMAC,
2376 },
LEROY Christophe7405c8d2016-06-06 13:20:46 +02002377 { .type = CRYPTO_ALG_TYPE_AEAD,
2378 .priority = TALITOS_CRA_PRIORITY_AEAD_HSNA,
2379 .alg.aead = {
2380 .base = {
2381 .cra_name = "authenc(hmac(sha224),cbc(aes))",
2382 .cra_driver_name = "authenc-hmac-sha224-"
2383 "cbc-aes-talitos",
2384 .cra_blocksize = AES_BLOCK_SIZE,
2385 .cra_flags = CRYPTO_ALG_ASYNC,
2386 },
2387 .ivsize = AES_BLOCK_SIZE,
2388 .maxauthsize = SHA224_DIGEST_SIZE,
2389 },
2390 .desc_hdr_template = DESC_HDR_TYPE_HMAC_SNOOP_NO_AFEU |
2391 DESC_HDR_SEL0_AESU |
2392 DESC_HDR_MODE0_AESU_CBC |
2393 DESC_HDR_SEL1_MDEUA |
2394 DESC_HDR_MODE1_MDEU_INIT |
2395 DESC_HDR_MODE1_MDEU_PAD |
2396 DESC_HDR_MODE1_MDEU_SHA224_HMAC,
2397 },
Horia Geanta357fb602012-07-03 19:16:53 +03002398 { .type = CRYPTO_ALG_TYPE_AEAD,
Herbert Xuaeb4c132015-07-30 17:53:22 +08002399 .alg.aead = {
2400 .base = {
2401 .cra_name = "authenc(hmac(sha224),"
2402 "cbc(des3_ede))",
2403 .cra_driver_name = "authenc-hmac-sha224-"
2404 "cbc-3des-talitos",
2405 .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2406 .cra_flags = CRYPTO_ALG_ASYNC,
2407 },
2408 .ivsize = DES3_EDE_BLOCK_SIZE,
2409 .maxauthsize = SHA224_DIGEST_SIZE,
Horia Geanta357fb602012-07-03 19:16:53 +03002410 },
2411 .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
2412 DESC_HDR_SEL0_DEU |
2413 DESC_HDR_MODE0_DEU_CBC |
2414 DESC_HDR_MODE0_DEU_3DES |
2415 DESC_HDR_SEL1_MDEUA |
2416 DESC_HDR_MODE1_MDEU_INIT |
2417 DESC_HDR_MODE1_MDEU_PAD |
2418 DESC_HDR_MODE1_MDEU_SHA224_HMAC,
2419 },
Lee Nipperd5e4aae2010-05-19 19:18:38 +10002420 { .type = CRYPTO_ALG_TYPE_AEAD,
LEROY Christophe7405c8d2016-06-06 13:20:46 +02002421 .priority = TALITOS_CRA_PRIORITY_AEAD_HSNA,
2422 .alg.aead = {
2423 .base = {
2424 .cra_name = "authenc(hmac(sha224),"
2425 "cbc(des3_ede))",
2426 .cra_driver_name = "authenc-hmac-sha224-"
2427 "cbc-3des-talitos",
2428 .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2429 .cra_flags = CRYPTO_ALG_ASYNC,
2430 },
2431 .ivsize = DES3_EDE_BLOCK_SIZE,
2432 .maxauthsize = SHA224_DIGEST_SIZE,
2433 },
2434 .desc_hdr_template = DESC_HDR_TYPE_HMAC_SNOOP_NO_AFEU |
2435 DESC_HDR_SEL0_DEU |
2436 DESC_HDR_MODE0_DEU_CBC |
2437 DESC_HDR_MODE0_DEU_3DES |
2438 DESC_HDR_SEL1_MDEUA |
2439 DESC_HDR_MODE1_MDEU_INIT |
2440 DESC_HDR_MODE1_MDEU_PAD |
2441 DESC_HDR_MODE1_MDEU_SHA224_HMAC,
2442 },
2443 { .type = CRYPTO_ALG_TYPE_AEAD,
Herbert Xuaeb4c132015-07-30 17:53:22 +08002444 .alg.aead = {
2445 .base = {
2446 .cra_name = "authenc(hmac(sha256),cbc(aes))",
2447 .cra_driver_name = "authenc-hmac-sha256-"
2448 "cbc-aes-talitos",
2449 .cra_blocksize = AES_BLOCK_SIZE,
2450 .cra_flags = CRYPTO_ALG_ASYNC,
2451 },
2452 .ivsize = AES_BLOCK_SIZE,
2453 .maxauthsize = SHA256_DIGEST_SIZE,
Lee Nipper56af8cd2009-03-29 15:50:50 +08002454 },
Lee Nipper3952f172008-07-10 18:29:18 +08002455 .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
2456 DESC_HDR_SEL0_AESU |
2457 DESC_HDR_MODE0_AESU_CBC |
2458 DESC_HDR_SEL1_MDEUA |
2459 DESC_HDR_MODE1_MDEU_INIT |
2460 DESC_HDR_MODE1_MDEU_PAD |
2461 DESC_HDR_MODE1_MDEU_SHA256_HMAC,
2462 },
Lee Nipperd5e4aae2010-05-19 19:18:38 +10002463 { .type = CRYPTO_ALG_TYPE_AEAD,
LEROY Christophe7405c8d2016-06-06 13:20:46 +02002464 .priority = TALITOS_CRA_PRIORITY_AEAD_HSNA,
2465 .alg.aead = {
2466 .base = {
2467 .cra_name = "authenc(hmac(sha256),cbc(aes))",
2468 .cra_driver_name = "authenc-hmac-sha256-"
2469 "cbc-aes-talitos",
2470 .cra_blocksize = AES_BLOCK_SIZE,
2471 .cra_flags = CRYPTO_ALG_ASYNC,
2472 },
2473 .ivsize = AES_BLOCK_SIZE,
2474 .maxauthsize = SHA256_DIGEST_SIZE,
2475 },
2476 .desc_hdr_template = DESC_HDR_TYPE_HMAC_SNOOP_NO_AFEU |
2477 DESC_HDR_SEL0_AESU |
2478 DESC_HDR_MODE0_AESU_CBC |
2479 DESC_HDR_SEL1_MDEUA |
2480 DESC_HDR_MODE1_MDEU_INIT |
2481 DESC_HDR_MODE1_MDEU_PAD |
2482 DESC_HDR_MODE1_MDEU_SHA256_HMAC,
2483 },
2484 { .type = CRYPTO_ALG_TYPE_AEAD,
Herbert Xuaeb4c132015-07-30 17:53:22 +08002485 .alg.aead = {
2486 .base = {
2487 .cra_name = "authenc(hmac(sha256),"
2488 "cbc(des3_ede))",
2489 .cra_driver_name = "authenc-hmac-sha256-"
2490 "cbc-3des-talitos",
2491 .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2492 .cra_flags = CRYPTO_ALG_ASYNC,
2493 },
2494 .ivsize = DES3_EDE_BLOCK_SIZE,
2495 .maxauthsize = SHA256_DIGEST_SIZE,
Lee Nipper56af8cd2009-03-29 15:50:50 +08002496 },
Lee Nipper3952f172008-07-10 18:29:18 +08002497 .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
2498 DESC_HDR_SEL0_DEU |
2499 DESC_HDR_MODE0_DEU_CBC |
2500 DESC_HDR_MODE0_DEU_3DES |
2501 DESC_HDR_SEL1_MDEUA |
2502 DESC_HDR_MODE1_MDEU_INIT |
2503 DESC_HDR_MODE1_MDEU_PAD |
2504 DESC_HDR_MODE1_MDEU_SHA256_HMAC,
2505 },
Lee Nipperd5e4aae2010-05-19 19:18:38 +10002506 { .type = CRYPTO_ALG_TYPE_AEAD,
LEROY Christophe7405c8d2016-06-06 13:20:46 +02002507 .priority = TALITOS_CRA_PRIORITY_AEAD_HSNA,
2508 .alg.aead = {
2509 .base = {
2510 .cra_name = "authenc(hmac(sha256),"
2511 "cbc(des3_ede))",
2512 .cra_driver_name = "authenc-hmac-sha256-"
2513 "cbc-3des-talitos",
2514 .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2515 .cra_flags = CRYPTO_ALG_ASYNC,
2516 },
2517 .ivsize = DES3_EDE_BLOCK_SIZE,
2518 .maxauthsize = SHA256_DIGEST_SIZE,
2519 },
2520 .desc_hdr_template = DESC_HDR_TYPE_HMAC_SNOOP_NO_AFEU |
2521 DESC_HDR_SEL0_DEU |
2522 DESC_HDR_MODE0_DEU_CBC |
2523 DESC_HDR_MODE0_DEU_3DES |
2524 DESC_HDR_SEL1_MDEUA |
2525 DESC_HDR_MODE1_MDEU_INIT |
2526 DESC_HDR_MODE1_MDEU_PAD |
2527 DESC_HDR_MODE1_MDEU_SHA256_HMAC,
2528 },
2529 { .type = CRYPTO_ALG_TYPE_AEAD,
Herbert Xuaeb4c132015-07-30 17:53:22 +08002530 .alg.aead = {
2531 .base = {
2532 .cra_name = "authenc(hmac(sha384),cbc(aes))",
2533 .cra_driver_name = "authenc-hmac-sha384-"
2534 "cbc-aes-talitos",
2535 .cra_blocksize = AES_BLOCK_SIZE,
2536 .cra_flags = CRYPTO_ALG_ASYNC,
2537 },
2538 .ivsize = AES_BLOCK_SIZE,
2539 .maxauthsize = SHA384_DIGEST_SIZE,
Horia Geanta357fb602012-07-03 19:16:53 +03002540 },
2541 .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
2542 DESC_HDR_SEL0_AESU |
2543 DESC_HDR_MODE0_AESU_CBC |
2544 DESC_HDR_SEL1_MDEUB |
2545 DESC_HDR_MODE1_MDEU_INIT |
2546 DESC_HDR_MODE1_MDEU_PAD |
2547 DESC_HDR_MODE1_MDEUB_SHA384_HMAC,
2548 },
2549 { .type = CRYPTO_ALG_TYPE_AEAD,
Herbert Xuaeb4c132015-07-30 17:53:22 +08002550 .alg.aead = {
2551 .base = {
2552 .cra_name = "authenc(hmac(sha384),"
2553 "cbc(des3_ede))",
2554 .cra_driver_name = "authenc-hmac-sha384-"
2555 "cbc-3des-talitos",
2556 .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2557 .cra_flags = CRYPTO_ALG_ASYNC,
2558 },
2559 .ivsize = DES3_EDE_BLOCK_SIZE,
2560 .maxauthsize = SHA384_DIGEST_SIZE,
Horia Geanta357fb602012-07-03 19:16:53 +03002561 },
2562 .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
2563 DESC_HDR_SEL0_DEU |
2564 DESC_HDR_MODE0_DEU_CBC |
2565 DESC_HDR_MODE0_DEU_3DES |
2566 DESC_HDR_SEL1_MDEUB |
2567 DESC_HDR_MODE1_MDEU_INIT |
2568 DESC_HDR_MODE1_MDEU_PAD |
2569 DESC_HDR_MODE1_MDEUB_SHA384_HMAC,
2570 },
2571 { .type = CRYPTO_ALG_TYPE_AEAD,
Herbert Xuaeb4c132015-07-30 17:53:22 +08002572 .alg.aead = {
2573 .base = {
2574 .cra_name = "authenc(hmac(sha512),cbc(aes))",
2575 .cra_driver_name = "authenc-hmac-sha512-"
2576 "cbc-aes-talitos",
2577 .cra_blocksize = AES_BLOCK_SIZE,
2578 .cra_flags = CRYPTO_ALG_ASYNC,
2579 },
2580 .ivsize = AES_BLOCK_SIZE,
2581 .maxauthsize = SHA512_DIGEST_SIZE,
Horia Geanta357fb602012-07-03 19:16:53 +03002582 },
2583 .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
2584 DESC_HDR_SEL0_AESU |
2585 DESC_HDR_MODE0_AESU_CBC |
2586 DESC_HDR_SEL1_MDEUB |
2587 DESC_HDR_MODE1_MDEU_INIT |
2588 DESC_HDR_MODE1_MDEU_PAD |
2589 DESC_HDR_MODE1_MDEUB_SHA512_HMAC,
2590 },
2591 { .type = CRYPTO_ALG_TYPE_AEAD,
Herbert Xuaeb4c132015-07-30 17:53:22 +08002592 .alg.aead = {
2593 .base = {
2594 .cra_name = "authenc(hmac(sha512),"
2595 "cbc(des3_ede))",
2596 .cra_driver_name = "authenc-hmac-sha512-"
2597 "cbc-3des-talitos",
2598 .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2599 .cra_flags = CRYPTO_ALG_ASYNC,
2600 },
2601 .ivsize = DES3_EDE_BLOCK_SIZE,
2602 .maxauthsize = SHA512_DIGEST_SIZE,
Horia Geanta357fb602012-07-03 19:16:53 +03002603 },
2604 .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
2605 DESC_HDR_SEL0_DEU |
2606 DESC_HDR_MODE0_DEU_CBC |
2607 DESC_HDR_MODE0_DEU_3DES |
2608 DESC_HDR_SEL1_MDEUB |
2609 DESC_HDR_MODE1_MDEU_INIT |
2610 DESC_HDR_MODE1_MDEU_PAD |
2611 DESC_HDR_MODE1_MDEUB_SHA512_HMAC,
2612 },
2613 { .type = CRYPTO_ALG_TYPE_AEAD,
Herbert Xuaeb4c132015-07-30 17:53:22 +08002614 .alg.aead = {
2615 .base = {
2616 .cra_name = "authenc(hmac(md5),cbc(aes))",
2617 .cra_driver_name = "authenc-hmac-md5-"
2618 "cbc-aes-talitos",
2619 .cra_blocksize = AES_BLOCK_SIZE,
2620 .cra_flags = CRYPTO_ALG_ASYNC,
2621 },
2622 .ivsize = AES_BLOCK_SIZE,
2623 .maxauthsize = MD5_DIGEST_SIZE,
Lee Nipper56af8cd2009-03-29 15:50:50 +08002624 },
Lee Nipper3952f172008-07-10 18:29:18 +08002625 .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
2626 DESC_HDR_SEL0_AESU |
2627 DESC_HDR_MODE0_AESU_CBC |
2628 DESC_HDR_SEL1_MDEUA |
2629 DESC_HDR_MODE1_MDEU_INIT |
2630 DESC_HDR_MODE1_MDEU_PAD |
2631 DESC_HDR_MODE1_MDEU_MD5_HMAC,
2632 },
Lee Nipperd5e4aae2010-05-19 19:18:38 +10002633 { .type = CRYPTO_ALG_TYPE_AEAD,
LEROY Christophe7405c8d2016-06-06 13:20:46 +02002634 .priority = TALITOS_CRA_PRIORITY_AEAD_HSNA,
2635 .alg.aead = {
2636 .base = {
2637 .cra_name = "authenc(hmac(md5),cbc(aes))",
2638 .cra_driver_name = "authenc-hmac-md5-"
2639 "cbc-aes-talitos",
2640 .cra_blocksize = AES_BLOCK_SIZE,
2641 .cra_flags = CRYPTO_ALG_ASYNC,
2642 },
2643 .ivsize = AES_BLOCK_SIZE,
2644 .maxauthsize = MD5_DIGEST_SIZE,
2645 },
2646 .desc_hdr_template = DESC_HDR_TYPE_HMAC_SNOOP_NO_AFEU |
2647 DESC_HDR_SEL0_AESU |
2648 DESC_HDR_MODE0_AESU_CBC |
2649 DESC_HDR_SEL1_MDEUA |
2650 DESC_HDR_MODE1_MDEU_INIT |
2651 DESC_HDR_MODE1_MDEU_PAD |
2652 DESC_HDR_MODE1_MDEU_MD5_HMAC,
2653 },
2654 { .type = CRYPTO_ALG_TYPE_AEAD,
Herbert Xuaeb4c132015-07-30 17:53:22 +08002655 .alg.aead = {
2656 .base = {
2657 .cra_name = "authenc(hmac(md5),cbc(des3_ede))",
2658 .cra_driver_name = "authenc-hmac-md5-"
2659 "cbc-3des-talitos",
2660 .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2661 .cra_flags = CRYPTO_ALG_ASYNC,
2662 },
2663 .ivsize = DES3_EDE_BLOCK_SIZE,
2664 .maxauthsize = MD5_DIGEST_SIZE,
Lee Nipper56af8cd2009-03-29 15:50:50 +08002665 },
Lee Nipper3952f172008-07-10 18:29:18 +08002666 .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
2667 DESC_HDR_SEL0_DEU |
2668 DESC_HDR_MODE0_DEU_CBC |
2669 DESC_HDR_MODE0_DEU_3DES |
2670 DESC_HDR_SEL1_MDEUA |
2671 DESC_HDR_MODE1_MDEU_INIT |
2672 DESC_HDR_MODE1_MDEU_PAD |
2673 DESC_HDR_MODE1_MDEU_MD5_HMAC,
Lee Nipper4de9d0b2009-03-29 15:52:32 +08002674 },
LEROY Christophe7405c8d2016-06-06 13:20:46 +02002675 { .type = CRYPTO_ALG_TYPE_AEAD,
2676 .priority = TALITOS_CRA_PRIORITY_AEAD_HSNA,
2677 .alg.aead = {
2678 .base = {
2679 .cra_name = "authenc(hmac(md5),cbc(des3_ede))",
2680 .cra_driver_name = "authenc-hmac-md5-"
2681 "cbc-3des-talitos",
2682 .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2683 .cra_flags = CRYPTO_ALG_ASYNC,
2684 },
2685 .ivsize = DES3_EDE_BLOCK_SIZE,
2686 .maxauthsize = MD5_DIGEST_SIZE,
2687 },
2688 .desc_hdr_template = DESC_HDR_TYPE_HMAC_SNOOP_NO_AFEU |
2689 DESC_HDR_SEL0_DEU |
2690 DESC_HDR_MODE0_DEU_CBC |
2691 DESC_HDR_MODE0_DEU_3DES |
2692 DESC_HDR_SEL1_MDEUA |
2693 DESC_HDR_MODE1_MDEU_INIT |
2694 DESC_HDR_MODE1_MDEU_PAD |
2695 DESC_HDR_MODE1_MDEU_MD5_HMAC,
2696 },
Lee Nipper4de9d0b2009-03-29 15:52:32 +08002697 /* ABLKCIPHER algorithms. */
Lee Nipperd5e4aae2010-05-19 19:18:38 +10002698 { .type = CRYPTO_ALG_TYPE_ABLKCIPHER,
2699 .alg.crypto = {
LEROY Christophe5e75ae12015-12-01 12:44:15 +01002700 .cra_name = "ecb(aes)",
2701 .cra_driver_name = "ecb-aes-talitos",
2702 .cra_blocksize = AES_BLOCK_SIZE,
2703 .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER |
2704 CRYPTO_ALG_ASYNC,
2705 .cra_ablkcipher = {
2706 .min_keysize = AES_MIN_KEY_SIZE,
2707 .max_keysize = AES_MAX_KEY_SIZE,
2708 .ivsize = AES_BLOCK_SIZE,
2709 }
2710 },
2711 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2712 DESC_HDR_SEL0_AESU,
2713 },
2714 { .type = CRYPTO_ALG_TYPE_ABLKCIPHER,
2715 .alg.crypto = {
Lee Nipper4de9d0b2009-03-29 15:52:32 +08002716 .cra_name = "cbc(aes)",
2717 .cra_driver_name = "cbc-aes-talitos",
2718 .cra_blocksize = AES_BLOCK_SIZE,
2719 .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER |
2720 CRYPTO_ALG_ASYNC,
Lee Nipper4de9d0b2009-03-29 15:52:32 +08002721 .cra_ablkcipher = {
Lee Nipper4de9d0b2009-03-29 15:52:32 +08002722 .min_keysize = AES_MIN_KEY_SIZE,
2723 .max_keysize = AES_MAX_KEY_SIZE,
2724 .ivsize = AES_BLOCK_SIZE,
2725 }
2726 },
2727 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2728 DESC_HDR_SEL0_AESU |
2729 DESC_HDR_MODE0_AESU_CBC,
2730 },
Lee Nipperd5e4aae2010-05-19 19:18:38 +10002731 { .type = CRYPTO_ALG_TYPE_ABLKCIPHER,
2732 .alg.crypto = {
LEROY Christophe5e75ae12015-12-01 12:44:15 +01002733 .cra_name = "ctr(aes)",
2734 .cra_driver_name = "ctr-aes-talitos",
2735 .cra_blocksize = AES_BLOCK_SIZE,
2736 .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER |
2737 CRYPTO_ALG_ASYNC,
2738 .cra_ablkcipher = {
2739 .min_keysize = AES_MIN_KEY_SIZE,
2740 .max_keysize = AES_MAX_KEY_SIZE,
2741 .ivsize = AES_BLOCK_SIZE,
2742 }
2743 },
LEROY Christophe70d355c2017-10-06 15:04:43 +02002744 .desc_hdr_template = DESC_HDR_TYPE_AESU_CTR_NONSNOOP |
LEROY Christophe5e75ae12015-12-01 12:44:15 +01002745 DESC_HDR_SEL0_AESU |
2746 DESC_HDR_MODE0_AESU_CTR,
2747 },
2748 { .type = CRYPTO_ALG_TYPE_ABLKCIPHER,
2749 .alg.crypto = {
2750 .cra_name = "ecb(des)",
2751 .cra_driver_name = "ecb-des-talitos",
2752 .cra_blocksize = DES_BLOCK_SIZE,
2753 .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER |
2754 CRYPTO_ALG_ASYNC,
2755 .cra_ablkcipher = {
2756 .min_keysize = DES_KEY_SIZE,
2757 .max_keysize = DES_KEY_SIZE,
2758 .ivsize = DES_BLOCK_SIZE,
2759 }
2760 },
2761 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2762 DESC_HDR_SEL0_DEU,
2763 },
2764 { .type = CRYPTO_ALG_TYPE_ABLKCIPHER,
2765 .alg.crypto = {
2766 .cra_name = "cbc(des)",
2767 .cra_driver_name = "cbc-des-talitos",
2768 .cra_blocksize = DES_BLOCK_SIZE,
2769 .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER |
2770 CRYPTO_ALG_ASYNC,
2771 .cra_ablkcipher = {
2772 .min_keysize = DES_KEY_SIZE,
2773 .max_keysize = DES_KEY_SIZE,
2774 .ivsize = DES_BLOCK_SIZE,
2775 }
2776 },
2777 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2778 DESC_HDR_SEL0_DEU |
2779 DESC_HDR_MODE0_DEU_CBC,
2780 },
2781 { .type = CRYPTO_ALG_TYPE_ABLKCIPHER,
2782 .alg.crypto = {
2783 .cra_name = "ecb(des3_ede)",
2784 .cra_driver_name = "ecb-3des-talitos",
2785 .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2786 .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER |
2787 CRYPTO_ALG_ASYNC,
2788 .cra_ablkcipher = {
2789 .min_keysize = DES3_EDE_KEY_SIZE,
2790 .max_keysize = DES3_EDE_KEY_SIZE,
2791 .ivsize = DES3_EDE_BLOCK_SIZE,
2792 }
2793 },
2794 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2795 DESC_HDR_SEL0_DEU |
2796 DESC_HDR_MODE0_DEU_3DES,
2797 },
2798 { .type = CRYPTO_ALG_TYPE_ABLKCIPHER,
2799 .alg.crypto = {
Lee Nipper4de9d0b2009-03-29 15:52:32 +08002800 .cra_name = "cbc(des3_ede)",
2801 .cra_driver_name = "cbc-3des-talitos",
2802 .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2803 .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER |
2804 CRYPTO_ALG_ASYNC,
Lee Nipper4de9d0b2009-03-29 15:52:32 +08002805 .cra_ablkcipher = {
Lee Nipper4de9d0b2009-03-29 15:52:32 +08002806 .min_keysize = DES3_EDE_KEY_SIZE,
2807 .max_keysize = DES3_EDE_KEY_SIZE,
2808 .ivsize = DES3_EDE_BLOCK_SIZE,
2809 }
2810 },
2811 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2812 DESC_HDR_SEL0_DEU |
2813 DESC_HDR_MODE0_DEU_CBC |
2814 DESC_HDR_MODE0_DEU_3DES,
Lee Nipper497f2e62010-05-19 19:20:36 +10002815 },
2816 /* AHASH algorithms. */
2817 { .type = CRYPTO_ALG_TYPE_AHASH,
2818 .alg.hash = {
Lee Nipper497f2e62010-05-19 19:20:36 +10002819 .halg.digestsize = MD5_DIGEST_SIZE,
Horia Geant?3639ca82016-04-21 19:24:55 +03002820 .halg.statesize = sizeof(struct talitos_export_state),
Lee Nipper497f2e62010-05-19 19:20:36 +10002821 .halg.base = {
2822 .cra_name = "md5",
2823 .cra_driver_name = "md5-talitos",
Martin Hicksb3988612015-03-03 08:21:34 -05002824 .cra_blocksize = MD5_HMAC_BLOCK_SIZE,
Lee Nipper497f2e62010-05-19 19:20:36 +10002825 .cra_flags = CRYPTO_ALG_TYPE_AHASH |
2826 CRYPTO_ALG_ASYNC,
Lee Nipper497f2e62010-05-19 19:20:36 +10002827 }
2828 },
2829 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2830 DESC_HDR_SEL0_MDEUA |
2831 DESC_HDR_MODE0_MDEU_MD5,
2832 },
2833 { .type = CRYPTO_ALG_TYPE_AHASH,
2834 .alg.hash = {
Lee Nipper497f2e62010-05-19 19:20:36 +10002835 .halg.digestsize = SHA1_DIGEST_SIZE,
Horia Geant?3639ca82016-04-21 19:24:55 +03002836 .halg.statesize = sizeof(struct talitos_export_state),
Lee Nipper497f2e62010-05-19 19:20:36 +10002837 .halg.base = {
2838 .cra_name = "sha1",
2839 .cra_driver_name = "sha1-talitos",
2840 .cra_blocksize = SHA1_BLOCK_SIZE,
2841 .cra_flags = CRYPTO_ALG_TYPE_AHASH |
2842 CRYPTO_ALG_ASYNC,
Lee Nipper497f2e62010-05-19 19:20:36 +10002843 }
2844 },
2845 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2846 DESC_HDR_SEL0_MDEUA |
2847 DESC_HDR_MODE0_MDEU_SHA1,
2848 },
2849 { .type = CRYPTO_ALG_TYPE_AHASH,
2850 .alg.hash = {
Kim Phillips60f208d2010-05-19 19:21:53 +10002851 .halg.digestsize = SHA224_DIGEST_SIZE,
Horia Geant?3639ca82016-04-21 19:24:55 +03002852 .halg.statesize = sizeof(struct talitos_export_state),
Kim Phillips60f208d2010-05-19 19:21:53 +10002853 .halg.base = {
2854 .cra_name = "sha224",
2855 .cra_driver_name = "sha224-talitos",
2856 .cra_blocksize = SHA224_BLOCK_SIZE,
2857 .cra_flags = CRYPTO_ALG_TYPE_AHASH |
2858 CRYPTO_ALG_ASYNC,
Kim Phillips60f208d2010-05-19 19:21:53 +10002859 }
2860 },
2861 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2862 DESC_HDR_SEL0_MDEUA |
2863 DESC_HDR_MODE0_MDEU_SHA224,
2864 },
2865 { .type = CRYPTO_ALG_TYPE_AHASH,
2866 .alg.hash = {
Lee Nipper497f2e62010-05-19 19:20:36 +10002867 .halg.digestsize = SHA256_DIGEST_SIZE,
Horia Geant?3639ca82016-04-21 19:24:55 +03002868 .halg.statesize = sizeof(struct talitos_export_state),
Lee Nipper497f2e62010-05-19 19:20:36 +10002869 .halg.base = {
2870 .cra_name = "sha256",
2871 .cra_driver_name = "sha256-talitos",
2872 .cra_blocksize = SHA256_BLOCK_SIZE,
2873 .cra_flags = CRYPTO_ALG_TYPE_AHASH |
2874 CRYPTO_ALG_ASYNC,
Lee Nipper497f2e62010-05-19 19:20:36 +10002875 }
2876 },
2877 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2878 DESC_HDR_SEL0_MDEUA |
2879 DESC_HDR_MODE0_MDEU_SHA256,
2880 },
2881 { .type = CRYPTO_ALG_TYPE_AHASH,
2882 .alg.hash = {
Lee Nipper497f2e62010-05-19 19:20:36 +10002883 .halg.digestsize = SHA384_DIGEST_SIZE,
Horia Geant?3639ca82016-04-21 19:24:55 +03002884 .halg.statesize = sizeof(struct talitos_export_state),
Lee Nipper497f2e62010-05-19 19:20:36 +10002885 .halg.base = {
2886 .cra_name = "sha384",
2887 .cra_driver_name = "sha384-talitos",
2888 .cra_blocksize = SHA384_BLOCK_SIZE,
2889 .cra_flags = CRYPTO_ALG_TYPE_AHASH |
2890 CRYPTO_ALG_ASYNC,
Lee Nipper497f2e62010-05-19 19:20:36 +10002891 }
2892 },
2893 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2894 DESC_HDR_SEL0_MDEUB |
2895 DESC_HDR_MODE0_MDEUB_SHA384,
2896 },
2897 { .type = CRYPTO_ALG_TYPE_AHASH,
2898 .alg.hash = {
Lee Nipper497f2e62010-05-19 19:20:36 +10002899 .halg.digestsize = SHA512_DIGEST_SIZE,
Horia Geant?3639ca82016-04-21 19:24:55 +03002900 .halg.statesize = sizeof(struct talitos_export_state),
Lee Nipper497f2e62010-05-19 19:20:36 +10002901 .halg.base = {
2902 .cra_name = "sha512",
2903 .cra_driver_name = "sha512-talitos",
2904 .cra_blocksize = SHA512_BLOCK_SIZE,
2905 .cra_flags = CRYPTO_ALG_TYPE_AHASH |
2906 CRYPTO_ALG_ASYNC,
Lee Nipper497f2e62010-05-19 19:20:36 +10002907 }
2908 },
2909 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2910 DESC_HDR_SEL0_MDEUB |
2911 DESC_HDR_MODE0_MDEUB_SHA512,
2912 },
Lee Nipper79b3a412011-11-21 16:13:25 +08002913 { .type = CRYPTO_ALG_TYPE_AHASH,
2914 .alg.hash = {
Lee Nipper79b3a412011-11-21 16:13:25 +08002915 .halg.digestsize = MD5_DIGEST_SIZE,
Horia Geant?3639ca82016-04-21 19:24:55 +03002916 .halg.statesize = sizeof(struct talitos_export_state),
Lee Nipper79b3a412011-11-21 16:13:25 +08002917 .halg.base = {
2918 .cra_name = "hmac(md5)",
2919 .cra_driver_name = "hmac-md5-talitos",
Martin Hicksb3988612015-03-03 08:21:34 -05002920 .cra_blocksize = MD5_HMAC_BLOCK_SIZE,
Lee Nipper79b3a412011-11-21 16:13:25 +08002921 .cra_flags = CRYPTO_ALG_TYPE_AHASH |
2922 CRYPTO_ALG_ASYNC,
Lee Nipper79b3a412011-11-21 16:13:25 +08002923 }
2924 },
2925 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2926 DESC_HDR_SEL0_MDEUA |
2927 DESC_HDR_MODE0_MDEU_MD5,
2928 },
2929 { .type = CRYPTO_ALG_TYPE_AHASH,
2930 .alg.hash = {
Lee Nipper79b3a412011-11-21 16:13:25 +08002931 .halg.digestsize = SHA1_DIGEST_SIZE,
Horia Geant?3639ca82016-04-21 19:24:55 +03002932 .halg.statesize = sizeof(struct talitos_export_state),
Lee Nipper79b3a412011-11-21 16:13:25 +08002933 .halg.base = {
2934 .cra_name = "hmac(sha1)",
2935 .cra_driver_name = "hmac-sha1-talitos",
2936 .cra_blocksize = SHA1_BLOCK_SIZE,
2937 .cra_flags = CRYPTO_ALG_TYPE_AHASH |
2938 CRYPTO_ALG_ASYNC,
Lee Nipper79b3a412011-11-21 16:13:25 +08002939 }
2940 },
2941 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2942 DESC_HDR_SEL0_MDEUA |
2943 DESC_HDR_MODE0_MDEU_SHA1,
2944 },
2945 { .type = CRYPTO_ALG_TYPE_AHASH,
2946 .alg.hash = {
Lee Nipper79b3a412011-11-21 16:13:25 +08002947 .halg.digestsize = SHA224_DIGEST_SIZE,
Horia Geant?3639ca82016-04-21 19:24:55 +03002948 .halg.statesize = sizeof(struct talitos_export_state),
Lee Nipper79b3a412011-11-21 16:13:25 +08002949 .halg.base = {
2950 .cra_name = "hmac(sha224)",
2951 .cra_driver_name = "hmac-sha224-talitos",
2952 .cra_blocksize = SHA224_BLOCK_SIZE,
2953 .cra_flags = CRYPTO_ALG_TYPE_AHASH |
2954 CRYPTO_ALG_ASYNC,
Lee Nipper79b3a412011-11-21 16:13:25 +08002955 }
2956 },
2957 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2958 DESC_HDR_SEL0_MDEUA |
2959 DESC_HDR_MODE0_MDEU_SHA224,
2960 },
2961 { .type = CRYPTO_ALG_TYPE_AHASH,
2962 .alg.hash = {
Lee Nipper79b3a412011-11-21 16:13:25 +08002963 .halg.digestsize = SHA256_DIGEST_SIZE,
Horia Geant?3639ca82016-04-21 19:24:55 +03002964 .halg.statesize = sizeof(struct talitos_export_state),
Lee Nipper79b3a412011-11-21 16:13:25 +08002965 .halg.base = {
2966 .cra_name = "hmac(sha256)",
2967 .cra_driver_name = "hmac-sha256-talitos",
2968 .cra_blocksize = SHA256_BLOCK_SIZE,
2969 .cra_flags = CRYPTO_ALG_TYPE_AHASH |
2970 CRYPTO_ALG_ASYNC,
Lee Nipper79b3a412011-11-21 16:13:25 +08002971 }
2972 },
2973 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2974 DESC_HDR_SEL0_MDEUA |
2975 DESC_HDR_MODE0_MDEU_SHA256,
2976 },
2977 { .type = CRYPTO_ALG_TYPE_AHASH,
2978 .alg.hash = {
Lee Nipper79b3a412011-11-21 16:13:25 +08002979 .halg.digestsize = SHA384_DIGEST_SIZE,
Horia Geant?3639ca82016-04-21 19:24:55 +03002980 .halg.statesize = sizeof(struct talitos_export_state),
Lee Nipper79b3a412011-11-21 16:13:25 +08002981 .halg.base = {
2982 .cra_name = "hmac(sha384)",
2983 .cra_driver_name = "hmac-sha384-talitos",
2984 .cra_blocksize = SHA384_BLOCK_SIZE,
2985 .cra_flags = CRYPTO_ALG_TYPE_AHASH |
2986 CRYPTO_ALG_ASYNC,
Lee Nipper79b3a412011-11-21 16:13:25 +08002987 }
2988 },
2989 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2990 DESC_HDR_SEL0_MDEUB |
2991 DESC_HDR_MODE0_MDEUB_SHA384,
2992 },
2993 { .type = CRYPTO_ALG_TYPE_AHASH,
2994 .alg.hash = {
Lee Nipper79b3a412011-11-21 16:13:25 +08002995 .halg.digestsize = SHA512_DIGEST_SIZE,
Horia Geant?3639ca82016-04-21 19:24:55 +03002996 .halg.statesize = sizeof(struct talitos_export_state),
Lee Nipper79b3a412011-11-21 16:13:25 +08002997 .halg.base = {
2998 .cra_name = "hmac(sha512)",
2999 .cra_driver_name = "hmac-sha512-talitos",
3000 .cra_blocksize = SHA512_BLOCK_SIZE,
3001 .cra_flags = CRYPTO_ALG_TYPE_AHASH |
3002 CRYPTO_ALG_ASYNC,
Lee Nipper79b3a412011-11-21 16:13:25 +08003003 }
3004 },
3005 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
3006 DESC_HDR_SEL0_MDEUB |
3007 DESC_HDR_MODE0_MDEUB_SHA512,
3008 }
Kim Phillips9c4a7962008-06-23 19:50:15 +08003009};
3010
3011struct talitos_crypto_alg {
3012 struct list_head entry;
3013 struct device *dev;
Lee Nipperacbf7c622010-05-19 19:19:33 +10003014 struct talitos_alg_template algt;
Kim Phillips9c4a7962008-06-23 19:50:15 +08003015};
3016
Jonas Eymann89d124c2016-04-19 20:33:47 +03003017static int talitos_init_common(struct talitos_ctx *ctx,
3018 struct talitos_crypto_alg *talitos_alg)
Kim Phillips9c4a7962008-06-23 19:50:15 +08003019{
Kim Phillips5228f0f2011-07-15 11:21:38 +08003020 struct talitos_private *priv;
Kim Phillips9c4a7962008-06-23 19:50:15 +08003021
3022 /* update context with ptr to dev */
3023 ctx->dev = talitos_alg->dev;
Kim Phillips19bbbc62009-03-29 15:53:59 +08003024
Kim Phillips5228f0f2011-07-15 11:21:38 +08003025 /* assign SEC channel to tfm in round-robin fashion */
3026 priv = dev_get_drvdata(ctx->dev);
3027 ctx->ch = atomic_inc_return(&priv->last_chan) &
3028 (priv->num_channels - 1);
3029
Kim Phillips9c4a7962008-06-23 19:50:15 +08003030 /* copy descriptor header template value */
Lee Nipperacbf7c622010-05-19 19:19:33 +10003031 ctx->desc_hdr_template = talitos_alg->algt.desc_hdr_template;
Kim Phillips9c4a7962008-06-23 19:50:15 +08003032
Kim Phillips602dba52011-07-15 11:21:39 +08003033 /* select done notification */
3034 ctx->desc_hdr_template |= DESC_HDR_DONE_NOTIFY;
3035
Lee Nipper497f2e62010-05-19 19:20:36 +10003036 return 0;
3037}
3038
Jonas Eymann89d124c2016-04-19 20:33:47 +03003039static int talitos_cra_init(struct crypto_tfm *tfm)
3040{
3041 struct crypto_alg *alg = tfm->__crt_alg;
3042 struct talitos_crypto_alg *talitos_alg;
3043 struct talitos_ctx *ctx = crypto_tfm_ctx(tfm);
3044
3045 if ((alg->cra_flags & CRYPTO_ALG_TYPE_MASK) == CRYPTO_ALG_TYPE_AHASH)
3046 talitos_alg = container_of(__crypto_ahash_alg(alg),
3047 struct talitos_crypto_alg,
3048 algt.alg.hash);
3049 else
3050 talitos_alg = container_of(alg, struct talitos_crypto_alg,
3051 algt.alg.crypto);
3052
3053 return talitos_init_common(ctx, talitos_alg);
3054}
3055
Herbert Xuaeb4c132015-07-30 17:53:22 +08003056static int talitos_cra_init_aead(struct crypto_aead *tfm)
Lee Nipper497f2e62010-05-19 19:20:36 +10003057{
Jonas Eymann89d124c2016-04-19 20:33:47 +03003058 struct aead_alg *alg = crypto_aead_alg(tfm);
3059 struct talitos_crypto_alg *talitos_alg;
3060 struct talitos_ctx *ctx = crypto_aead_ctx(tfm);
3061
3062 talitos_alg = container_of(alg, struct talitos_crypto_alg,
3063 algt.alg.aead);
3064
3065 return talitos_init_common(ctx, talitos_alg);
Kim Phillips9c4a7962008-06-23 19:50:15 +08003066}
3067
Lee Nipper497f2e62010-05-19 19:20:36 +10003068static int talitos_cra_init_ahash(struct crypto_tfm *tfm)
3069{
3070 struct talitos_ctx *ctx = crypto_tfm_ctx(tfm);
3071
3072 talitos_cra_init(tfm);
3073
3074 ctx->keylen = 0;
3075 crypto_ahash_set_reqsize(__crypto_ahash_cast(tfm),
3076 sizeof(struct talitos_ahash_req_ctx));
3077
3078 return 0;
3079}
3080
LEROY Christophe2e13ce02017-10-06 15:05:02 +02003081static void talitos_cra_exit(struct crypto_tfm *tfm)
3082{
3083 struct talitos_ctx *ctx = crypto_tfm_ctx(tfm);
3084 struct device *dev = ctx->dev;
3085
3086 if (ctx->keylen)
3087 dma_unmap_single(dev, ctx->dma_key, ctx->keylen, DMA_TO_DEVICE);
3088}
3089
Kim Phillips9c4a7962008-06-23 19:50:15 +08003090/*
3091 * given the alg's descriptor header template, determine whether descriptor
3092 * type and primary/secondary execution units required match the hw
3093 * capabilities description provided in the device tree node.
3094 */
3095static int hw_supports(struct device *dev, __be32 desc_hdr_template)
3096{
3097 struct talitos_private *priv = dev_get_drvdata(dev);
3098 int ret;
3099
3100 ret = (1 << DESC_TYPE(desc_hdr_template) & priv->desc_types) &&
3101 (1 << PRIMARY_EU(desc_hdr_template) & priv->exec_units);
3102
3103 if (SECONDARY_EU(desc_hdr_template))
3104 ret = ret && (1 << SECONDARY_EU(desc_hdr_template)
3105 & priv->exec_units);
3106
3107 return ret;
3108}
3109
Grant Likely2dc11582010-08-06 09:25:50 -06003110static int talitos_remove(struct platform_device *ofdev)
Kim Phillips9c4a7962008-06-23 19:50:15 +08003111{
3112 struct device *dev = &ofdev->dev;
3113 struct talitos_private *priv = dev_get_drvdata(dev);
3114 struct talitos_crypto_alg *t_alg, *n;
3115 int i;
3116
3117 list_for_each_entry_safe(t_alg, n, &priv->alg_list, entry) {
Lee Nipperacbf7c622010-05-19 19:19:33 +10003118 switch (t_alg->algt.type) {
3119 case CRYPTO_ALG_TYPE_ABLKCIPHER:
Lee Nipperacbf7c622010-05-19 19:19:33 +10003120 break;
Herbert Xuaeb4c132015-07-30 17:53:22 +08003121 case CRYPTO_ALG_TYPE_AEAD:
3122 crypto_unregister_aead(&t_alg->algt.alg.aead);
Lee Nipperacbf7c622010-05-19 19:19:33 +10003123 case CRYPTO_ALG_TYPE_AHASH:
3124 crypto_unregister_ahash(&t_alg->algt.alg.hash);
3125 break;
3126 }
Kim Phillips9c4a7962008-06-23 19:50:15 +08003127 list_del(&t_alg->entry);
Kim Phillips9c4a7962008-06-23 19:50:15 +08003128 }
3129
3130 if (hw_supports(dev, DESC_HDR_SEL0_RNG))
3131 talitos_unregister_rng(dev);
3132
Kim Phillipsc3e337f2011-11-21 16:13:27 +08003133 for (i = 0; i < 2; i++)
Kim Phillips2cdba3c2011-12-12 14:59:11 -06003134 if (priv->irq[i]) {
Kim Phillipsc3e337f2011-11-21 16:13:27 +08003135 free_irq(priv->irq[i], dev);
3136 irq_dispose_mapping(priv->irq[i]);
3137 }
Kim Phillips9c4a7962008-06-23 19:50:15 +08003138
Kim Phillipsc3e337f2011-11-21 16:13:27 +08003139 tasklet_kill(&priv->done_task[0]);
Kim Phillips2cdba3c2011-12-12 14:59:11 -06003140 if (priv->irq[1])
Kim Phillipsc3e337f2011-11-21 16:13:27 +08003141 tasklet_kill(&priv->done_task[1]);
Kim Phillips9c4a7962008-06-23 19:50:15 +08003142
Kim Phillips9c4a7962008-06-23 19:50:15 +08003143 return 0;
3144}
3145
3146static struct talitos_crypto_alg *talitos_alg_alloc(struct device *dev,
3147 struct talitos_alg_template
3148 *template)
3149{
Kim Phillips60f208d2010-05-19 19:21:53 +10003150 struct talitos_private *priv = dev_get_drvdata(dev);
Kim Phillips9c4a7962008-06-23 19:50:15 +08003151 struct talitos_crypto_alg *t_alg;
3152 struct crypto_alg *alg;
3153
LEROY Christophe24b92ff2017-10-06 15:04:49 +02003154 t_alg = devm_kzalloc(dev, sizeof(struct talitos_crypto_alg),
3155 GFP_KERNEL);
Kim Phillips9c4a7962008-06-23 19:50:15 +08003156 if (!t_alg)
3157 return ERR_PTR(-ENOMEM);
3158
Lee Nipperacbf7c622010-05-19 19:19:33 +10003159 t_alg->algt = *template;
3160
3161 switch (t_alg->algt.type) {
3162 case CRYPTO_ALG_TYPE_ABLKCIPHER:
Lee Nipper497f2e62010-05-19 19:20:36 +10003163 alg = &t_alg->algt.alg.crypto;
3164 alg->cra_init = talitos_cra_init;
LEROY Christophe2e13ce02017-10-06 15:05:02 +02003165 alg->cra_exit = talitos_cra_exit;
Kim Phillipsd4cd3282012-08-08 20:32:00 -05003166 alg->cra_type = &crypto_ablkcipher_type;
Kim Phillipsb286e002012-08-08 20:33:34 -05003167 alg->cra_ablkcipher.setkey = ablkcipher_setkey;
3168 alg->cra_ablkcipher.encrypt = ablkcipher_encrypt;
3169 alg->cra_ablkcipher.decrypt = ablkcipher_decrypt;
3170 alg->cra_ablkcipher.geniv = "eseqiv";
Lee Nipper497f2e62010-05-19 19:20:36 +10003171 break;
Lee Nipperacbf7c622010-05-19 19:19:33 +10003172 case CRYPTO_ALG_TYPE_AEAD:
Herbert Xuaeb4c132015-07-30 17:53:22 +08003173 alg = &t_alg->algt.alg.aead.base;
LEROY Christophe2e13ce02017-10-06 15:05:02 +02003174 alg->cra_exit = talitos_cra_exit;
Herbert Xuaeb4c132015-07-30 17:53:22 +08003175 t_alg->algt.alg.aead.init = talitos_cra_init_aead;
3176 t_alg->algt.alg.aead.setkey = aead_setkey;
3177 t_alg->algt.alg.aead.encrypt = aead_encrypt;
3178 t_alg->algt.alg.aead.decrypt = aead_decrypt;
LEROY Christophe6cda0752017-10-06 15:04:39 +02003179 if (!(priv->features & TALITOS_FTR_SHA224_HWINIT) &&
3180 !strncmp(alg->cra_name, "authenc(hmac(sha224)", 20)) {
LEROY Christophe24b92ff2017-10-06 15:04:49 +02003181 devm_kfree(dev, t_alg);
LEROY Christophe6cda0752017-10-06 15:04:39 +02003182 return ERR_PTR(-ENOTSUPP);
3183 }
Lee Nipperacbf7c622010-05-19 19:19:33 +10003184 break;
3185 case CRYPTO_ALG_TYPE_AHASH:
3186 alg = &t_alg->algt.alg.hash.halg.base;
Lee Nipper497f2e62010-05-19 19:20:36 +10003187 alg->cra_init = talitos_cra_init_ahash;
LEROY Christophead4cd512018-02-26 17:40:04 +01003188 alg->cra_exit = talitos_cra_exit;
Kim Phillipsd4cd3282012-08-08 20:32:00 -05003189 alg->cra_type = &crypto_ahash_type;
Kim Phillipsb286e002012-08-08 20:33:34 -05003190 t_alg->algt.alg.hash.init = ahash_init;
3191 t_alg->algt.alg.hash.update = ahash_update;
3192 t_alg->algt.alg.hash.final = ahash_final;
3193 t_alg->algt.alg.hash.finup = ahash_finup;
3194 t_alg->algt.alg.hash.digest = ahash_digest;
LEROY Christophe56136632017-09-12 11:03:39 +02003195 if (!strncmp(alg->cra_name, "hmac", 4))
3196 t_alg->algt.alg.hash.setkey = ahash_setkey;
Horia Geant?3639ca82016-04-21 19:24:55 +03003197 t_alg->algt.alg.hash.import = ahash_import;
3198 t_alg->algt.alg.hash.export = ahash_export;
Kim Phillipsb286e002012-08-08 20:33:34 -05003199
Lee Nipper79b3a412011-11-21 16:13:25 +08003200 if (!(priv->features & TALITOS_FTR_HMAC_OK) &&
Kim Phillips0b2730d2011-12-12 14:59:10 -06003201 !strncmp(alg->cra_name, "hmac", 4)) {
LEROY Christophe24b92ff2017-10-06 15:04:49 +02003202 devm_kfree(dev, t_alg);
Lee Nipper79b3a412011-11-21 16:13:25 +08003203 return ERR_PTR(-ENOTSUPP);
Kim Phillips0b2730d2011-12-12 14:59:10 -06003204 }
Kim Phillips60f208d2010-05-19 19:21:53 +10003205 if (!(priv->features & TALITOS_FTR_SHA224_HWINIT) &&
Lee Nipper79b3a412011-11-21 16:13:25 +08003206 (!strcmp(alg->cra_name, "sha224") ||
3207 !strcmp(alg->cra_name, "hmac(sha224)"))) {
Kim Phillips60f208d2010-05-19 19:21:53 +10003208 t_alg->algt.alg.hash.init = ahash_init_sha224_swinit;
3209 t_alg->algt.desc_hdr_template =
3210 DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
3211 DESC_HDR_SEL0_MDEUA |
3212 DESC_HDR_MODE0_MDEU_SHA256;
3213 }
Lee Nipper497f2e62010-05-19 19:20:36 +10003214 break;
Kim Phillips1d119112010-09-23 15:55:27 +08003215 default:
3216 dev_err(dev, "unknown algorithm type %d\n", t_alg->algt.type);
LEROY Christophe24b92ff2017-10-06 15:04:49 +02003217 devm_kfree(dev, t_alg);
Kim Phillips1d119112010-09-23 15:55:27 +08003218 return ERR_PTR(-EINVAL);
Lee Nipperacbf7c622010-05-19 19:19:33 +10003219 }
Kim Phillips9c4a7962008-06-23 19:50:15 +08003220
Kim Phillips9c4a7962008-06-23 19:50:15 +08003221 alg->cra_module = THIS_MODULE;
LEROY Christopheb0057762016-06-06 13:20:44 +02003222 if (t_alg->algt.priority)
3223 alg->cra_priority = t_alg->algt.priority;
3224 else
3225 alg->cra_priority = TALITOS_CRA_PRIORITY;
Kim Phillips9c4a7962008-06-23 19:50:15 +08003226 alg->cra_alignmask = 0;
Kim Phillips9c4a7962008-06-23 19:50:15 +08003227 alg->cra_ctxsize = sizeof(struct talitos_ctx);
Nikos Mavrogiannopoulosd912bb72011-11-01 13:39:56 +01003228 alg->cra_flags |= CRYPTO_ALG_KERN_DRIVER_ONLY;
Kim Phillips9c4a7962008-06-23 19:50:15 +08003229
Kim Phillips9c4a7962008-06-23 19:50:15 +08003230 t_alg->dev = dev;
3231
3232 return t_alg;
3233}
3234
Kim Phillipsc3e337f2011-11-21 16:13:27 +08003235static int talitos_probe_irq(struct platform_device *ofdev)
3236{
3237 struct device *dev = &ofdev->dev;
3238 struct device_node *np = ofdev->dev.of_node;
3239 struct talitos_private *priv = dev_get_drvdata(dev);
3240 int err;
LEROY Christophedd3c0982015-04-17 16:32:13 +02003241 bool is_sec1 = has_ftr_sec1(priv);
Kim Phillipsc3e337f2011-11-21 16:13:27 +08003242
3243 priv->irq[0] = irq_of_parse_and_map(np, 0);
Kim Phillips2cdba3c2011-12-12 14:59:11 -06003244 if (!priv->irq[0]) {
Kim Phillipsc3e337f2011-11-21 16:13:27 +08003245 dev_err(dev, "failed to map irq\n");
3246 return -EINVAL;
3247 }
LEROY Christophedd3c0982015-04-17 16:32:13 +02003248 if (is_sec1) {
3249 err = request_irq(priv->irq[0], talitos1_interrupt_4ch, 0,
3250 dev_driver_string(dev), dev);
3251 goto primary_out;
3252 }
Kim Phillipsc3e337f2011-11-21 16:13:27 +08003253
3254 priv->irq[1] = irq_of_parse_and_map(np, 1);
3255
3256 /* get the primary irq line */
Kim Phillips2cdba3c2011-12-12 14:59:11 -06003257 if (!priv->irq[1]) {
LEROY Christophedd3c0982015-04-17 16:32:13 +02003258 err = request_irq(priv->irq[0], talitos2_interrupt_4ch, 0,
Kim Phillipsc3e337f2011-11-21 16:13:27 +08003259 dev_driver_string(dev), dev);
3260 goto primary_out;
3261 }
3262
LEROY Christophedd3c0982015-04-17 16:32:13 +02003263 err = request_irq(priv->irq[0], talitos2_interrupt_ch0_2, 0,
Kim Phillipsc3e337f2011-11-21 16:13:27 +08003264 dev_driver_string(dev), dev);
3265 if (err)
3266 goto primary_out;
3267
3268 /* get the secondary irq line */
LEROY Christophedd3c0982015-04-17 16:32:13 +02003269 err = request_irq(priv->irq[1], talitos2_interrupt_ch1_3, 0,
Kim Phillipsc3e337f2011-11-21 16:13:27 +08003270 dev_driver_string(dev), dev);
3271 if (err) {
3272 dev_err(dev, "failed to request secondary irq\n");
3273 irq_dispose_mapping(priv->irq[1]);
Kim Phillips2cdba3c2011-12-12 14:59:11 -06003274 priv->irq[1] = 0;
Kim Phillipsc3e337f2011-11-21 16:13:27 +08003275 }
3276
3277 return err;
3278
3279primary_out:
3280 if (err) {
3281 dev_err(dev, "failed to request primary irq\n");
3282 irq_dispose_mapping(priv->irq[0]);
Kim Phillips2cdba3c2011-12-12 14:59:11 -06003283 priv->irq[0] = 0;
Kim Phillipsc3e337f2011-11-21 16:13:27 +08003284 }
3285
3286 return err;
3287}
3288
Grant Likely1c48a5c2011-02-17 02:43:24 -07003289static int talitos_probe(struct platform_device *ofdev)
Kim Phillips9c4a7962008-06-23 19:50:15 +08003290{
3291 struct device *dev = &ofdev->dev;
Grant Likely61c7a082010-04-13 16:12:29 -07003292 struct device_node *np = ofdev->dev.of_node;
Kim Phillips9c4a7962008-06-23 19:50:15 +08003293 struct talitos_private *priv;
Kim Phillips9c4a7962008-06-23 19:50:15 +08003294 int i, err;
LEROY Christophe5fa7fa12015-04-17 16:32:11 +02003295 int stride;
LEROY Christophefd5ea7f2017-10-06 15:04:53 +02003296 struct resource *res;
Kim Phillips9c4a7962008-06-23 19:50:15 +08003297
LEROY Christophe24b92ff2017-10-06 15:04:49 +02003298 priv = devm_kzalloc(dev, sizeof(struct talitos_private), GFP_KERNEL);
Kim Phillips9c4a7962008-06-23 19:50:15 +08003299 if (!priv)
3300 return -ENOMEM;
3301
Kevin Haof3de9cb2014-01-28 20:17:23 +08003302 INIT_LIST_HEAD(&priv->alg_list);
3303
Kim Phillips9c4a7962008-06-23 19:50:15 +08003304 dev_set_drvdata(dev, priv);
3305
3306 priv->ofdev = ofdev;
3307
Horia Geanta511d63c2012-03-30 17:49:53 +03003308 spin_lock_init(&priv->reg_lock);
3309
LEROY Christophefd5ea7f2017-10-06 15:04:53 +02003310 res = platform_get_resource(ofdev, IORESOURCE_MEM, 0);
3311 if (!res)
3312 return -ENXIO;
3313 priv->reg = devm_ioremap(dev, res->start, resource_size(res));
Kim Phillips9c4a7962008-06-23 19:50:15 +08003314 if (!priv->reg) {
3315 dev_err(dev, "failed to of_iomap\n");
3316 err = -ENOMEM;
3317 goto err_out;
3318 }
3319
3320 /* get SEC version capabilities from device tree */
LEROY Christophefa14c6c2017-10-06 15:04:51 +02003321 of_property_read_u32(np, "fsl,num-channels", &priv->num_channels);
3322 of_property_read_u32(np, "fsl,channel-fifo-len", &priv->chfifo_len);
3323 of_property_read_u32(np, "fsl,exec-units-mask", &priv->exec_units);
3324 of_property_read_u32(np, "fsl,descriptor-types-mask",
3325 &priv->desc_types);
Kim Phillips9c4a7962008-06-23 19:50:15 +08003326
3327 if (!is_power_of_2(priv->num_channels) || !priv->chfifo_len ||
3328 !priv->exec_units || !priv->desc_types) {
3329 dev_err(dev, "invalid property data in device tree node\n");
3330 err = -EINVAL;
3331 goto err_out;
3332 }
3333
Lee Nipperf3c85bc2008-07-30 16:26:57 +08003334 if (of_device_is_compatible(np, "fsl,sec3.0"))
3335 priv->features |= TALITOS_FTR_SRC_LINK_TBL_LEN_INCLUDES_EXTENT;
3336
Kim Phillipsfe5720e2008-10-12 20:33:14 +08003337 if (of_device_is_compatible(np, "fsl,sec2.1"))
Kim Phillips60f208d2010-05-19 19:21:53 +10003338 priv->features |= TALITOS_FTR_HW_AUTH_CHECK |
Lee Nipper79b3a412011-11-21 16:13:25 +08003339 TALITOS_FTR_SHA224_HWINIT |
3340 TALITOS_FTR_HMAC_OK;
Kim Phillipsfe5720e2008-10-12 20:33:14 +08003341
LEROY Christophe21590882015-04-17 16:32:05 +02003342 if (of_device_is_compatible(np, "fsl,sec1.0"))
3343 priv->features |= TALITOS_FTR_SEC1;
3344
LEROY Christophe5fa7fa12015-04-17 16:32:11 +02003345 if (of_device_is_compatible(np, "fsl,sec1.2")) {
3346 priv->reg_deu = priv->reg + TALITOS12_DEU;
3347 priv->reg_aesu = priv->reg + TALITOS12_AESU;
3348 priv->reg_mdeu = priv->reg + TALITOS12_MDEU;
3349 stride = TALITOS1_CH_STRIDE;
3350 } else if (of_device_is_compatible(np, "fsl,sec1.0")) {
3351 priv->reg_deu = priv->reg + TALITOS10_DEU;
3352 priv->reg_aesu = priv->reg + TALITOS10_AESU;
3353 priv->reg_mdeu = priv->reg + TALITOS10_MDEU;
3354 priv->reg_afeu = priv->reg + TALITOS10_AFEU;
3355 priv->reg_rngu = priv->reg + TALITOS10_RNGU;
3356 priv->reg_pkeu = priv->reg + TALITOS10_PKEU;
3357 stride = TALITOS1_CH_STRIDE;
3358 } else {
3359 priv->reg_deu = priv->reg + TALITOS2_DEU;
3360 priv->reg_aesu = priv->reg + TALITOS2_AESU;
3361 priv->reg_mdeu = priv->reg + TALITOS2_MDEU;
3362 priv->reg_afeu = priv->reg + TALITOS2_AFEU;
3363 priv->reg_rngu = priv->reg + TALITOS2_RNGU;
3364 priv->reg_pkeu = priv->reg + TALITOS2_PKEU;
3365 priv->reg_keu = priv->reg + TALITOS2_KEU;
3366 priv->reg_crcu = priv->reg + TALITOS2_CRCU;
3367 stride = TALITOS2_CH_STRIDE;
3368 }
3369
LEROY Christophedd3c0982015-04-17 16:32:13 +02003370 err = talitos_probe_irq(ofdev);
3371 if (err)
3372 goto err_out;
3373
3374 if (of_device_is_compatible(np, "fsl,sec1.0")) {
LEROY Christophe9c02e282017-10-06 15:04:55 +02003375 if (priv->num_channels == 1)
3376 tasklet_init(&priv->done_task[0], talitos1_done_ch0,
LEROY Christophedd3c0982015-04-17 16:32:13 +02003377 (unsigned long)dev);
LEROY Christophe9c02e282017-10-06 15:04:55 +02003378 else
3379 tasklet_init(&priv->done_task[0], talitos1_done_4ch,
3380 (unsigned long)dev);
3381 } else {
3382 if (priv->irq[1]) {
LEROY Christophedd3c0982015-04-17 16:32:13 +02003383 tasklet_init(&priv->done_task[0], talitos2_done_ch0_2,
3384 (unsigned long)dev);
3385 tasklet_init(&priv->done_task[1], talitos2_done_ch1_3,
3386 (unsigned long)dev);
LEROY Christophe9c02e282017-10-06 15:04:55 +02003387 } else if (priv->num_channels == 1) {
3388 tasklet_init(&priv->done_task[0], talitos2_done_ch0,
3389 (unsigned long)dev);
3390 } else {
3391 tasklet_init(&priv->done_task[0], talitos2_done_4ch,
3392 (unsigned long)dev);
LEROY Christophedd3c0982015-04-17 16:32:13 +02003393 }
3394 }
3395
LEROY Christophe24b92ff2017-10-06 15:04:49 +02003396 priv->chan = devm_kzalloc(dev, sizeof(struct talitos_channel) *
3397 priv->num_channels, GFP_KERNEL);
Kim Phillips4b9926282009-08-13 11:50:38 +10003398 if (!priv->chan) {
3399 dev_err(dev, "failed to allocate channel management space\n");
Kim Phillips9c4a7962008-06-23 19:50:15 +08003400 err = -ENOMEM;
3401 goto err_out;
3402 }
3403
Martin Hicksf641ddd2015-03-03 08:21:33 -05003404 priv->fifo_len = roundup_pow_of_two(priv->chfifo_len);
3405
Kim Phillipsc3e337f2011-11-21 16:13:27 +08003406 for (i = 0; i < priv->num_channels; i++) {
LEROY Christophe5fa7fa12015-04-17 16:32:11 +02003407 priv->chan[i].reg = priv->reg + stride * (i + 1);
Kim Phillips2cdba3c2011-12-12 14:59:11 -06003408 if (!priv->irq[1] || !(i & 1))
Kim Phillipsc3e337f2011-11-21 16:13:27 +08003409 priv->chan[i].reg += TALITOS_CH_BASE_OFFSET;
Kim Phillipsad42d5f2011-11-21 16:13:27 +08003410
Kim Phillips4b9926282009-08-13 11:50:38 +10003411 spin_lock_init(&priv->chan[i].head_lock);
3412 spin_lock_init(&priv->chan[i].tail_lock);
Kim Phillips9c4a7962008-06-23 19:50:15 +08003413
LEROY Christophe24b92ff2017-10-06 15:04:49 +02003414 priv->chan[i].fifo = devm_kzalloc(dev,
3415 sizeof(struct talitos_request) *
3416 priv->fifo_len, GFP_KERNEL);
Kim Phillips4b9926282009-08-13 11:50:38 +10003417 if (!priv->chan[i].fifo) {
Kim Phillips9c4a7962008-06-23 19:50:15 +08003418 dev_err(dev, "failed to allocate request fifo %d\n", i);
3419 err = -ENOMEM;
3420 goto err_out;
3421 }
Kim Phillips9c4a7962008-06-23 19:50:15 +08003422
Kim Phillips4b9926282009-08-13 11:50:38 +10003423 atomic_set(&priv->chan[i].submit_count,
3424 -(priv->chfifo_len - 1));
Martin Hicksf641ddd2015-03-03 08:21:33 -05003425 }
Kim Phillips9c4a7962008-06-23 19:50:15 +08003426
Kim Phillips81eb0242009-08-13 11:51:51 +10003427 dma_set_mask(dev, DMA_BIT_MASK(36));
3428
Kim Phillips9c4a7962008-06-23 19:50:15 +08003429 /* reset and initialize the h/w */
3430 err = init_device(dev);
3431 if (err) {
3432 dev_err(dev, "failed to initialize device\n");
3433 goto err_out;
3434 }
3435
3436 /* register the RNG, if available */
3437 if (hw_supports(dev, DESC_HDR_SEL0_RNG)) {
3438 err = talitos_register_rng(dev);
3439 if (err) {
3440 dev_err(dev, "failed to register hwrng: %d\n", err);
3441 goto err_out;
3442 } else
3443 dev_info(dev, "hwrng\n");
3444 }
3445
3446 /* register crypto algorithms the device supports */
Kim Phillips9c4a7962008-06-23 19:50:15 +08003447 for (i = 0; i < ARRAY_SIZE(driver_algs); i++) {
3448 if (hw_supports(dev, driver_algs[i].desc_hdr_template)) {
3449 struct talitos_crypto_alg *t_alg;
Herbert Xuaeb4c132015-07-30 17:53:22 +08003450 struct crypto_alg *alg = NULL;
Kim Phillips9c4a7962008-06-23 19:50:15 +08003451
3452 t_alg = talitos_alg_alloc(dev, &driver_algs[i]);
3453 if (IS_ERR(t_alg)) {
3454 err = PTR_ERR(t_alg);
Kim Phillips0b2730d2011-12-12 14:59:10 -06003455 if (err == -ENOTSUPP)
Lee Nipper79b3a412011-11-21 16:13:25 +08003456 continue;
Kim Phillips9c4a7962008-06-23 19:50:15 +08003457 goto err_out;
3458 }
3459
Lee Nipperacbf7c622010-05-19 19:19:33 +10003460 switch (t_alg->algt.type) {
3461 case CRYPTO_ALG_TYPE_ABLKCIPHER:
Lee Nipperacbf7c622010-05-19 19:19:33 +10003462 err = crypto_register_alg(
3463 &t_alg->algt.alg.crypto);
Herbert Xuaeb4c132015-07-30 17:53:22 +08003464 alg = &t_alg->algt.alg.crypto;
Lee Nipperacbf7c622010-05-19 19:19:33 +10003465 break;
Herbert Xuaeb4c132015-07-30 17:53:22 +08003466
3467 case CRYPTO_ALG_TYPE_AEAD:
3468 err = crypto_register_aead(
3469 &t_alg->algt.alg.aead);
3470 alg = &t_alg->algt.alg.aead.base;
3471 break;
3472
Lee Nipperacbf7c622010-05-19 19:19:33 +10003473 case CRYPTO_ALG_TYPE_AHASH:
3474 err = crypto_register_ahash(
3475 &t_alg->algt.alg.hash);
Herbert Xuaeb4c132015-07-30 17:53:22 +08003476 alg = &t_alg->algt.alg.hash.halg.base;
Lee Nipperacbf7c622010-05-19 19:19:33 +10003477 break;
3478 }
Kim Phillips9c4a7962008-06-23 19:50:15 +08003479 if (err) {
3480 dev_err(dev, "%s alg registration failed\n",
Herbert Xuaeb4c132015-07-30 17:53:22 +08003481 alg->cra_driver_name);
LEROY Christophe24b92ff2017-10-06 15:04:49 +02003482 devm_kfree(dev, t_alg);
Horia Geanta991155b2013-03-20 16:31:38 +02003483 } else
Kim Phillips9c4a7962008-06-23 19:50:15 +08003484 list_add_tail(&t_alg->entry, &priv->alg_list);
Kim Phillips9c4a7962008-06-23 19:50:15 +08003485 }
3486 }
Kim Phillips5b859b6e2011-11-21 16:13:26 +08003487 if (!list_empty(&priv->alg_list))
3488 dev_info(dev, "%s algorithms registered in /proc/crypto\n",
3489 (char *)of_get_property(np, "compatible", NULL));
Kim Phillips9c4a7962008-06-23 19:50:15 +08003490
3491 return 0;
3492
3493err_out:
3494 talitos_remove(ofdev);
Kim Phillips9c4a7962008-06-23 19:50:15 +08003495
3496 return err;
3497}
3498
Márton Németh6c3f9752010-01-17 21:54:01 +11003499static const struct of_device_id talitos_match[] = {
LEROY Christophe0635b7d2015-04-17 16:32:20 +02003500#ifdef CONFIG_CRYPTO_DEV_TALITOS1
3501 {
3502 .compatible = "fsl,sec1.0",
3503 },
3504#endif
3505#ifdef CONFIG_CRYPTO_DEV_TALITOS2
Kim Phillips9c4a7962008-06-23 19:50:15 +08003506 {
3507 .compatible = "fsl,sec2.0",
3508 },
LEROY Christophe0635b7d2015-04-17 16:32:20 +02003509#endif
Kim Phillips9c4a7962008-06-23 19:50:15 +08003510 {},
3511};
3512MODULE_DEVICE_TABLE(of, talitos_match);
3513
Grant Likely1c48a5c2011-02-17 02:43:24 -07003514static struct platform_driver talitos_driver = {
Grant Likely40182942010-04-13 16:13:02 -07003515 .driver = {
3516 .name = "talitos",
Grant Likely40182942010-04-13 16:13:02 -07003517 .of_match_table = talitos_match,
3518 },
Kim Phillips9c4a7962008-06-23 19:50:15 +08003519 .probe = talitos_probe,
Al Viro596f1032008-11-22 17:34:24 +00003520 .remove = talitos_remove,
Kim Phillips9c4a7962008-06-23 19:50:15 +08003521};
3522
Axel Lin741e8c22011-11-26 21:26:19 +08003523module_platform_driver(talitos_driver);
Kim Phillips9c4a7962008-06-23 19:50:15 +08003524
3525MODULE_LICENSE("GPL");
3526MODULE_AUTHOR("Kim Phillips <kim.phillips@freescale.com>");
3527MODULE_DESCRIPTION("Freescale integrated security engine (SEC) driver");