blob: 3cfd53a00dc18df3bcbcd0ae4e8fac8036da8490 [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
907 return 0;
908
909badkey:
910 crypto_aead_set_flags(authenc, CRYPTO_TFM_RES_BAD_KEY_LEN);
911 return -EINVAL;
912}
913
914/*
Lee Nipper56af8cd2009-03-29 15:50:50 +0800915 * talitos_edesc - s/w-extended descriptor
Kim Phillips9c4a7962008-06-23 19:50:15 +0800916 * @src_nents: number of segments in input scatterlist
917 * @dst_nents: number of segments in output scatterlist
Herbert Xuaeb4c132015-07-30 17:53:22 +0800918 * @icv_ool: whether ICV is out-of-line
Horia Geanta79fd31d2012-08-02 17:16:40 +0300919 * @iv_dma: dma address of iv for checking continuity and link table
Kim Phillips9c4a7962008-06-23 19:50:15 +0800920 * @dma_len: length of dma mapped link_tbl space
LEROY Christophe6f65f6a2015-04-17 16:32:15 +0200921 * @dma_link_tbl: bus physical address of link_tbl/buf
Kim Phillips9c4a7962008-06-23 19:50:15 +0800922 * @desc: h/w descriptor
LEROY Christophe6f65f6a2015-04-17 16:32:15 +0200923 * @link_tbl: input and output h/w link tables (if {src,dst}_nents > 1) (SEC2)
924 * @buf: input and output buffeur (if {src,dst}_nents > 1) (SEC1)
Kim Phillips9c4a7962008-06-23 19:50:15 +0800925 *
926 * if decrypting (with authcheck), or either one of src_nents or dst_nents
927 * is greater than 1, an integrity check value is concatenated to the end
928 * of link_tbl data
929 */
Lee Nipper56af8cd2009-03-29 15:50:50 +0800930struct talitos_edesc {
Kim Phillips9c4a7962008-06-23 19:50:15 +0800931 int src_nents;
932 int dst_nents;
Herbert Xuaeb4c132015-07-30 17:53:22 +0800933 bool icv_ool;
Horia Geanta79fd31d2012-08-02 17:16:40 +0300934 dma_addr_t iv_dma;
Kim Phillips9c4a7962008-06-23 19:50:15 +0800935 int dma_len;
936 dma_addr_t dma_link_tbl;
937 struct talitos_desc desc;
LEROY Christophe6f65f6a2015-04-17 16:32:15 +0200938 union {
939 struct talitos_ptr link_tbl[0];
940 u8 buf[0];
941 };
Kim Phillips9c4a7962008-06-23 19:50:15 +0800942};
943
Lee Nipper4de9d0b2009-03-29 15:52:32 +0800944static void talitos_sg_unmap(struct device *dev,
945 struct talitos_edesc *edesc,
946 struct scatterlist *src,
LEROY Christophe6a1e8d12016-06-06 13:20:38 +0200947 struct scatterlist *dst,
948 unsigned int len, unsigned int offset)
LEROY Christophe246a87c2016-06-06 13:20:36 +0200949{
950 struct talitos_private *priv = dev_get_drvdata(dev);
951 bool is_sec1 = has_ftr_sec1(priv);
LEROY Christophe6a1e8d12016-06-06 13:20:38 +0200952 unsigned int src_nents = edesc->src_nents ? : 1;
953 unsigned int dst_nents = edesc->dst_nents ? : 1;
LEROY Christophe246a87c2016-06-06 13:20:36 +0200954
LEROY Christophe6a1e8d12016-06-06 13:20:38 +0200955 if (is_sec1 && dst && dst_nents > 1) {
956 dma_sync_single_for_device(dev, edesc->dma_link_tbl + offset,
957 len, DMA_FROM_DEVICE);
958 sg_pcopy_from_buffer(dst, dst_nents, edesc->buf + offset, len,
959 offset);
960 }
961 if (src != dst) {
962 if (src_nents == 1 || !is_sec1)
963 dma_unmap_sg(dev, src, src_nents, DMA_TO_DEVICE);
964
965 if (dst && (dst_nents == 1 || !is_sec1))
966 dma_unmap_sg(dev, dst, dst_nents, DMA_FROM_DEVICE);
967 } else if (src_nents == 1 || !is_sec1) {
968 dma_unmap_sg(dev, src, src_nents, DMA_BIDIRECTIONAL);
LEROY Christophe246a87c2016-06-06 13:20:36 +0200969 }
970}
971
Kim Phillips9c4a7962008-06-23 19:50:15 +0800972static void ipsec_esp_unmap(struct device *dev,
Lee Nipper56af8cd2009-03-29 15:50:50 +0800973 struct talitos_edesc *edesc,
Kim Phillips9c4a7962008-06-23 19:50:15 +0800974 struct aead_request *areq)
975{
LEROY Christophe549bd8b2016-06-06 13:20:40 +0200976 struct crypto_aead *aead = crypto_aead_reqtfm(areq);
977 struct talitos_ctx *ctx = crypto_aead_ctx(aead);
978 unsigned int ivsize = crypto_aead_ivsize(aead);
LEROY Christophe9a655602017-10-06 15:04:59 +0200979 bool is_ipsec_esp = edesc->desc.hdr & DESC_HDR_TYPE_IPSEC_ESP;
980 struct talitos_ptr *civ_ptr = &edesc->desc.ptr[is_ipsec_esp ? 2 : 3];
LEROY Christophe549bd8b2016-06-06 13:20:40 +0200981
LEROY Christophe9a655602017-10-06 15:04:59 +0200982 if (is_ipsec_esp)
LEROY Christophe549bd8b2016-06-06 13:20:40 +0200983 unmap_single_talitos_ptr(dev, &edesc->desc.ptr[6],
984 DMA_FROM_DEVICE);
LEROY Christophe9a655602017-10-06 15:04:59 +0200985 unmap_single_talitos_ptr(dev, civ_ptr, DMA_TO_DEVICE);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800986
LEROY Christophe6a1e8d12016-06-06 13:20:38 +0200987 talitos_sg_unmap(dev, edesc, areq->src, areq->dst, areq->cryptlen,
988 areq->assoclen);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800989
990 if (edesc->dma_len)
991 dma_unmap_single(dev, edesc->dma_link_tbl, edesc->dma_len,
992 DMA_BIDIRECTIONAL);
LEROY Christophe549bd8b2016-06-06 13:20:40 +0200993
LEROY Christophe9a655602017-10-06 15:04:59 +0200994 if (!is_ipsec_esp) {
LEROY Christophe549bd8b2016-06-06 13:20:40 +0200995 unsigned int dst_nents = edesc->dst_nents ? : 1;
996
997 sg_pcopy_to_buffer(areq->dst, dst_nents, ctx->iv, ivsize,
998 areq->assoclen + areq->cryptlen - ivsize);
999 }
Kim Phillips9c4a7962008-06-23 19:50:15 +08001000}
1001
1002/*
1003 * ipsec_esp descriptor callbacks
1004 */
1005static void ipsec_esp_encrypt_done(struct device *dev,
1006 struct talitos_desc *desc, void *context,
1007 int err)
1008{
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001009 struct talitos_private *priv = dev_get_drvdata(dev);
1010 bool is_sec1 = has_ftr_sec1(priv);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001011 struct aead_request *areq = context;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001012 struct crypto_aead *authenc = crypto_aead_reqtfm(areq);
Herbert Xuaeb4c132015-07-30 17:53:22 +08001013 unsigned int authsize = crypto_aead_authsize(authenc);
LEROY Christophe2e13ce02017-10-06 15:05:02 +02001014 unsigned int ivsize = crypto_aead_ivsize(authenc);
Kim Phillips19bbbc62009-03-29 15:53:59 +08001015 struct talitos_edesc *edesc;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001016 struct scatterlist *sg;
1017 void *icvdata;
1018
Kim Phillips19bbbc62009-03-29 15:53:59 +08001019 edesc = container_of(desc, struct talitos_edesc, desc);
1020
Kim Phillips9c4a7962008-06-23 19:50:15 +08001021 ipsec_esp_unmap(dev, edesc, areq);
1022
1023 /* copy the generated ICV to dst */
Herbert Xuaeb4c132015-07-30 17:53:22 +08001024 if (edesc->icv_ool) {
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001025 if (is_sec1)
1026 icvdata = edesc->buf + areq->assoclen + areq->cryptlen;
1027 else
1028 icvdata = &edesc->link_tbl[edesc->src_nents +
1029 edesc->dst_nents + 2];
Kim Phillips9c4a7962008-06-23 19:50:15 +08001030 sg = sg_last(areq->dst, edesc->dst_nents);
Herbert Xuaeb4c132015-07-30 17:53:22 +08001031 memcpy((char *)sg_virt(sg) + sg->length - authsize,
1032 icvdata, authsize);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001033 }
1034
LEROY Christophe2e13ce02017-10-06 15:05:02 +02001035 dma_unmap_single(dev, edesc->iv_dma, ivsize, DMA_TO_DEVICE);
1036
Kim Phillips9c4a7962008-06-23 19:50:15 +08001037 kfree(edesc);
1038
1039 aead_request_complete(areq, err);
1040}
1041
Kim Phillipsfe5720e2008-10-12 20:33:14 +08001042static void ipsec_esp_decrypt_swauth_done(struct device *dev,
Kim Phillipse938e462009-03-29 15:53:23 +08001043 struct talitos_desc *desc,
1044 void *context, int err)
Kim Phillips9c4a7962008-06-23 19:50:15 +08001045{
1046 struct aead_request *req = context;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001047 struct crypto_aead *authenc = crypto_aead_reqtfm(req);
Herbert Xuaeb4c132015-07-30 17:53:22 +08001048 unsigned int authsize = crypto_aead_authsize(authenc);
Kim Phillips19bbbc62009-03-29 15:53:59 +08001049 struct talitos_edesc *edesc;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001050 struct scatterlist *sg;
Herbert Xuaeb4c132015-07-30 17:53:22 +08001051 char *oicv, *icv;
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001052 struct talitos_private *priv = dev_get_drvdata(dev);
1053 bool is_sec1 = has_ftr_sec1(priv);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001054
Kim Phillips19bbbc62009-03-29 15:53:59 +08001055 edesc = container_of(desc, struct talitos_edesc, desc);
1056
Kim Phillips9c4a7962008-06-23 19:50:15 +08001057 ipsec_esp_unmap(dev, edesc, req);
1058
1059 if (!err) {
1060 /* auth check */
Kim Phillips9c4a7962008-06-23 19:50:15 +08001061 sg = sg_last(req->dst, edesc->dst_nents ? : 1);
Herbert Xuaeb4c132015-07-30 17:53:22 +08001062 icv = (char *)sg_virt(sg) + sg->length - authsize;
1063
1064 if (edesc->dma_len) {
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001065 if (is_sec1)
1066 oicv = (char *)&edesc->dma_link_tbl +
1067 req->assoclen + req->cryptlen;
1068 else
1069 oicv = (char *)
1070 &edesc->link_tbl[edesc->src_nents +
Herbert Xuaeb4c132015-07-30 17:53:22 +08001071 edesc->dst_nents + 2];
1072 if (edesc->icv_ool)
1073 icv = oicv + authsize;
1074 } else
1075 oicv = (char *)&edesc->link_tbl[0];
1076
David Gstir79960942015-11-15 17:14:42 +01001077 err = crypto_memneq(oicv, icv, authsize) ? -EBADMSG : 0;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001078 }
1079
1080 kfree(edesc);
1081
1082 aead_request_complete(req, err);
1083}
1084
Kim Phillipsfe5720e2008-10-12 20:33:14 +08001085static void ipsec_esp_decrypt_hwauth_done(struct device *dev,
Kim Phillipse938e462009-03-29 15:53:23 +08001086 struct talitos_desc *desc,
1087 void *context, int err)
Kim Phillipsfe5720e2008-10-12 20:33:14 +08001088{
1089 struct aead_request *req = context;
Kim Phillips19bbbc62009-03-29 15:53:59 +08001090 struct talitos_edesc *edesc;
1091
1092 edesc = container_of(desc, struct talitos_edesc, desc);
Kim Phillipsfe5720e2008-10-12 20:33:14 +08001093
1094 ipsec_esp_unmap(dev, edesc, req);
1095
1096 /* check ICV auth status */
Kim Phillipse938e462009-03-29 15:53:23 +08001097 if (!err && ((desc->hdr_lo & DESC_HDR_LO_ICCR1_MASK) !=
1098 DESC_HDR_LO_ICCR1_PASS))
1099 err = -EBADMSG;
Kim Phillipsfe5720e2008-10-12 20:33:14 +08001100
1101 kfree(edesc);
1102
1103 aead_request_complete(req, err);
1104}
1105
Kim Phillips9c4a7962008-06-23 19:50:15 +08001106/*
1107 * convert scatterlist to SEC h/w link table format
1108 * stop at cryptlen bytes
1109 */
Herbert Xuaeb4c132015-07-30 17:53:22 +08001110static int sg_to_link_tbl_offset(struct scatterlist *sg, int sg_count,
1111 unsigned int offset, int cryptlen,
1112 struct talitos_ptr *link_tbl_ptr)
Kim Phillips9c4a7962008-06-23 19:50:15 +08001113{
Lee Nipper70bcaca2008-07-03 19:08:46 +08001114 int n_sg = sg_count;
Herbert Xuaeb4c132015-07-30 17:53:22 +08001115 int count = 0;
Lee Nipper70bcaca2008-07-03 19:08:46 +08001116
Herbert Xuaeb4c132015-07-30 17:53:22 +08001117 while (cryptlen && sg && n_sg--) {
1118 unsigned int len = sg_dma_len(sg);
1119
1120 if (offset >= len) {
1121 offset -= len;
1122 goto next;
1123 }
1124
1125 len -= offset;
1126
1127 if (len > cryptlen)
1128 len = cryptlen;
1129
1130 to_talitos_ptr(link_tbl_ptr + count,
LEROY Christopheda9de142017-10-06 15:04:57 +02001131 sg_dma_address(sg) + offset, len, 0);
LEROY Christopheb096b542016-06-06 13:20:34 +02001132 to_talitos_ptr_ext_set(link_tbl_ptr + count, 0, 0);
Herbert Xuaeb4c132015-07-30 17:53:22 +08001133 count++;
1134 cryptlen -= len;
1135 offset = 0;
1136
1137next:
Cristian Stoica5be4d4c2015-01-20 10:06:16 +02001138 sg = sg_next(sg);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001139 }
1140
Kim Phillips9c4a7962008-06-23 19:50:15 +08001141 /* tag end of link table */
Herbert Xuaeb4c132015-07-30 17:53:22 +08001142 if (count > 0)
LEROY Christopheb096b542016-06-06 13:20:34 +02001143 to_talitos_ptr_ext_set(link_tbl_ptr + count - 1,
1144 DESC_PTR_LNKTBL_RETURN, 0);
Lee Nipper70bcaca2008-07-03 19:08:46 +08001145
Herbert Xuaeb4c132015-07-30 17:53:22 +08001146 return count;
1147}
1148
LEROY Christophe2b122732018-03-22 10:57:01 +01001149static int talitos_sg_map_ext(struct device *dev, struct scatterlist *src,
1150 unsigned int len, struct talitos_edesc *edesc,
1151 struct talitos_ptr *ptr, int sg_count,
1152 unsigned int offset, int tbl_off, int elen)
LEROY Christophe246a87c2016-06-06 13:20:36 +02001153{
LEROY Christophe246a87c2016-06-06 13:20:36 +02001154 struct talitos_private *priv = dev_get_drvdata(dev);
1155 bool is_sec1 = has_ftr_sec1(priv);
1156
LEROY Christophe87a81dc2018-01-26 17:09:59 +01001157 if (!src) {
1158 to_talitos_ptr(ptr, 0, 0, is_sec1);
1159 return 1;
1160 }
LEROY Christophe2b122732018-03-22 10:57:01 +01001161 to_talitos_ptr_ext_set(ptr, elen, is_sec1);
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001162 if (sg_count == 1) {
LEROY Christopheda9de142017-10-06 15:04:57 +02001163 to_talitos_ptr(ptr, sg_dma_address(src) + offset, len, is_sec1);
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001164 return sg_count;
LEROY Christophe246a87c2016-06-06 13:20:36 +02001165 }
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001166 if (is_sec1) {
LEROY Christopheda9de142017-10-06 15:04:57 +02001167 to_talitos_ptr(ptr, edesc->dma_link_tbl + offset, len, is_sec1);
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001168 return sg_count;
1169 }
LEROY Christophe2b122732018-03-22 10:57:01 +01001170 sg_count = sg_to_link_tbl_offset(src, sg_count, offset, len + elen,
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001171 &edesc->link_tbl[tbl_off]);
1172 if (sg_count == 1) {
1173 /* Only one segment now, so no link tbl needed*/
1174 copy_talitos_ptr(ptr, &edesc->link_tbl[tbl_off], is_sec1);
1175 return sg_count;
1176 }
1177 to_talitos_ptr(ptr, edesc->dma_link_tbl +
LEROY Christopheda9de142017-10-06 15:04:57 +02001178 tbl_off * sizeof(struct talitos_ptr), len, is_sec1);
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001179 to_talitos_ptr_ext_or(ptr, DESC_PTR_LNKTBL_JUMP, is_sec1);
1180
LEROY Christophe246a87c2016-06-06 13:20:36 +02001181 return sg_count;
1182}
1183
LEROY Christophe2b122732018-03-22 10:57:01 +01001184static int talitos_sg_map(struct device *dev, struct scatterlist *src,
1185 unsigned int len, struct talitos_edesc *edesc,
1186 struct talitos_ptr *ptr, int sg_count,
1187 unsigned int offset, int tbl_off)
1188{
1189 return talitos_sg_map_ext(dev, src, len, edesc, ptr, sg_count, offset,
1190 tbl_off, 0);
1191}
1192
Kim Phillips9c4a7962008-06-23 19:50:15 +08001193/*
1194 * fill in and submit ipsec_esp descriptor
1195 */
Lee Nipper56af8cd2009-03-29 15:50:50 +08001196static int ipsec_esp(struct talitos_edesc *edesc, struct aead_request *areq,
Herbert Xuaeb4c132015-07-30 17:53:22 +08001197 void (*callback)(struct device *dev,
1198 struct talitos_desc *desc,
1199 void *context, int error))
Kim Phillips9c4a7962008-06-23 19:50:15 +08001200{
1201 struct crypto_aead *aead = crypto_aead_reqtfm(areq);
Herbert Xuaeb4c132015-07-30 17:53:22 +08001202 unsigned int authsize = crypto_aead_authsize(aead);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001203 struct talitos_ctx *ctx = crypto_aead_ctx(aead);
1204 struct device *dev = ctx->dev;
1205 struct talitos_desc *desc = &edesc->desc;
1206 unsigned int cryptlen = areq->cryptlen;
Kim Phillipse41256f2009-08-13 11:49:06 +10001207 unsigned int ivsize = crypto_aead_ivsize(aead);
Herbert Xuaeb4c132015-07-30 17:53:22 +08001208 int tbl_off = 0;
Kim Phillipsfa86a262008-07-17 20:20:06 +08001209 int sg_count, ret;
LEROY Christophe2b122732018-03-22 10:57:01 +01001210 int elen = 0;
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001211 bool sync_needed = false;
1212 struct talitos_private *priv = dev_get_drvdata(dev);
1213 bool is_sec1 = has_ftr_sec1(priv);
LEROY Christophe9a655602017-10-06 15:04:59 +02001214 bool is_ipsec_esp = desc->hdr & DESC_HDR_TYPE_IPSEC_ESP;
1215 struct talitos_ptr *civ_ptr = &desc->ptr[is_ipsec_esp ? 2 : 3];
1216 struct talitos_ptr *ckey_ptr = &desc->ptr[is_ipsec_esp ? 3 : 2];
Kim Phillips9c4a7962008-06-23 19:50:15 +08001217
1218 /* hmac key */
LEROY Christophe2e13ce02017-10-06 15:05:02 +02001219 to_talitos_ptr(&desc->ptr[0], ctx->dma_key, ctx->authkeylen, is_sec1);
Horia Geanta79fd31d2012-08-02 17:16:40 +03001220
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001221 sg_count = edesc->src_nents ?: 1;
1222 if (is_sec1 && sg_count > 1)
1223 sg_copy_to_buffer(areq->src, sg_count, edesc->buf,
1224 areq->assoclen + cryptlen);
1225 else
1226 sg_count = dma_map_sg(dev, areq->src, sg_count,
1227 (areq->src == areq->dst) ?
1228 DMA_BIDIRECTIONAL : DMA_TO_DEVICE);
1229
Kim Phillips9c4a7962008-06-23 19:50:15 +08001230 /* hmac data */
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001231 ret = talitos_sg_map(dev, areq->src, areq->assoclen, edesc,
1232 &desc->ptr[1], sg_count, 0, tbl_off);
Horia Geanta79fd31d2012-08-02 17:16:40 +03001233
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001234 if (ret > 1) {
Horia Geant?340ff602016-04-19 20:33:48 +03001235 tbl_off += ret;
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001236 sync_needed = true;
Horia Geanta79fd31d2012-08-02 17:16:40 +03001237 }
1238
Kim Phillips9c4a7962008-06-23 19:50:15 +08001239 /* cipher iv */
LEROY Christophe9a655602017-10-06 15:04:59 +02001240 to_talitos_ptr(civ_ptr, edesc->iv_dma, ivsize, is_sec1);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001241
1242 /* cipher key */
LEROY Christophe2e13ce02017-10-06 15:05:02 +02001243 to_talitos_ptr(ckey_ptr, ctx->dma_key + ctx->authkeylen,
1244 ctx->enckeylen, is_sec1);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001245
1246 /*
1247 * cipher in
1248 * map and adjust cipher len to aead request cryptlen.
1249 * extent is bytes of HMAC postpended to ciphertext,
1250 * typically 12 for ipsec
1251 */
LEROY Christophe2b122732018-03-22 10:57:01 +01001252 if (is_ipsec_esp && (desc->hdr & DESC_HDR_MODE1_MDEU_CICV))
1253 elen = authsize;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001254
LEROY Christophe2b122732018-03-22 10:57:01 +01001255 ret = talitos_sg_map_ext(dev, areq->src, cryptlen, edesc, &desc->ptr[4],
1256 sg_count, areq->assoclen, tbl_off, elen);
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001257
LEROY Christopheec8c7d12017-10-06 15:04:33 +02001258 if (ret > 1) {
1259 tbl_off += ret;
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001260 sync_needed = true;
Horia Geant?340ff602016-04-19 20:33:48 +03001261 }
Kim Phillips9c4a7962008-06-23 19:50:15 +08001262
1263 /* cipher out */
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001264 if (areq->src != areq->dst) {
1265 sg_count = edesc->dst_nents ? : 1;
1266 if (!is_sec1 || sg_count == 1)
1267 dma_map_sg(dev, areq->dst, sg_count, DMA_FROM_DEVICE);
1268 }
Kim Phillips9c4a7962008-06-23 19:50:15 +08001269
LEROY Christophee04a61b2017-10-06 15:04:35 +02001270 ret = talitos_sg_map(dev, areq->dst, cryptlen, edesc, &desc->ptr[5],
1271 sg_count, areq->assoclen, tbl_off);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001272
LEROY Christophe9a655602017-10-06 15:04:59 +02001273 if (is_ipsec_esp)
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001274 to_talitos_ptr_ext_or(&desc->ptr[5], authsize, is_sec1);
Herbert Xuaeb4c132015-07-30 17:53:22 +08001275
LEROY Christophee04a61b2017-10-06 15:04:35 +02001276 /* ICV data */
1277 if (ret > 1) {
1278 tbl_off += ret;
Herbert Xuaeb4c132015-07-30 17:53:22 +08001279 edesc->icv_ool = true;
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001280 sync_needed = true;
1281
LEROY Christophe9a655602017-10-06 15:04:59 +02001282 if (is_ipsec_esp) {
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001283 struct talitos_ptr *tbl_ptr = &edesc->link_tbl[tbl_off];
1284 int offset = (edesc->src_nents + edesc->dst_nents + 2) *
1285 sizeof(struct talitos_ptr) + authsize;
1286
1287 /* Add an entry to the link table for ICV data */
LEROY Christophee04a61b2017-10-06 15:04:35 +02001288 to_talitos_ptr_ext_set(tbl_ptr - 1, 0, is_sec1);
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001289 to_talitos_ptr_ext_set(tbl_ptr, DESC_PTR_LNKTBL_RETURN,
1290 is_sec1);
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001291
1292 /* icv data follows link tables */
1293 to_talitos_ptr(tbl_ptr, edesc->dma_link_tbl + offset,
LEROY Christopheda9de142017-10-06 15:04:57 +02001294 authsize, is_sec1);
LEROY Christophee04a61b2017-10-06 15:04:35 +02001295 } else {
1296 dma_addr_t addr = edesc->dma_link_tbl;
1297
1298 if (is_sec1)
1299 addr += areq->assoclen + cryptlen;
1300 else
1301 addr += sizeof(struct talitos_ptr) * tbl_off;
1302
LEROY Christopheda9de142017-10-06 15:04:57 +02001303 to_talitos_ptr(&desc->ptr[6], addr, authsize, is_sec1);
LEROY Christophee04a61b2017-10-06 15:04:35 +02001304 }
LEROY Christophe9a655602017-10-06 15:04:59 +02001305 } else if (!is_ipsec_esp) {
LEROY Christophee04a61b2017-10-06 15:04:35 +02001306 ret = talitos_sg_map(dev, areq->dst, authsize, edesc,
1307 &desc->ptr[6], sg_count, areq->assoclen +
1308 cryptlen,
1309 tbl_off);
1310 if (ret > 1) {
1311 tbl_off += ret;
1312 edesc->icv_ool = true;
1313 sync_needed = true;
1314 } else {
1315 edesc->icv_ool = false;
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001316 }
Horia Geant?340ff602016-04-19 20:33:48 +03001317 } else {
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001318 edesc->icv_ool = false;
1319 }
1320
Kim Phillips9c4a7962008-06-23 19:50:15 +08001321 /* iv out */
LEROY Christophe9a655602017-10-06 15:04:59 +02001322 if (is_ipsec_esp)
LEROY Christophe549bd8b2016-06-06 13:20:40 +02001323 map_single_talitos_ptr(dev, &desc->ptr[6], ivsize, ctx->iv,
1324 DMA_FROM_DEVICE);
1325
1326 if (sync_needed)
1327 dma_sync_single_for_device(dev, edesc->dma_link_tbl,
1328 edesc->dma_len,
1329 DMA_BIDIRECTIONAL);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001330
Kim Phillips5228f0f2011-07-15 11:21:38 +08001331 ret = talitos_submit(dev, ctx->ch, desc, callback, areq);
Kim Phillipsfa86a262008-07-17 20:20:06 +08001332 if (ret != -EINPROGRESS) {
1333 ipsec_esp_unmap(dev, edesc, areq);
1334 kfree(edesc);
1335 }
1336 return ret;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001337}
1338
Kim Phillips9c4a7962008-06-23 19:50:15 +08001339/*
Lee Nipper56af8cd2009-03-29 15:50:50 +08001340 * allocate and map the extended descriptor
Kim Phillips9c4a7962008-06-23 19:50:15 +08001341 */
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001342static struct talitos_edesc *talitos_edesc_alloc(struct device *dev,
1343 struct scatterlist *src,
1344 struct scatterlist *dst,
Horia Geanta79fd31d2012-08-02 17:16:40 +03001345 u8 *iv,
1346 unsigned int assoclen,
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001347 unsigned int cryptlen,
1348 unsigned int authsize,
Horia Geanta79fd31d2012-08-02 17:16:40 +03001349 unsigned int ivsize,
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001350 int icv_stashing,
Horia Geanta62293a32013-11-28 15:11:17 +02001351 u32 cryptoflags,
1352 bool encrypt)
Kim Phillips9c4a7962008-06-23 19:50:15 +08001353{
Lee Nipper56af8cd2009-03-29 15:50:50 +08001354 struct talitos_edesc *edesc;
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001355 int src_nents, dst_nents, alloc_len, dma_len, src_len, dst_len;
Horia Geanta79fd31d2012-08-02 17:16:40 +03001356 dma_addr_t iv_dma = 0;
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001357 gfp_t flags = cryptoflags & CRYPTO_TFM_REQ_MAY_SLEEP ? GFP_KERNEL :
Kim Phillips586725f2008-07-17 20:19:18 +08001358 GFP_ATOMIC;
LEROY Christophe6f65f6a2015-04-17 16:32:15 +02001359 struct talitos_private *priv = dev_get_drvdata(dev);
1360 bool is_sec1 = has_ftr_sec1(priv);
1361 int max_len = is_sec1 ? TALITOS1_MAX_DATA_LEN : TALITOS2_MAX_DATA_LEN;
LABBE Corentin8e409fe2015-11-04 21:13:34 +01001362 void *err;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001363
LEROY Christophe6f65f6a2015-04-17 16:32:15 +02001364 if (cryptlen + authsize > max_len) {
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001365 dev_err(dev, "length exceeds h/w max limit\n");
Kim Phillips9c4a7962008-06-23 19:50:15 +08001366 return ERR_PTR(-EINVAL);
1367 }
1368
Horia Geanta935e99a2013-11-19 14:57:49 +02001369 if (ivsize)
Horia Geanta79fd31d2012-08-02 17:16:40 +03001370 iv_dma = dma_map_single(dev, iv, ivsize, DMA_TO_DEVICE);
1371
Horia Geanta62293a32013-11-28 15:11:17 +02001372 if (!dst || dst == src) {
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001373 src_len = assoclen + cryptlen + authsize;
1374 src_nents = sg_nents_for_len(src, src_len);
LABBE Corentin8e409fe2015-11-04 21:13:34 +01001375 if (src_nents < 0) {
1376 dev_err(dev, "Invalid number of src SG.\n");
1377 err = ERR_PTR(-EINVAL);
1378 goto error_sg;
1379 }
Horia Geanta62293a32013-11-28 15:11:17 +02001380 src_nents = (src_nents == 1) ? 0 : src_nents;
1381 dst_nents = dst ? src_nents : 0;
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001382 dst_len = 0;
Horia Geanta62293a32013-11-28 15:11:17 +02001383 } else { /* dst && dst != src*/
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001384 src_len = assoclen + cryptlen + (encrypt ? 0 : authsize);
1385 src_nents = sg_nents_for_len(src, src_len);
LABBE Corentin8e409fe2015-11-04 21:13:34 +01001386 if (src_nents < 0) {
1387 dev_err(dev, "Invalid number of src SG.\n");
1388 err = ERR_PTR(-EINVAL);
1389 goto error_sg;
1390 }
Horia Geanta62293a32013-11-28 15:11:17 +02001391 src_nents = (src_nents == 1) ? 0 : src_nents;
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001392 dst_len = assoclen + cryptlen + (encrypt ? authsize : 0);
1393 dst_nents = sg_nents_for_len(dst, dst_len);
LABBE Corentin8e409fe2015-11-04 21:13:34 +01001394 if (dst_nents < 0) {
1395 dev_err(dev, "Invalid number of dst SG.\n");
1396 err = ERR_PTR(-EINVAL);
1397 goto error_sg;
1398 }
Horia Geanta62293a32013-11-28 15:11:17 +02001399 dst_nents = (dst_nents == 1) ? 0 : dst_nents;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001400 }
1401
1402 /*
1403 * allocate space for base edesc plus the link tables,
Herbert Xuaeb4c132015-07-30 17:53:22 +08001404 * allowing for two separate entries for AD and generated ICV (+ 2),
1405 * and space for two sets of ICVs (stashed and generated)
Kim Phillips9c4a7962008-06-23 19:50:15 +08001406 */
Lee Nipper56af8cd2009-03-29 15:50:50 +08001407 alloc_len = sizeof(struct talitos_edesc);
Herbert Xuaeb4c132015-07-30 17:53:22 +08001408 if (src_nents || dst_nents) {
LEROY Christophe6f65f6a2015-04-17 16:32:15 +02001409 if (is_sec1)
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001410 dma_len = (src_nents ? src_len : 0) +
1411 (dst_nents ? dst_len : 0);
LEROY Christophe6f65f6a2015-04-17 16:32:15 +02001412 else
Herbert Xuaeb4c132015-07-30 17:53:22 +08001413 dma_len = (src_nents + dst_nents + 2) *
1414 sizeof(struct talitos_ptr) + authsize * 2;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001415 alloc_len += dma_len;
1416 } else {
1417 dma_len = 0;
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001418 alloc_len += icv_stashing ? authsize : 0;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001419 }
1420
LEROY Christophe37b5e882017-10-06 15:05:06 +02001421 /* if its a ahash, add space for a second desc next to the first one */
1422 if (is_sec1 && !dst)
1423 alloc_len += sizeof(struct talitos_desc);
1424
Kim Phillips586725f2008-07-17 20:19:18 +08001425 edesc = kmalloc(alloc_len, GFP_DMA | flags);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001426 if (!edesc) {
LABBE Corentin8e409fe2015-11-04 21:13:34 +01001427 err = ERR_PTR(-ENOMEM);
1428 goto error_sg;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001429 }
LEROY Christophee4a647c2017-10-06 15:04:45 +02001430 memset(&edesc->desc, 0, sizeof(edesc->desc));
Kim Phillips9c4a7962008-06-23 19:50:15 +08001431
1432 edesc->src_nents = src_nents;
1433 edesc->dst_nents = dst_nents;
Horia Geanta79fd31d2012-08-02 17:16:40 +03001434 edesc->iv_dma = iv_dma;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001435 edesc->dma_len = dma_len;
LEROY Christophe37b5e882017-10-06 15:05:06 +02001436 if (dma_len) {
1437 void *addr = &edesc->link_tbl[0];
1438
1439 if (is_sec1 && !dst)
1440 addr += sizeof(struct talitos_desc);
1441 edesc->dma_link_tbl = dma_map_single(dev, addr,
Lee Nipper497f2e62010-05-19 19:20:36 +10001442 edesc->dma_len,
1443 DMA_BIDIRECTIONAL);
LEROY Christophe37b5e882017-10-06 15:05:06 +02001444 }
Kim Phillips9c4a7962008-06-23 19:50:15 +08001445 return edesc;
LABBE Corentin8e409fe2015-11-04 21:13:34 +01001446error_sg:
1447 if (iv_dma)
1448 dma_unmap_single(dev, iv_dma, ivsize, DMA_TO_DEVICE);
1449 return err;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001450}
1451
Horia Geanta79fd31d2012-08-02 17:16:40 +03001452static struct talitos_edesc *aead_edesc_alloc(struct aead_request *areq, u8 *iv,
Horia Geanta62293a32013-11-28 15:11:17 +02001453 int icv_stashing, bool encrypt)
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001454{
1455 struct crypto_aead *authenc = crypto_aead_reqtfm(areq);
Herbert Xuaeb4c132015-07-30 17:53:22 +08001456 unsigned int authsize = crypto_aead_authsize(authenc);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001457 struct talitos_ctx *ctx = crypto_aead_ctx(authenc);
Horia Geanta79fd31d2012-08-02 17:16:40 +03001458 unsigned int ivsize = crypto_aead_ivsize(authenc);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001459
Herbert Xuaeb4c132015-07-30 17:53:22 +08001460 return talitos_edesc_alloc(ctx->dev, areq->src, areq->dst,
Horia Geanta79fd31d2012-08-02 17:16:40 +03001461 iv, areq->assoclen, areq->cryptlen,
Herbert Xuaeb4c132015-07-30 17:53:22 +08001462 authsize, ivsize, icv_stashing,
Horia Geanta62293a32013-11-28 15:11:17 +02001463 areq->base.flags, encrypt);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001464}
1465
Lee Nipper56af8cd2009-03-29 15:50:50 +08001466static int aead_encrypt(struct aead_request *req)
Kim Phillips9c4a7962008-06-23 19:50:15 +08001467{
1468 struct crypto_aead *authenc = crypto_aead_reqtfm(req);
1469 struct talitos_ctx *ctx = crypto_aead_ctx(authenc);
Lee Nipper56af8cd2009-03-29 15:50:50 +08001470 struct talitos_edesc *edesc;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001471
1472 /* allocate extended descriptor */
Horia Geanta62293a32013-11-28 15:11:17 +02001473 edesc = aead_edesc_alloc(req, req->iv, 0, true);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001474 if (IS_ERR(edesc))
1475 return PTR_ERR(edesc);
1476
1477 /* set encrypt */
Lee Nipper70bcaca2008-07-03 19:08:46 +08001478 edesc->desc.hdr = ctx->desc_hdr_template | DESC_HDR_MODE0_ENCRYPT;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001479
Herbert Xuaeb4c132015-07-30 17:53:22 +08001480 return ipsec_esp(edesc, req, ipsec_esp_encrypt_done);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001481}
1482
Lee Nipper56af8cd2009-03-29 15:50:50 +08001483static int aead_decrypt(struct aead_request *req)
Kim Phillips9c4a7962008-06-23 19:50:15 +08001484{
1485 struct crypto_aead *authenc = crypto_aead_reqtfm(req);
Herbert Xuaeb4c132015-07-30 17:53:22 +08001486 unsigned int authsize = crypto_aead_authsize(authenc);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001487 struct talitos_ctx *ctx = crypto_aead_ctx(authenc);
Kim Phillipsfe5720e2008-10-12 20:33:14 +08001488 struct talitos_private *priv = dev_get_drvdata(ctx->dev);
Lee Nipper56af8cd2009-03-29 15:50:50 +08001489 struct talitos_edesc *edesc;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001490 struct scatterlist *sg;
1491 void *icvdata;
1492
1493 req->cryptlen -= authsize;
1494
1495 /* allocate extended descriptor */
Horia Geanta62293a32013-11-28 15:11:17 +02001496 edesc = aead_edesc_alloc(req, req->iv, 1, false);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001497 if (IS_ERR(edesc))
1498 return PTR_ERR(edesc);
1499
Kim Phillipsfe5720e2008-10-12 20:33:14 +08001500 if ((priv->features & TALITOS_FTR_HW_AUTH_CHECK) &&
Kim Phillipse938e462009-03-29 15:53:23 +08001501 ((!edesc->src_nents && !edesc->dst_nents) ||
1502 priv->features & TALITOS_FTR_SRC_LINK_TBL_LEN_INCLUDES_EXTENT)) {
Kim Phillips9c4a7962008-06-23 19:50:15 +08001503
Kim Phillipsfe5720e2008-10-12 20:33:14 +08001504 /* decrypt and check the ICV */
Kim Phillipse938e462009-03-29 15:53:23 +08001505 edesc->desc.hdr = ctx->desc_hdr_template |
1506 DESC_HDR_DIR_INBOUND |
Kim Phillipsfe5720e2008-10-12 20:33:14 +08001507 DESC_HDR_MODE1_MDEU_CICV;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001508
Kim Phillipsfe5720e2008-10-12 20:33:14 +08001509 /* reset integrity check result bits */
Kim Phillips9c4a7962008-06-23 19:50:15 +08001510
Herbert Xuaeb4c132015-07-30 17:53:22 +08001511 return ipsec_esp(edesc, req, ipsec_esp_decrypt_hwauth_done);
Kim Phillipsfe5720e2008-10-12 20:33:14 +08001512 }
Kim Phillipse938e462009-03-29 15:53:23 +08001513
1514 /* Have to check the ICV with software */
1515 edesc->desc.hdr = ctx->desc_hdr_template | DESC_HDR_DIR_INBOUND;
1516
1517 /* stash incoming ICV for later cmp with ICV generated by the h/w */
1518 if (edesc->dma_len)
Herbert Xuaeb4c132015-07-30 17:53:22 +08001519 icvdata = (char *)&edesc->link_tbl[edesc->src_nents +
1520 edesc->dst_nents + 2];
Kim Phillipse938e462009-03-29 15:53:23 +08001521 else
1522 icvdata = &edesc->link_tbl[0];
1523
1524 sg = sg_last(req->src, edesc->src_nents ? : 1);
1525
Herbert Xuaeb4c132015-07-30 17:53:22 +08001526 memcpy(icvdata, (char *)sg_virt(sg) + sg->length - authsize, authsize);
Kim Phillipse938e462009-03-29 15:53:23 +08001527
Herbert Xuaeb4c132015-07-30 17:53:22 +08001528 return ipsec_esp(edesc, req, ipsec_esp_decrypt_swauth_done);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001529}
1530
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001531static int ablkcipher_setkey(struct crypto_ablkcipher *cipher,
1532 const u8 *key, unsigned int keylen)
1533{
1534 struct talitos_ctx *ctx = crypto_ablkcipher_ctx(cipher);
LEROY Christophe2e13ce02017-10-06 15:05:02 +02001535 struct device *dev = ctx->dev;
LEROY Christophef384cdc2017-10-06 15:04:37 +02001536 u32 tmp[DES_EXPKEY_WORDS];
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001537
Martin Hicks03d2c512017-05-02 09:38:35 -04001538 if (keylen > TALITOS_MAX_KEY_SIZE) {
1539 crypto_ablkcipher_set_flags(cipher, CRYPTO_TFM_RES_BAD_KEY_LEN);
1540 return -EINVAL;
1541 }
1542
LEROY Christophef384cdc2017-10-06 15:04:37 +02001543 if (unlikely(crypto_ablkcipher_get_flags(cipher) &
1544 CRYPTO_TFM_REQ_WEAK_KEY) &&
1545 !des_ekey(tmp, key)) {
1546 crypto_ablkcipher_set_flags(cipher, CRYPTO_TFM_RES_WEAK_KEY);
1547 return -EINVAL;
1548 }
1549
LEROY Christophe2e13ce02017-10-06 15:05:02 +02001550 if (ctx->keylen)
1551 dma_unmap_single(dev, ctx->dma_key, ctx->keylen, DMA_TO_DEVICE);
1552
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001553 memcpy(&ctx->key, key, keylen);
1554 ctx->keylen = keylen;
1555
LEROY Christophe2e13ce02017-10-06 15:05:02 +02001556 ctx->dma_key = dma_map_single(dev, ctx->key, keylen, DMA_TO_DEVICE);
1557
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001558 return 0;
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001559}
1560
1561static void common_nonsnoop_unmap(struct device *dev,
1562 struct talitos_edesc *edesc,
1563 struct ablkcipher_request *areq)
1564{
1565 unmap_single_talitos_ptr(dev, &edesc->desc.ptr[5], DMA_FROM_DEVICE);
LEROY Christophe032d1972015-04-17 16:31:51 +02001566
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001567 talitos_sg_unmap(dev, edesc, areq->src, areq->dst, areq->nbytes, 0);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001568 unmap_single_talitos_ptr(dev, &edesc->desc.ptr[1], DMA_TO_DEVICE);
1569
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001570 if (edesc->dma_len)
1571 dma_unmap_single(dev, edesc->dma_link_tbl, edesc->dma_len,
1572 DMA_BIDIRECTIONAL);
1573}
1574
1575static void ablkcipher_done(struct device *dev,
1576 struct talitos_desc *desc, void *context,
1577 int err)
1578{
1579 struct ablkcipher_request *areq = context;
Kim Phillips19bbbc62009-03-29 15:53:59 +08001580 struct talitos_edesc *edesc;
1581
1582 edesc = container_of(desc, struct talitos_edesc, desc);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001583
1584 common_nonsnoop_unmap(dev, edesc, areq);
1585
1586 kfree(edesc);
1587
1588 areq->base.complete(&areq->base, err);
1589}
1590
1591static int common_nonsnoop(struct talitos_edesc *edesc,
1592 struct ablkcipher_request *areq,
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001593 void (*callback) (struct device *dev,
1594 struct talitos_desc *desc,
1595 void *context, int error))
1596{
1597 struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(areq);
1598 struct talitos_ctx *ctx = crypto_ablkcipher_ctx(cipher);
1599 struct device *dev = ctx->dev;
1600 struct talitos_desc *desc = &edesc->desc;
1601 unsigned int cryptlen = areq->nbytes;
Horia Geanta79fd31d2012-08-02 17:16:40 +03001602 unsigned int ivsize = crypto_ablkcipher_ivsize(cipher);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001603 int sg_count, ret;
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001604 bool sync_needed = false;
LEROY Christophe922f9dc2015-04-17 16:32:07 +02001605 struct talitos_private *priv = dev_get_drvdata(dev);
1606 bool is_sec1 = has_ftr_sec1(priv);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001607
1608 /* first DWORD empty */
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001609
1610 /* cipher iv */
LEROY Christopheda9de142017-10-06 15:04:57 +02001611 to_talitos_ptr(&desc->ptr[1], edesc->iv_dma, ivsize, is_sec1);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001612
1613 /* cipher key */
LEROY Christophe2e13ce02017-10-06 15:05:02 +02001614 to_talitos_ptr(&desc->ptr[2], ctx->dma_key, ctx->keylen, is_sec1);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001615
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001616 sg_count = edesc->src_nents ?: 1;
1617 if (is_sec1 && sg_count > 1)
1618 sg_copy_to_buffer(areq->src, sg_count, edesc->buf,
1619 cryptlen);
1620 else
1621 sg_count = dma_map_sg(dev, areq->src, sg_count,
1622 (areq->src == areq->dst) ?
1623 DMA_BIDIRECTIONAL : DMA_TO_DEVICE);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001624 /*
1625 * cipher in
1626 */
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001627 sg_count = talitos_sg_map(dev, areq->src, cryptlen, edesc,
1628 &desc->ptr[3], sg_count, 0, 0);
1629 if (sg_count > 1)
1630 sync_needed = true;
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001631
1632 /* cipher out */
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001633 if (areq->src != areq->dst) {
1634 sg_count = edesc->dst_nents ? : 1;
1635 if (!is_sec1 || sg_count == 1)
1636 dma_map_sg(dev, areq->dst, sg_count, DMA_FROM_DEVICE);
1637 }
1638
1639 ret = talitos_sg_map(dev, areq->dst, cryptlen, edesc, &desc->ptr[4],
1640 sg_count, 0, (edesc->src_nents + 1));
1641 if (ret > 1)
1642 sync_needed = true;
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001643
1644 /* iv out */
LEROY Christophea2b35aa2015-04-17 16:31:57 +02001645 map_single_talitos_ptr(dev, &desc->ptr[5], ivsize, ctx->iv,
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001646 DMA_FROM_DEVICE);
1647
1648 /* last DWORD empty */
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001649
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001650 if (sync_needed)
1651 dma_sync_single_for_device(dev, edesc->dma_link_tbl,
1652 edesc->dma_len, DMA_BIDIRECTIONAL);
1653
Kim Phillips5228f0f2011-07-15 11:21:38 +08001654 ret = talitos_submit(dev, ctx->ch, desc, callback, areq);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001655 if (ret != -EINPROGRESS) {
1656 common_nonsnoop_unmap(dev, edesc, areq);
1657 kfree(edesc);
1658 }
1659 return ret;
1660}
1661
Kim Phillipse938e462009-03-29 15:53:23 +08001662static struct talitos_edesc *ablkcipher_edesc_alloc(struct ablkcipher_request *
Horia Geanta62293a32013-11-28 15:11:17 +02001663 areq, bool encrypt)
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001664{
1665 struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(areq);
1666 struct talitos_ctx *ctx = crypto_ablkcipher_ctx(cipher);
Horia Geanta79fd31d2012-08-02 17:16:40 +03001667 unsigned int ivsize = crypto_ablkcipher_ivsize(cipher);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001668
Herbert Xuaeb4c132015-07-30 17:53:22 +08001669 return talitos_edesc_alloc(ctx->dev, areq->src, areq->dst,
Horia Geanta79fd31d2012-08-02 17:16:40 +03001670 areq->info, 0, areq->nbytes, 0, ivsize, 0,
Horia Geanta62293a32013-11-28 15:11:17 +02001671 areq->base.flags, encrypt);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001672}
1673
1674static int ablkcipher_encrypt(struct ablkcipher_request *areq)
1675{
1676 struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(areq);
1677 struct talitos_ctx *ctx = crypto_ablkcipher_ctx(cipher);
1678 struct talitos_edesc *edesc;
1679
1680 /* allocate extended descriptor */
Horia Geanta62293a32013-11-28 15:11:17 +02001681 edesc = ablkcipher_edesc_alloc(areq, true);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001682 if (IS_ERR(edesc))
1683 return PTR_ERR(edesc);
1684
1685 /* set encrypt */
1686 edesc->desc.hdr = ctx->desc_hdr_template | DESC_HDR_MODE0_ENCRYPT;
1687
Kim Phillipsfebec542011-07-15 11:21:39 +08001688 return common_nonsnoop(edesc, areq, ablkcipher_done);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001689}
1690
1691static int ablkcipher_decrypt(struct ablkcipher_request *areq)
1692{
1693 struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(areq);
1694 struct talitos_ctx *ctx = crypto_ablkcipher_ctx(cipher);
1695 struct talitos_edesc *edesc;
1696
1697 /* allocate extended descriptor */
Horia Geanta62293a32013-11-28 15:11:17 +02001698 edesc = ablkcipher_edesc_alloc(areq, false);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001699 if (IS_ERR(edesc))
1700 return PTR_ERR(edesc);
1701
1702 edesc->desc.hdr = ctx->desc_hdr_template | DESC_HDR_DIR_INBOUND;
1703
Kim Phillipsfebec542011-07-15 11:21:39 +08001704 return common_nonsnoop(edesc, areq, ablkcipher_done);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001705}
1706
Lee Nipper497f2e62010-05-19 19:20:36 +10001707static void common_nonsnoop_hash_unmap(struct device *dev,
1708 struct talitos_edesc *edesc,
1709 struct ahash_request *areq)
1710{
1711 struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
LEROY Christophead4cd512018-02-26 17:40:04 +01001712 struct talitos_private *priv = dev_get_drvdata(dev);
1713 bool is_sec1 = has_ftr_sec1(priv);
1714 struct talitos_desc *desc = &edesc->desc;
1715 struct talitos_desc *desc2 = desc + 1;
1716
1717 unmap_single_talitos_ptr(dev, &edesc->desc.ptr[5], DMA_FROM_DEVICE);
1718 if (desc->next_desc &&
1719 desc->ptr[5].ptr != desc2->ptr[5].ptr)
1720 unmap_single_talitos_ptr(dev, &desc2->ptr[5], DMA_FROM_DEVICE);
Lee Nipper497f2e62010-05-19 19:20:36 +10001721
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001722 talitos_sg_unmap(dev, edesc, req_ctx->psrc, NULL, 0, 0);
LEROY Christophe032d1972015-04-17 16:31:51 +02001723
LEROY Christophead4cd512018-02-26 17:40:04 +01001724 /* When using hashctx-in, must unmap it. */
1725 if (from_talitos_ptr_len(&edesc->desc.ptr[1], is_sec1))
1726 unmap_single_talitos_ptr(dev, &edesc->desc.ptr[1],
1727 DMA_TO_DEVICE);
1728 else if (desc->next_desc)
1729 unmap_single_talitos_ptr(dev, &desc2->ptr[1],
1730 DMA_TO_DEVICE);
1731
1732 if (is_sec1 && req_ctx->nbuf)
1733 unmap_single_talitos_ptr(dev, &desc->ptr[3],
1734 DMA_TO_DEVICE);
1735
Lee Nipper497f2e62010-05-19 19:20:36 +10001736 if (edesc->dma_len)
1737 dma_unmap_single(dev, edesc->dma_link_tbl, edesc->dma_len,
1738 DMA_BIDIRECTIONAL);
1739
LEROY Christophe37b5e882017-10-06 15:05:06 +02001740 if (edesc->desc.next_desc)
1741 dma_unmap_single(dev, be32_to_cpu(edesc->desc.next_desc),
1742 TALITOS_DESC_SIZE, DMA_BIDIRECTIONAL);
Lee Nipper497f2e62010-05-19 19:20:36 +10001743}
1744
1745static void ahash_done(struct device *dev,
1746 struct talitos_desc *desc, void *context,
1747 int err)
1748{
1749 struct ahash_request *areq = context;
1750 struct talitos_edesc *edesc =
1751 container_of(desc, struct talitos_edesc, desc);
1752 struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
1753
1754 if (!req_ctx->last && req_ctx->to_hash_later) {
1755 /* Position any partial block for next update/final/finup */
LEROY Christophe3c0dd192017-10-06 15:05:08 +02001756 req_ctx->buf_idx = (req_ctx->buf_idx + 1) & 1;
Lee Nipper5e833bc2010-06-16 15:29:15 +10001757 req_ctx->nbuf = req_ctx->to_hash_later;
Lee Nipper497f2e62010-05-19 19:20:36 +10001758 }
1759 common_nonsnoop_hash_unmap(dev, edesc, areq);
1760
1761 kfree(edesc);
1762
1763 areq->base.complete(&areq->base, err);
1764}
1765
LEROY Christophe2d029052015-04-17 16:32:18 +02001766/*
1767 * SEC1 doesn't like hashing of 0 sized message, so we do the padding
1768 * ourself and submit a padded block
1769 */
LEROY Christophe5b2cf262017-10-06 15:04:47 +02001770static void talitos_handle_buggy_hash(struct talitos_ctx *ctx,
LEROY Christophe2d029052015-04-17 16:32:18 +02001771 struct talitos_edesc *edesc,
1772 struct talitos_ptr *ptr)
1773{
1774 static u8 padded_hash[64] = {
1775 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1776 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1777 0, 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 };
1780
1781 pr_err_once("Bug in SEC1, padding ourself\n");
1782 edesc->desc.hdr &= ~DESC_HDR_MODE0_MDEU_PAD;
1783 map_single_talitos_ptr(ctx->dev, ptr, sizeof(padded_hash),
1784 (char *)padded_hash, DMA_TO_DEVICE);
1785}
1786
Lee Nipper497f2e62010-05-19 19:20:36 +10001787static int common_nonsnoop_hash(struct talitos_edesc *edesc,
1788 struct ahash_request *areq, unsigned int length,
LEROY Christophe37b5e882017-10-06 15:05:06 +02001789 unsigned int offset,
Lee Nipper497f2e62010-05-19 19:20:36 +10001790 void (*callback) (struct device *dev,
1791 struct talitos_desc *desc,
1792 void *context, int error))
1793{
1794 struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
1795 struct talitos_ctx *ctx = crypto_ahash_ctx(tfm);
1796 struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
1797 struct device *dev = ctx->dev;
1798 struct talitos_desc *desc = &edesc->desc;
LEROY Christophe032d1972015-04-17 16:31:51 +02001799 int ret;
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001800 bool sync_needed = false;
LEROY Christophe922f9dc2015-04-17 16:32:07 +02001801 struct talitos_private *priv = dev_get_drvdata(dev);
1802 bool is_sec1 = has_ftr_sec1(priv);
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001803 int sg_count;
Lee Nipper497f2e62010-05-19 19:20:36 +10001804
1805 /* first DWORD empty */
Lee Nipper497f2e62010-05-19 19:20:36 +10001806
Kim Phillips60f208d2010-05-19 19:21:53 +10001807 /* hash context in */
1808 if (!req_ctx->first || req_ctx->swinit) {
LEROY Christophe6a4967c2018-02-26 17:40:06 +01001809 map_single_talitos_ptr_nosync(dev, &desc->ptr[1],
1810 req_ctx->hw_context_size,
1811 req_ctx->hw_context,
1812 DMA_TO_DEVICE);
Kim Phillips60f208d2010-05-19 19:21:53 +10001813 req_ctx->swinit = 0;
Lee Nipper497f2e62010-05-19 19:20:36 +10001814 }
LEROY Christopheafd62fa2017-09-13 12:44:51 +02001815 /* Indicate next op is not the first. */
1816 req_ctx->first = 0;
Lee Nipper497f2e62010-05-19 19:20:36 +10001817
1818 /* HMAC key */
1819 if (ctx->keylen)
LEROY Christophe2e13ce02017-10-06 15:05:02 +02001820 to_talitos_ptr(&desc->ptr[2], ctx->dma_key, ctx->keylen,
1821 is_sec1);
Lee Nipper497f2e62010-05-19 19:20:36 +10001822
LEROY Christophe37b5e882017-10-06 15:05:06 +02001823 if (is_sec1 && req_ctx->nbuf)
1824 length -= req_ctx->nbuf;
1825
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001826 sg_count = edesc->src_nents ?: 1;
1827 if (is_sec1 && sg_count > 1)
LEROY Christophe37b5e882017-10-06 15:05:06 +02001828 sg_pcopy_to_buffer(req_ctx->psrc, sg_count,
1829 edesc->buf + sizeof(struct talitos_desc),
1830 length, req_ctx->nbuf);
1831 else if (length)
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001832 sg_count = dma_map_sg(dev, req_ctx->psrc, sg_count,
1833 DMA_TO_DEVICE);
Lee Nipper497f2e62010-05-19 19:20:36 +10001834 /*
1835 * data in
1836 */
LEROY Christophe37b5e882017-10-06 15:05:06 +02001837 if (is_sec1 && req_ctx->nbuf) {
LEROY Christophead4cd512018-02-26 17:40:04 +01001838 map_single_talitos_ptr(dev, &desc->ptr[3], req_ctx->nbuf,
1839 req_ctx->buf[req_ctx->buf_idx],
1840 DMA_TO_DEVICE);
LEROY Christophe37b5e882017-10-06 15:05:06 +02001841 } else {
1842 sg_count = talitos_sg_map(dev, req_ctx->psrc, length, edesc,
1843 &desc->ptr[3], sg_count, offset, 0);
1844 if (sg_count > 1)
1845 sync_needed = true;
1846 }
Lee Nipper497f2e62010-05-19 19:20:36 +10001847
1848 /* fifth DWORD empty */
Lee Nipper497f2e62010-05-19 19:20:36 +10001849
1850 /* hash/HMAC out -or- hash context out */
1851 if (req_ctx->last)
1852 map_single_talitos_ptr(dev, &desc->ptr[5],
1853 crypto_ahash_digestsize(tfm),
LEROY Christophea2b35aa2015-04-17 16:31:57 +02001854 areq->result, DMA_FROM_DEVICE);
Lee Nipper497f2e62010-05-19 19:20:36 +10001855 else
LEROY Christophe6a4967c2018-02-26 17:40:06 +01001856 map_single_talitos_ptr_nosync(dev, &desc->ptr[5],
1857 req_ctx->hw_context_size,
1858 req_ctx->hw_context,
1859 DMA_FROM_DEVICE);
Lee Nipper497f2e62010-05-19 19:20:36 +10001860
1861 /* last DWORD empty */
Lee Nipper497f2e62010-05-19 19:20:36 +10001862
LEROY Christophe2d029052015-04-17 16:32:18 +02001863 if (is_sec1 && from_talitos_ptr_len(&desc->ptr[3], true) == 0)
1864 talitos_handle_buggy_hash(ctx, edesc, &desc->ptr[3]);
1865
LEROY Christophe37b5e882017-10-06 15:05:06 +02001866 if (is_sec1 && req_ctx->nbuf && length) {
1867 struct talitos_desc *desc2 = desc + 1;
1868 dma_addr_t next_desc;
1869
1870 memset(desc2, 0, sizeof(*desc2));
1871 desc2->hdr = desc->hdr;
1872 desc2->hdr &= ~DESC_HDR_MODE0_MDEU_INIT;
1873 desc2->hdr1 = desc2->hdr;
1874 desc->hdr &= ~DESC_HDR_MODE0_MDEU_PAD;
1875 desc->hdr |= DESC_HDR_MODE0_MDEU_CONT;
1876 desc->hdr &= ~DESC_HDR_DONE_NOTIFY;
1877
LEROY Christophead4cd512018-02-26 17:40:04 +01001878 if (desc->ptr[1].ptr)
1879 copy_talitos_ptr(&desc2->ptr[1], &desc->ptr[1],
1880 is_sec1);
1881 else
LEROY Christophe6a4967c2018-02-26 17:40:06 +01001882 map_single_talitos_ptr_nosync(dev, &desc2->ptr[1],
1883 req_ctx->hw_context_size,
1884 req_ctx->hw_context,
1885 DMA_TO_DEVICE);
LEROY Christophe37b5e882017-10-06 15:05:06 +02001886 copy_talitos_ptr(&desc2->ptr[2], &desc->ptr[2], is_sec1);
1887 sg_count = talitos_sg_map(dev, req_ctx->psrc, length, edesc,
1888 &desc2->ptr[3], sg_count, offset, 0);
1889 if (sg_count > 1)
1890 sync_needed = true;
1891 copy_talitos_ptr(&desc2->ptr[5], &desc->ptr[5], is_sec1);
1892 if (req_ctx->last)
LEROY Christophe6a4967c2018-02-26 17:40:06 +01001893 map_single_talitos_ptr_nosync(dev, &desc->ptr[5],
1894 req_ctx->hw_context_size,
1895 req_ctx->hw_context,
1896 DMA_FROM_DEVICE);
LEROY Christophe37b5e882017-10-06 15:05:06 +02001897
1898 next_desc = dma_map_single(dev, &desc2->hdr1, TALITOS_DESC_SIZE,
1899 DMA_BIDIRECTIONAL);
1900 desc->next_desc = cpu_to_be32(next_desc);
1901 }
1902
LEROY Christophe6a1e8d12016-06-06 13:20:38 +02001903 if (sync_needed)
1904 dma_sync_single_for_device(dev, edesc->dma_link_tbl,
1905 edesc->dma_len, DMA_BIDIRECTIONAL);
1906
Kim Phillips5228f0f2011-07-15 11:21:38 +08001907 ret = talitos_submit(dev, ctx->ch, desc, callback, areq);
Lee Nipper497f2e62010-05-19 19:20:36 +10001908 if (ret != -EINPROGRESS) {
1909 common_nonsnoop_hash_unmap(dev, edesc, areq);
1910 kfree(edesc);
1911 }
1912 return ret;
1913}
1914
1915static struct talitos_edesc *ahash_edesc_alloc(struct ahash_request *areq,
1916 unsigned int nbytes)
1917{
1918 struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
1919 struct talitos_ctx *ctx = crypto_ahash_ctx(tfm);
1920 struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
LEROY Christophe37b5e882017-10-06 15:05:06 +02001921 struct talitos_private *priv = dev_get_drvdata(ctx->dev);
1922 bool is_sec1 = has_ftr_sec1(priv);
1923
1924 if (is_sec1)
1925 nbytes -= req_ctx->nbuf;
Lee Nipper497f2e62010-05-19 19:20:36 +10001926
Herbert Xuaeb4c132015-07-30 17:53:22 +08001927 return talitos_edesc_alloc(ctx->dev, req_ctx->psrc, NULL, NULL, 0,
Horia Geanta62293a32013-11-28 15:11:17 +02001928 nbytes, 0, 0, 0, areq->base.flags, false);
Lee Nipper497f2e62010-05-19 19:20:36 +10001929}
1930
1931static int ahash_init(struct ahash_request *areq)
1932{
1933 struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
LEROY Christophe6a4967c2018-02-26 17:40:06 +01001934 struct talitos_ctx *ctx = crypto_ahash_ctx(tfm);
1935 struct device *dev = ctx->dev;
Lee Nipper497f2e62010-05-19 19:20:36 +10001936 struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
LEROY Christophe49f97832017-10-06 15:05:04 +02001937 unsigned int size;
LEROY Christophe6a4967c2018-02-26 17:40:06 +01001938 dma_addr_t dma;
Lee Nipper497f2e62010-05-19 19:20:36 +10001939
1940 /* Initialize the context */
LEROY Christophe3c0dd192017-10-06 15:05:08 +02001941 req_ctx->buf_idx = 0;
Lee Nipper5e833bc2010-06-16 15:29:15 +10001942 req_ctx->nbuf = 0;
Kim Phillips60f208d2010-05-19 19:21:53 +10001943 req_ctx->first = 1; /* first indicates h/w must init its context */
1944 req_ctx->swinit = 0; /* assume h/w init of context */
LEROY Christophe49f97832017-10-06 15:05:04 +02001945 size = (crypto_ahash_digestsize(tfm) <= SHA256_DIGEST_SIZE)
Lee Nipper497f2e62010-05-19 19:20:36 +10001946 ? TALITOS_MDEU_CONTEXT_SIZE_MD5_SHA1_SHA256
1947 : TALITOS_MDEU_CONTEXT_SIZE_SHA384_SHA512;
LEROY Christophe49f97832017-10-06 15:05:04 +02001948 req_ctx->hw_context_size = size;
Lee Nipper497f2e62010-05-19 19:20:36 +10001949
LEROY Christophe6a4967c2018-02-26 17:40:06 +01001950 dma = dma_map_single(dev, req_ctx->hw_context, req_ctx->hw_context_size,
1951 DMA_TO_DEVICE);
1952 dma_unmap_single(dev, dma, req_ctx->hw_context_size, DMA_TO_DEVICE);
1953
Lee Nipper497f2e62010-05-19 19:20:36 +10001954 return 0;
1955}
1956
Kim Phillips60f208d2010-05-19 19:21:53 +10001957/*
1958 * on h/w without explicit sha224 support, we initialize h/w context
1959 * manually with sha224 constants, and tell it to run sha256.
1960 */
1961static int ahash_init_sha224_swinit(struct ahash_request *areq)
1962{
1963 struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
1964
Kim Phillipsa7524472010-09-23 15:56:38 +08001965 req_ctx->hw_context[0] = SHA224_H0;
1966 req_ctx->hw_context[1] = SHA224_H1;
1967 req_ctx->hw_context[2] = SHA224_H2;
1968 req_ctx->hw_context[3] = SHA224_H3;
1969 req_ctx->hw_context[4] = SHA224_H4;
1970 req_ctx->hw_context[5] = SHA224_H5;
1971 req_ctx->hw_context[6] = SHA224_H6;
1972 req_ctx->hw_context[7] = SHA224_H7;
Kim Phillips60f208d2010-05-19 19:21:53 +10001973
1974 /* init 64-bit count */
1975 req_ctx->hw_context[8] = 0;
1976 req_ctx->hw_context[9] = 0;
1977
LEROY Christophe6a4967c2018-02-26 17:40:06 +01001978 ahash_init(areq);
1979 req_ctx->swinit = 1;/* prevent h/w initting context with sha256 values*/
1980
Kim Phillips60f208d2010-05-19 19:21:53 +10001981 return 0;
1982}
1983
Lee Nipper497f2e62010-05-19 19:20:36 +10001984static int ahash_process_req(struct ahash_request *areq, unsigned int nbytes)
1985{
1986 struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
1987 struct talitos_ctx *ctx = crypto_ahash_ctx(tfm);
1988 struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
1989 struct talitos_edesc *edesc;
1990 unsigned int blocksize =
1991 crypto_tfm_alg_blocksize(crypto_ahash_tfm(tfm));
1992 unsigned int nbytes_to_hash;
1993 unsigned int to_hash_later;
Lee Nipper5e833bc2010-06-16 15:29:15 +10001994 unsigned int nsg;
LABBE Corentin8e409fe2015-11-04 21:13:34 +01001995 int nents;
LEROY Christophe37b5e882017-10-06 15:05:06 +02001996 struct device *dev = ctx->dev;
1997 struct talitos_private *priv = dev_get_drvdata(dev);
1998 bool is_sec1 = has_ftr_sec1(priv);
1999 int offset = 0;
LEROY Christophe3c0dd192017-10-06 15:05:08 +02002000 u8 *ctx_buf = req_ctx->buf[req_ctx->buf_idx];
Lee Nipper497f2e62010-05-19 19:20:36 +10002001
Lee Nipper5e833bc2010-06-16 15:29:15 +10002002 if (!req_ctx->last && (nbytes + req_ctx->nbuf <= blocksize)) {
2003 /* Buffer up to one whole block */
LABBE Corentin8e409fe2015-11-04 21:13:34 +01002004 nents = sg_nents_for_len(areq->src, nbytes);
2005 if (nents < 0) {
2006 dev_err(ctx->dev, "Invalid number of src SG.\n");
2007 return nents;
2008 }
2009 sg_copy_to_buffer(areq->src, nents,
LEROY Christophe3c0dd192017-10-06 15:05:08 +02002010 ctx_buf + req_ctx->nbuf, nbytes);
Lee Nipper5e833bc2010-06-16 15:29:15 +10002011 req_ctx->nbuf += nbytes;
Lee Nipper497f2e62010-05-19 19:20:36 +10002012 return 0;
2013 }
2014
Lee Nipper5e833bc2010-06-16 15:29:15 +10002015 /* At least (blocksize + 1) bytes are available to hash */
2016 nbytes_to_hash = nbytes + req_ctx->nbuf;
2017 to_hash_later = nbytes_to_hash & (blocksize - 1);
2018
2019 if (req_ctx->last)
2020 to_hash_later = 0;
2021 else if (to_hash_later)
2022 /* There is a partial block. Hash the full block(s) now */
2023 nbytes_to_hash -= to_hash_later;
2024 else {
2025 /* Keep one block buffered */
2026 nbytes_to_hash -= blocksize;
2027 to_hash_later = blocksize;
2028 }
2029
2030 /* Chain in any previously buffered data */
LEROY Christophe37b5e882017-10-06 15:05:06 +02002031 if (!is_sec1 && req_ctx->nbuf) {
Lee Nipper5e833bc2010-06-16 15:29:15 +10002032 nsg = (req_ctx->nbuf < nbytes_to_hash) ? 2 : 1;
2033 sg_init_table(req_ctx->bufsl, nsg);
LEROY Christophe3c0dd192017-10-06 15:05:08 +02002034 sg_set_buf(req_ctx->bufsl, ctx_buf, req_ctx->nbuf);
Lee Nipper5e833bc2010-06-16 15:29:15 +10002035 if (nsg > 1)
Dan Williamsc56f6d12015-08-07 18:15:13 +02002036 sg_chain(req_ctx->bufsl, 2, areq->src);
Lee Nipper497f2e62010-05-19 19:20:36 +10002037 req_ctx->psrc = req_ctx->bufsl;
LEROY Christophe37b5e882017-10-06 15:05:06 +02002038 } else if (is_sec1 && req_ctx->nbuf && req_ctx->nbuf < blocksize) {
2039 if (nbytes_to_hash > blocksize)
2040 offset = blocksize - req_ctx->nbuf;
2041 else
2042 offset = nbytes_to_hash - req_ctx->nbuf;
2043 nents = sg_nents_for_len(areq->src, offset);
2044 if (nents < 0) {
2045 dev_err(ctx->dev, "Invalid number of src SG.\n");
2046 return nents;
2047 }
2048 sg_copy_to_buffer(areq->src, nents,
LEROY Christophe3c0dd192017-10-06 15:05:08 +02002049 ctx_buf + req_ctx->nbuf, offset);
LEROY Christophe37b5e882017-10-06 15:05:06 +02002050 req_ctx->nbuf += offset;
2051 req_ctx->psrc = areq->src;
Lee Nipper5e833bc2010-06-16 15:29:15 +10002052 } else
Lee Nipper497f2e62010-05-19 19:20:36 +10002053 req_ctx->psrc = areq->src;
Lee Nipper497f2e62010-05-19 19:20:36 +10002054
Lee Nipper5e833bc2010-06-16 15:29:15 +10002055 if (to_hash_later) {
LABBE Corentin8e409fe2015-11-04 21:13:34 +01002056 nents = sg_nents_for_len(areq->src, nbytes);
2057 if (nents < 0) {
2058 dev_err(ctx->dev, "Invalid number of src SG.\n");
2059 return nents;
2060 }
Akinobu Mitad0525722013-07-08 16:01:55 -07002061 sg_pcopy_to_buffer(areq->src, nents,
LEROY Christophe3c0dd192017-10-06 15:05:08 +02002062 req_ctx->buf[(req_ctx->buf_idx + 1) & 1],
Lee Nipper5e833bc2010-06-16 15:29:15 +10002063 to_hash_later,
2064 nbytes - to_hash_later);
Lee Nipper497f2e62010-05-19 19:20:36 +10002065 }
Lee Nipper5e833bc2010-06-16 15:29:15 +10002066 req_ctx->to_hash_later = to_hash_later;
Lee Nipper497f2e62010-05-19 19:20:36 +10002067
Lee Nipper5e833bc2010-06-16 15:29:15 +10002068 /* Allocate extended descriptor */
Lee Nipper497f2e62010-05-19 19:20:36 +10002069 edesc = ahash_edesc_alloc(areq, nbytes_to_hash);
2070 if (IS_ERR(edesc))
2071 return PTR_ERR(edesc);
2072
2073 edesc->desc.hdr = ctx->desc_hdr_template;
2074
2075 /* On last one, request SEC to pad; otherwise continue */
2076 if (req_ctx->last)
2077 edesc->desc.hdr |= DESC_HDR_MODE0_MDEU_PAD;
2078 else
2079 edesc->desc.hdr |= DESC_HDR_MODE0_MDEU_CONT;
2080
Kim Phillips60f208d2010-05-19 19:21:53 +10002081 /* request SEC to INIT hash. */
2082 if (req_ctx->first && !req_ctx->swinit)
Lee Nipper497f2e62010-05-19 19:20:36 +10002083 edesc->desc.hdr |= DESC_HDR_MODE0_MDEU_INIT;
2084
2085 /* When the tfm context has a keylen, it's an HMAC.
2086 * A first or last (ie. not middle) descriptor must request HMAC.
2087 */
2088 if (ctx->keylen && (req_ctx->first || req_ctx->last))
2089 edesc->desc.hdr |= DESC_HDR_MODE0_MDEU_HMAC;
2090
LEROY Christophe37b5e882017-10-06 15:05:06 +02002091 return common_nonsnoop_hash(edesc, areq, nbytes_to_hash, offset,
Lee Nipper497f2e62010-05-19 19:20:36 +10002092 ahash_done);
2093}
2094
2095static int ahash_update(struct ahash_request *areq)
2096{
2097 struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
2098
2099 req_ctx->last = 0;
2100
2101 return ahash_process_req(areq, areq->nbytes);
2102}
2103
2104static int ahash_final(struct ahash_request *areq)
2105{
2106 struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
2107
2108 req_ctx->last = 1;
2109
2110 return ahash_process_req(areq, 0);
2111}
2112
2113static int ahash_finup(struct ahash_request *areq)
2114{
2115 struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
2116
2117 req_ctx->last = 1;
2118
2119 return ahash_process_req(areq, areq->nbytes);
2120}
2121
2122static int ahash_digest(struct ahash_request *areq)
2123{
2124 struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
Kim Phillips60f208d2010-05-19 19:21:53 +10002125 struct crypto_ahash *ahash = crypto_ahash_reqtfm(areq);
Lee Nipper497f2e62010-05-19 19:20:36 +10002126
Kim Phillips60f208d2010-05-19 19:21:53 +10002127 ahash->init(areq);
Lee Nipper497f2e62010-05-19 19:20:36 +10002128 req_ctx->last = 1;
2129
2130 return ahash_process_req(areq, areq->nbytes);
2131}
2132
Horia Geant?3639ca82016-04-21 19:24:55 +03002133static int ahash_export(struct ahash_request *areq, void *out)
2134{
2135 struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
2136 struct talitos_export_state *export = out;
LEROY Christophe6a4967c2018-02-26 17:40:06 +01002137 struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
2138 struct talitos_ctx *ctx = crypto_ahash_ctx(tfm);
2139 struct device *dev = ctx->dev;
2140 dma_addr_t dma;
2141
2142 dma = dma_map_single(dev, req_ctx->hw_context, req_ctx->hw_context_size,
2143 DMA_FROM_DEVICE);
2144 dma_unmap_single(dev, dma, req_ctx->hw_context_size, DMA_FROM_DEVICE);
Horia Geant?3639ca82016-04-21 19:24:55 +03002145
2146 memcpy(export->hw_context, req_ctx->hw_context,
2147 req_ctx->hw_context_size);
LEROY Christophe3c0dd192017-10-06 15:05:08 +02002148 memcpy(export->buf, req_ctx->buf[req_ctx->buf_idx], req_ctx->nbuf);
Horia Geant?3639ca82016-04-21 19:24:55 +03002149 export->swinit = req_ctx->swinit;
2150 export->first = req_ctx->first;
2151 export->last = req_ctx->last;
2152 export->to_hash_later = req_ctx->to_hash_later;
2153 export->nbuf = req_ctx->nbuf;
2154
2155 return 0;
2156}
2157
2158static int ahash_import(struct ahash_request *areq, const void *in)
2159{
2160 struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
2161 struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
LEROY Christophe6a4967c2018-02-26 17:40:06 +01002162 struct talitos_ctx *ctx = crypto_ahash_ctx(tfm);
2163 struct device *dev = ctx->dev;
Horia Geant?3639ca82016-04-21 19:24:55 +03002164 const struct talitos_export_state *export = in;
LEROY Christophe49f97832017-10-06 15:05:04 +02002165 unsigned int size;
LEROY Christophe6a4967c2018-02-26 17:40:06 +01002166 dma_addr_t dma;
Horia Geant?3639ca82016-04-21 19:24:55 +03002167
2168 memset(req_ctx, 0, sizeof(*req_ctx));
LEROY Christophe49f97832017-10-06 15:05:04 +02002169 size = (crypto_ahash_digestsize(tfm) <= SHA256_DIGEST_SIZE)
Horia Geant?3639ca82016-04-21 19:24:55 +03002170 ? TALITOS_MDEU_CONTEXT_SIZE_MD5_SHA1_SHA256
2171 : TALITOS_MDEU_CONTEXT_SIZE_SHA384_SHA512;
LEROY Christophe49f97832017-10-06 15:05:04 +02002172 req_ctx->hw_context_size = size;
LEROY Christophe49f97832017-10-06 15:05:04 +02002173 memcpy(req_ctx->hw_context, export->hw_context, size);
LEROY Christophe3c0dd192017-10-06 15:05:08 +02002174 memcpy(req_ctx->buf[0], export->buf, export->nbuf);
Horia Geant?3639ca82016-04-21 19:24:55 +03002175 req_ctx->swinit = export->swinit;
2176 req_ctx->first = export->first;
2177 req_ctx->last = export->last;
2178 req_ctx->to_hash_later = export->to_hash_later;
2179 req_ctx->nbuf = export->nbuf;
2180
LEROY Christophe6a4967c2018-02-26 17:40:06 +01002181 dma = dma_map_single(dev, req_ctx->hw_context, req_ctx->hw_context_size,
2182 DMA_TO_DEVICE);
2183 dma_unmap_single(dev, dma, req_ctx->hw_context_size, DMA_TO_DEVICE);
2184
Horia Geant?3639ca82016-04-21 19:24:55 +03002185 return 0;
2186}
2187
Lee Nipper79b3a412011-11-21 16:13:25 +08002188static int keyhash(struct crypto_ahash *tfm, const u8 *key, unsigned int keylen,
2189 u8 *hash)
2190{
2191 struct talitos_ctx *ctx = crypto_tfm_ctx(crypto_ahash_tfm(tfm));
2192
2193 struct scatterlist sg[1];
2194 struct ahash_request *req;
Gilad Ben-Yosseff1c90ac32017-10-18 08:00:49 +01002195 struct crypto_wait wait;
Lee Nipper79b3a412011-11-21 16:13:25 +08002196 int ret;
2197
Gilad Ben-Yosseff1c90ac32017-10-18 08:00:49 +01002198 crypto_init_wait(&wait);
Lee Nipper79b3a412011-11-21 16:13:25 +08002199
2200 req = ahash_request_alloc(tfm, GFP_KERNEL);
2201 if (!req)
2202 return -ENOMEM;
2203
2204 /* Keep tfm keylen == 0 during hash of the long key */
2205 ctx->keylen = 0;
2206 ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
Gilad Ben-Yosseff1c90ac32017-10-18 08:00:49 +01002207 crypto_req_done, &wait);
Lee Nipper79b3a412011-11-21 16:13:25 +08002208
2209 sg_init_one(&sg[0], key, keylen);
2210
2211 ahash_request_set_crypt(req, sg, hash, keylen);
Gilad Ben-Yosseff1c90ac32017-10-18 08:00:49 +01002212 ret = crypto_wait_req(crypto_ahash_digest(req), &wait);
2213
Lee Nipper79b3a412011-11-21 16:13:25 +08002214 ahash_request_free(req);
2215
2216 return ret;
2217}
2218
2219static int ahash_setkey(struct crypto_ahash *tfm, const u8 *key,
2220 unsigned int keylen)
2221{
2222 struct talitos_ctx *ctx = crypto_tfm_ctx(crypto_ahash_tfm(tfm));
LEROY Christophe2e13ce02017-10-06 15:05:02 +02002223 struct device *dev = ctx->dev;
Lee Nipper79b3a412011-11-21 16:13:25 +08002224 unsigned int blocksize =
2225 crypto_tfm_alg_blocksize(crypto_ahash_tfm(tfm));
2226 unsigned int digestsize = crypto_ahash_digestsize(tfm);
2227 unsigned int keysize = keylen;
2228 u8 hash[SHA512_DIGEST_SIZE];
2229 int ret;
2230
2231 if (keylen <= blocksize)
2232 memcpy(ctx->key, key, keysize);
2233 else {
2234 /* Must get the hash of the long key */
2235 ret = keyhash(tfm, key, keylen, hash);
2236
2237 if (ret) {
2238 crypto_ahash_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN);
2239 return -EINVAL;
2240 }
2241
2242 keysize = digestsize;
2243 memcpy(ctx->key, hash, digestsize);
2244 }
2245
LEROY Christophe2e13ce02017-10-06 15:05:02 +02002246 if (ctx->keylen)
2247 dma_unmap_single(dev, ctx->dma_key, ctx->keylen, DMA_TO_DEVICE);
2248
Lee Nipper79b3a412011-11-21 16:13:25 +08002249 ctx->keylen = keysize;
LEROY Christophe2e13ce02017-10-06 15:05:02 +02002250 ctx->dma_key = dma_map_single(dev, ctx->key, keysize, DMA_TO_DEVICE);
Lee Nipper79b3a412011-11-21 16:13:25 +08002251
2252 return 0;
2253}
2254
2255
Kim Phillips9c4a7962008-06-23 19:50:15 +08002256struct talitos_alg_template {
Lee Nipperd5e4aae2010-05-19 19:18:38 +10002257 u32 type;
LEROY Christopheb0057762016-06-06 13:20:44 +02002258 u32 priority;
Lee Nipperd5e4aae2010-05-19 19:18:38 +10002259 union {
2260 struct crypto_alg crypto;
Lee Nipperacbf7c622010-05-19 19:19:33 +10002261 struct ahash_alg hash;
Herbert Xuaeb4c132015-07-30 17:53:22 +08002262 struct aead_alg aead;
Lee Nipperd5e4aae2010-05-19 19:18:38 +10002263 } alg;
Kim Phillips9c4a7962008-06-23 19:50:15 +08002264 __be32 desc_hdr_template;
2265};
2266
2267static struct talitos_alg_template driver_algs[] = {
Horia Geanta991155b2013-03-20 16:31:38 +02002268 /* AEAD algorithms. These use a single-pass ipsec_esp descriptor */
Lee Nipperd5e4aae2010-05-19 19:18:38 +10002269 { .type = CRYPTO_ALG_TYPE_AEAD,
Herbert Xuaeb4c132015-07-30 17:53:22 +08002270 .alg.aead = {
2271 .base = {
2272 .cra_name = "authenc(hmac(sha1),cbc(aes))",
2273 .cra_driver_name = "authenc-hmac-sha1-"
2274 "cbc-aes-talitos",
2275 .cra_blocksize = AES_BLOCK_SIZE,
2276 .cra_flags = CRYPTO_ALG_ASYNC,
2277 },
2278 .ivsize = AES_BLOCK_SIZE,
2279 .maxauthsize = SHA1_DIGEST_SIZE,
Lee Nipper56af8cd2009-03-29 15:50:50 +08002280 },
Kim Phillips9c4a7962008-06-23 19:50:15 +08002281 .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
2282 DESC_HDR_SEL0_AESU |
2283 DESC_HDR_MODE0_AESU_CBC |
2284 DESC_HDR_SEL1_MDEUA |
2285 DESC_HDR_MODE1_MDEU_INIT |
2286 DESC_HDR_MODE1_MDEU_PAD |
2287 DESC_HDR_MODE1_MDEU_SHA1_HMAC,
Lee Nipper70bcaca2008-07-03 19:08:46 +08002288 },
Lee Nipperd5e4aae2010-05-19 19:18:38 +10002289 { .type = CRYPTO_ALG_TYPE_AEAD,
LEROY Christophe7405c8d2016-06-06 13:20:46 +02002290 .priority = TALITOS_CRA_PRIORITY_AEAD_HSNA,
2291 .alg.aead = {
2292 .base = {
2293 .cra_name = "authenc(hmac(sha1),cbc(aes))",
2294 .cra_driver_name = "authenc-hmac-sha1-"
2295 "cbc-aes-talitos",
2296 .cra_blocksize = AES_BLOCK_SIZE,
2297 .cra_flags = CRYPTO_ALG_ASYNC,
2298 },
2299 .ivsize = AES_BLOCK_SIZE,
2300 .maxauthsize = SHA1_DIGEST_SIZE,
2301 },
2302 .desc_hdr_template = DESC_HDR_TYPE_HMAC_SNOOP_NO_AFEU |
2303 DESC_HDR_SEL0_AESU |
2304 DESC_HDR_MODE0_AESU_CBC |
2305 DESC_HDR_SEL1_MDEUA |
2306 DESC_HDR_MODE1_MDEU_INIT |
2307 DESC_HDR_MODE1_MDEU_PAD |
2308 DESC_HDR_MODE1_MDEU_SHA1_HMAC,
2309 },
2310 { .type = CRYPTO_ALG_TYPE_AEAD,
Herbert Xuaeb4c132015-07-30 17:53:22 +08002311 .alg.aead = {
2312 .base = {
2313 .cra_name = "authenc(hmac(sha1),"
2314 "cbc(des3_ede))",
2315 .cra_driver_name = "authenc-hmac-sha1-"
2316 "cbc-3des-talitos",
2317 .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2318 .cra_flags = CRYPTO_ALG_ASYNC,
2319 },
2320 .ivsize = DES3_EDE_BLOCK_SIZE,
2321 .maxauthsize = SHA1_DIGEST_SIZE,
Lee Nipper56af8cd2009-03-29 15:50:50 +08002322 },
Lee Nipper70bcaca2008-07-03 19:08:46 +08002323 .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
2324 DESC_HDR_SEL0_DEU |
2325 DESC_HDR_MODE0_DEU_CBC |
2326 DESC_HDR_MODE0_DEU_3DES |
2327 DESC_HDR_SEL1_MDEUA |
2328 DESC_HDR_MODE1_MDEU_INIT |
2329 DESC_HDR_MODE1_MDEU_PAD |
2330 DESC_HDR_MODE1_MDEU_SHA1_HMAC,
Lee Nipper3952f172008-07-10 18:29:18 +08002331 },
LEROY Christophe7405c8d2016-06-06 13:20:46 +02002332 { .type = CRYPTO_ALG_TYPE_AEAD,
2333 .priority = TALITOS_CRA_PRIORITY_AEAD_HSNA,
2334 .alg.aead = {
2335 .base = {
2336 .cra_name = "authenc(hmac(sha1),"
2337 "cbc(des3_ede))",
2338 .cra_driver_name = "authenc-hmac-sha1-"
2339 "cbc-3des-talitos",
2340 .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2341 .cra_flags = CRYPTO_ALG_ASYNC,
2342 },
2343 .ivsize = DES3_EDE_BLOCK_SIZE,
2344 .maxauthsize = SHA1_DIGEST_SIZE,
2345 },
2346 .desc_hdr_template = DESC_HDR_TYPE_HMAC_SNOOP_NO_AFEU |
2347 DESC_HDR_SEL0_DEU |
2348 DESC_HDR_MODE0_DEU_CBC |
2349 DESC_HDR_MODE0_DEU_3DES |
2350 DESC_HDR_SEL1_MDEUA |
2351 DESC_HDR_MODE1_MDEU_INIT |
2352 DESC_HDR_MODE1_MDEU_PAD |
2353 DESC_HDR_MODE1_MDEU_SHA1_HMAC,
2354 },
Horia Geanta357fb602012-07-03 19:16:53 +03002355 { .type = CRYPTO_ALG_TYPE_AEAD,
Herbert Xuaeb4c132015-07-30 17:53:22 +08002356 .alg.aead = {
2357 .base = {
2358 .cra_name = "authenc(hmac(sha224),cbc(aes))",
2359 .cra_driver_name = "authenc-hmac-sha224-"
2360 "cbc-aes-talitos",
2361 .cra_blocksize = AES_BLOCK_SIZE,
2362 .cra_flags = CRYPTO_ALG_ASYNC,
2363 },
2364 .ivsize = AES_BLOCK_SIZE,
2365 .maxauthsize = SHA224_DIGEST_SIZE,
Horia Geanta357fb602012-07-03 19:16:53 +03002366 },
2367 .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
2368 DESC_HDR_SEL0_AESU |
2369 DESC_HDR_MODE0_AESU_CBC |
2370 DESC_HDR_SEL1_MDEUA |
2371 DESC_HDR_MODE1_MDEU_INIT |
2372 DESC_HDR_MODE1_MDEU_PAD |
2373 DESC_HDR_MODE1_MDEU_SHA224_HMAC,
2374 },
LEROY Christophe7405c8d2016-06-06 13:20:46 +02002375 { .type = CRYPTO_ALG_TYPE_AEAD,
2376 .priority = TALITOS_CRA_PRIORITY_AEAD_HSNA,
2377 .alg.aead = {
2378 .base = {
2379 .cra_name = "authenc(hmac(sha224),cbc(aes))",
2380 .cra_driver_name = "authenc-hmac-sha224-"
2381 "cbc-aes-talitos",
2382 .cra_blocksize = AES_BLOCK_SIZE,
2383 .cra_flags = CRYPTO_ALG_ASYNC,
2384 },
2385 .ivsize = AES_BLOCK_SIZE,
2386 .maxauthsize = SHA224_DIGEST_SIZE,
2387 },
2388 .desc_hdr_template = DESC_HDR_TYPE_HMAC_SNOOP_NO_AFEU |
2389 DESC_HDR_SEL0_AESU |
2390 DESC_HDR_MODE0_AESU_CBC |
2391 DESC_HDR_SEL1_MDEUA |
2392 DESC_HDR_MODE1_MDEU_INIT |
2393 DESC_HDR_MODE1_MDEU_PAD |
2394 DESC_HDR_MODE1_MDEU_SHA224_HMAC,
2395 },
Horia Geanta357fb602012-07-03 19:16:53 +03002396 { .type = CRYPTO_ALG_TYPE_AEAD,
Herbert Xuaeb4c132015-07-30 17:53:22 +08002397 .alg.aead = {
2398 .base = {
2399 .cra_name = "authenc(hmac(sha224),"
2400 "cbc(des3_ede))",
2401 .cra_driver_name = "authenc-hmac-sha224-"
2402 "cbc-3des-talitos",
2403 .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2404 .cra_flags = CRYPTO_ALG_ASYNC,
2405 },
2406 .ivsize = DES3_EDE_BLOCK_SIZE,
2407 .maxauthsize = SHA224_DIGEST_SIZE,
Horia Geanta357fb602012-07-03 19:16:53 +03002408 },
2409 .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
2410 DESC_HDR_SEL0_DEU |
2411 DESC_HDR_MODE0_DEU_CBC |
2412 DESC_HDR_MODE0_DEU_3DES |
2413 DESC_HDR_SEL1_MDEUA |
2414 DESC_HDR_MODE1_MDEU_INIT |
2415 DESC_HDR_MODE1_MDEU_PAD |
2416 DESC_HDR_MODE1_MDEU_SHA224_HMAC,
2417 },
Lee Nipperd5e4aae2010-05-19 19:18:38 +10002418 { .type = CRYPTO_ALG_TYPE_AEAD,
LEROY Christophe7405c8d2016-06-06 13:20:46 +02002419 .priority = TALITOS_CRA_PRIORITY_AEAD_HSNA,
2420 .alg.aead = {
2421 .base = {
2422 .cra_name = "authenc(hmac(sha224),"
2423 "cbc(des3_ede))",
2424 .cra_driver_name = "authenc-hmac-sha224-"
2425 "cbc-3des-talitos",
2426 .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2427 .cra_flags = CRYPTO_ALG_ASYNC,
2428 },
2429 .ivsize = DES3_EDE_BLOCK_SIZE,
2430 .maxauthsize = SHA224_DIGEST_SIZE,
2431 },
2432 .desc_hdr_template = DESC_HDR_TYPE_HMAC_SNOOP_NO_AFEU |
2433 DESC_HDR_SEL0_DEU |
2434 DESC_HDR_MODE0_DEU_CBC |
2435 DESC_HDR_MODE0_DEU_3DES |
2436 DESC_HDR_SEL1_MDEUA |
2437 DESC_HDR_MODE1_MDEU_INIT |
2438 DESC_HDR_MODE1_MDEU_PAD |
2439 DESC_HDR_MODE1_MDEU_SHA224_HMAC,
2440 },
2441 { .type = CRYPTO_ALG_TYPE_AEAD,
Herbert Xuaeb4c132015-07-30 17:53:22 +08002442 .alg.aead = {
2443 .base = {
2444 .cra_name = "authenc(hmac(sha256),cbc(aes))",
2445 .cra_driver_name = "authenc-hmac-sha256-"
2446 "cbc-aes-talitos",
2447 .cra_blocksize = AES_BLOCK_SIZE,
2448 .cra_flags = CRYPTO_ALG_ASYNC,
2449 },
2450 .ivsize = AES_BLOCK_SIZE,
2451 .maxauthsize = SHA256_DIGEST_SIZE,
Lee Nipper56af8cd2009-03-29 15:50:50 +08002452 },
Lee Nipper3952f172008-07-10 18:29:18 +08002453 .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
2454 DESC_HDR_SEL0_AESU |
2455 DESC_HDR_MODE0_AESU_CBC |
2456 DESC_HDR_SEL1_MDEUA |
2457 DESC_HDR_MODE1_MDEU_INIT |
2458 DESC_HDR_MODE1_MDEU_PAD |
2459 DESC_HDR_MODE1_MDEU_SHA256_HMAC,
2460 },
Lee Nipperd5e4aae2010-05-19 19:18:38 +10002461 { .type = CRYPTO_ALG_TYPE_AEAD,
LEROY Christophe7405c8d2016-06-06 13:20:46 +02002462 .priority = TALITOS_CRA_PRIORITY_AEAD_HSNA,
2463 .alg.aead = {
2464 .base = {
2465 .cra_name = "authenc(hmac(sha256),cbc(aes))",
2466 .cra_driver_name = "authenc-hmac-sha256-"
2467 "cbc-aes-talitos",
2468 .cra_blocksize = AES_BLOCK_SIZE,
2469 .cra_flags = CRYPTO_ALG_ASYNC,
2470 },
2471 .ivsize = AES_BLOCK_SIZE,
2472 .maxauthsize = SHA256_DIGEST_SIZE,
2473 },
2474 .desc_hdr_template = DESC_HDR_TYPE_HMAC_SNOOP_NO_AFEU |
2475 DESC_HDR_SEL0_AESU |
2476 DESC_HDR_MODE0_AESU_CBC |
2477 DESC_HDR_SEL1_MDEUA |
2478 DESC_HDR_MODE1_MDEU_INIT |
2479 DESC_HDR_MODE1_MDEU_PAD |
2480 DESC_HDR_MODE1_MDEU_SHA256_HMAC,
2481 },
2482 { .type = CRYPTO_ALG_TYPE_AEAD,
Herbert Xuaeb4c132015-07-30 17:53:22 +08002483 .alg.aead = {
2484 .base = {
2485 .cra_name = "authenc(hmac(sha256),"
2486 "cbc(des3_ede))",
2487 .cra_driver_name = "authenc-hmac-sha256-"
2488 "cbc-3des-talitos",
2489 .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2490 .cra_flags = CRYPTO_ALG_ASYNC,
2491 },
2492 .ivsize = DES3_EDE_BLOCK_SIZE,
2493 .maxauthsize = SHA256_DIGEST_SIZE,
Lee Nipper56af8cd2009-03-29 15:50:50 +08002494 },
Lee Nipper3952f172008-07-10 18:29:18 +08002495 .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
2496 DESC_HDR_SEL0_DEU |
2497 DESC_HDR_MODE0_DEU_CBC |
2498 DESC_HDR_MODE0_DEU_3DES |
2499 DESC_HDR_SEL1_MDEUA |
2500 DESC_HDR_MODE1_MDEU_INIT |
2501 DESC_HDR_MODE1_MDEU_PAD |
2502 DESC_HDR_MODE1_MDEU_SHA256_HMAC,
2503 },
Lee Nipperd5e4aae2010-05-19 19:18:38 +10002504 { .type = CRYPTO_ALG_TYPE_AEAD,
LEROY Christophe7405c8d2016-06-06 13:20:46 +02002505 .priority = TALITOS_CRA_PRIORITY_AEAD_HSNA,
2506 .alg.aead = {
2507 .base = {
2508 .cra_name = "authenc(hmac(sha256),"
2509 "cbc(des3_ede))",
2510 .cra_driver_name = "authenc-hmac-sha256-"
2511 "cbc-3des-talitos",
2512 .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2513 .cra_flags = CRYPTO_ALG_ASYNC,
2514 },
2515 .ivsize = DES3_EDE_BLOCK_SIZE,
2516 .maxauthsize = SHA256_DIGEST_SIZE,
2517 },
2518 .desc_hdr_template = DESC_HDR_TYPE_HMAC_SNOOP_NO_AFEU |
2519 DESC_HDR_SEL0_DEU |
2520 DESC_HDR_MODE0_DEU_CBC |
2521 DESC_HDR_MODE0_DEU_3DES |
2522 DESC_HDR_SEL1_MDEUA |
2523 DESC_HDR_MODE1_MDEU_INIT |
2524 DESC_HDR_MODE1_MDEU_PAD |
2525 DESC_HDR_MODE1_MDEU_SHA256_HMAC,
2526 },
2527 { .type = CRYPTO_ALG_TYPE_AEAD,
Herbert Xuaeb4c132015-07-30 17:53:22 +08002528 .alg.aead = {
2529 .base = {
2530 .cra_name = "authenc(hmac(sha384),cbc(aes))",
2531 .cra_driver_name = "authenc-hmac-sha384-"
2532 "cbc-aes-talitos",
2533 .cra_blocksize = AES_BLOCK_SIZE,
2534 .cra_flags = CRYPTO_ALG_ASYNC,
2535 },
2536 .ivsize = AES_BLOCK_SIZE,
2537 .maxauthsize = SHA384_DIGEST_SIZE,
Horia Geanta357fb602012-07-03 19:16:53 +03002538 },
2539 .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
2540 DESC_HDR_SEL0_AESU |
2541 DESC_HDR_MODE0_AESU_CBC |
2542 DESC_HDR_SEL1_MDEUB |
2543 DESC_HDR_MODE1_MDEU_INIT |
2544 DESC_HDR_MODE1_MDEU_PAD |
2545 DESC_HDR_MODE1_MDEUB_SHA384_HMAC,
2546 },
2547 { .type = CRYPTO_ALG_TYPE_AEAD,
Herbert Xuaeb4c132015-07-30 17:53:22 +08002548 .alg.aead = {
2549 .base = {
2550 .cra_name = "authenc(hmac(sha384),"
2551 "cbc(des3_ede))",
2552 .cra_driver_name = "authenc-hmac-sha384-"
2553 "cbc-3des-talitos",
2554 .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2555 .cra_flags = CRYPTO_ALG_ASYNC,
2556 },
2557 .ivsize = DES3_EDE_BLOCK_SIZE,
2558 .maxauthsize = SHA384_DIGEST_SIZE,
Horia Geanta357fb602012-07-03 19:16:53 +03002559 },
2560 .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
2561 DESC_HDR_SEL0_DEU |
2562 DESC_HDR_MODE0_DEU_CBC |
2563 DESC_HDR_MODE0_DEU_3DES |
2564 DESC_HDR_SEL1_MDEUB |
2565 DESC_HDR_MODE1_MDEU_INIT |
2566 DESC_HDR_MODE1_MDEU_PAD |
2567 DESC_HDR_MODE1_MDEUB_SHA384_HMAC,
2568 },
2569 { .type = CRYPTO_ALG_TYPE_AEAD,
Herbert Xuaeb4c132015-07-30 17:53:22 +08002570 .alg.aead = {
2571 .base = {
2572 .cra_name = "authenc(hmac(sha512),cbc(aes))",
2573 .cra_driver_name = "authenc-hmac-sha512-"
2574 "cbc-aes-talitos",
2575 .cra_blocksize = AES_BLOCK_SIZE,
2576 .cra_flags = CRYPTO_ALG_ASYNC,
2577 },
2578 .ivsize = AES_BLOCK_SIZE,
2579 .maxauthsize = SHA512_DIGEST_SIZE,
Horia Geanta357fb602012-07-03 19:16:53 +03002580 },
2581 .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
2582 DESC_HDR_SEL0_AESU |
2583 DESC_HDR_MODE0_AESU_CBC |
2584 DESC_HDR_SEL1_MDEUB |
2585 DESC_HDR_MODE1_MDEU_INIT |
2586 DESC_HDR_MODE1_MDEU_PAD |
2587 DESC_HDR_MODE1_MDEUB_SHA512_HMAC,
2588 },
2589 { .type = CRYPTO_ALG_TYPE_AEAD,
Herbert Xuaeb4c132015-07-30 17:53:22 +08002590 .alg.aead = {
2591 .base = {
2592 .cra_name = "authenc(hmac(sha512),"
2593 "cbc(des3_ede))",
2594 .cra_driver_name = "authenc-hmac-sha512-"
2595 "cbc-3des-talitos",
2596 .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2597 .cra_flags = CRYPTO_ALG_ASYNC,
2598 },
2599 .ivsize = DES3_EDE_BLOCK_SIZE,
2600 .maxauthsize = SHA512_DIGEST_SIZE,
Horia Geanta357fb602012-07-03 19:16:53 +03002601 },
2602 .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
2603 DESC_HDR_SEL0_DEU |
2604 DESC_HDR_MODE0_DEU_CBC |
2605 DESC_HDR_MODE0_DEU_3DES |
2606 DESC_HDR_SEL1_MDEUB |
2607 DESC_HDR_MODE1_MDEU_INIT |
2608 DESC_HDR_MODE1_MDEU_PAD |
2609 DESC_HDR_MODE1_MDEUB_SHA512_HMAC,
2610 },
2611 { .type = CRYPTO_ALG_TYPE_AEAD,
Herbert Xuaeb4c132015-07-30 17:53:22 +08002612 .alg.aead = {
2613 .base = {
2614 .cra_name = "authenc(hmac(md5),cbc(aes))",
2615 .cra_driver_name = "authenc-hmac-md5-"
2616 "cbc-aes-talitos",
2617 .cra_blocksize = AES_BLOCK_SIZE,
2618 .cra_flags = CRYPTO_ALG_ASYNC,
2619 },
2620 .ivsize = AES_BLOCK_SIZE,
2621 .maxauthsize = MD5_DIGEST_SIZE,
Lee Nipper56af8cd2009-03-29 15:50:50 +08002622 },
Lee Nipper3952f172008-07-10 18:29:18 +08002623 .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
2624 DESC_HDR_SEL0_AESU |
2625 DESC_HDR_MODE0_AESU_CBC |
2626 DESC_HDR_SEL1_MDEUA |
2627 DESC_HDR_MODE1_MDEU_INIT |
2628 DESC_HDR_MODE1_MDEU_PAD |
2629 DESC_HDR_MODE1_MDEU_MD5_HMAC,
2630 },
Lee Nipperd5e4aae2010-05-19 19:18:38 +10002631 { .type = CRYPTO_ALG_TYPE_AEAD,
LEROY Christophe7405c8d2016-06-06 13:20:46 +02002632 .priority = TALITOS_CRA_PRIORITY_AEAD_HSNA,
2633 .alg.aead = {
2634 .base = {
2635 .cra_name = "authenc(hmac(md5),cbc(aes))",
2636 .cra_driver_name = "authenc-hmac-md5-"
2637 "cbc-aes-talitos",
2638 .cra_blocksize = AES_BLOCK_SIZE,
2639 .cra_flags = CRYPTO_ALG_ASYNC,
2640 },
2641 .ivsize = AES_BLOCK_SIZE,
2642 .maxauthsize = MD5_DIGEST_SIZE,
2643 },
2644 .desc_hdr_template = DESC_HDR_TYPE_HMAC_SNOOP_NO_AFEU |
2645 DESC_HDR_SEL0_AESU |
2646 DESC_HDR_MODE0_AESU_CBC |
2647 DESC_HDR_SEL1_MDEUA |
2648 DESC_HDR_MODE1_MDEU_INIT |
2649 DESC_HDR_MODE1_MDEU_PAD |
2650 DESC_HDR_MODE1_MDEU_MD5_HMAC,
2651 },
2652 { .type = CRYPTO_ALG_TYPE_AEAD,
Herbert Xuaeb4c132015-07-30 17:53:22 +08002653 .alg.aead = {
2654 .base = {
2655 .cra_name = "authenc(hmac(md5),cbc(des3_ede))",
2656 .cra_driver_name = "authenc-hmac-md5-"
2657 "cbc-3des-talitos",
2658 .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2659 .cra_flags = CRYPTO_ALG_ASYNC,
2660 },
2661 .ivsize = DES3_EDE_BLOCK_SIZE,
2662 .maxauthsize = MD5_DIGEST_SIZE,
Lee Nipper56af8cd2009-03-29 15:50:50 +08002663 },
Lee Nipper3952f172008-07-10 18:29:18 +08002664 .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
2665 DESC_HDR_SEL0_DEU |
2666 DESC_HDR_MODE0_DEU_CBC |
2667 DESC_HDR_MODE0_DEU_3DES |
2668 DESC_HDR_SEL1_MDEUA |
2669 DESC_HDR_MODE1_MDEU_INIT |
2670 DESC_HDR_MODE1_MDEU_PAD |
2671 DESC_HDR_MODE1_MDEU_MD5_HMAC,
Lee Nipper4de9d0b2009-03-29 15:52:32 +08002672 },
LEROY Christophe7405c8d2016-06-06 13:20:46 +02002673 { .type = CRYPTO_ALG_TYPE_AEAD,
2674 .priority = TALITOS_CRA_PRIORITY_AEAD_HSNA,
2675 .alg.aead = {
2676 .base = {
2677 .cra_name = "authenc(hmac(md5),cbc(des3_ede))",
2678 .cra_driver_name = "authenc-hmac-md5-"
2679 "cbc-3des-talitos",
2680 .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2681 .cra_flags = CRYPTO_ALG_ASYNC,
2682 },
2683 .ivsize = DES3_EDE_BLOCK_SIZE,
2684 .maxauthsize = MD5_DIGEST_SIZE,
2685 },
2686 .desc_hdr_template = DESC_HDR_TYPE_HMAC_SNOOP_NO_AFEU |
2687 DESC_HDR_SEL0_DEU |
2688 DESC_HDR_MODE0_DEU_CBC |
2689 DESC_HDR_MODE0_DEU_3DES |
2690 DESC_HDR_SEL1_MDEUA |
2691 DESC_HDR_MODE1_MDEU_INIT |
2692 DESC_HDR_MODE1_MDEU_PAD |
2693 DESC_HDR_MODE1_MDEU_MD5_HMAC,
2694 },
Lee Nipper4de9d0b2009-03-29 15:52:32 +08002695 /* ABLKCIPHER algorithms. */
Lee Nipperd5e4aae2010-05-19 19:18:38 +10002696 { .type = CRYPTO_ALG_TYPE_ABLKCIPHER,
2697 .alg.crypto = {
LEROY Christophe5e75ae12015-12-01 12:44:15 +01002698 .cra_name = "ecb(aes)",
2699 .cra_driver_name = "ecb-aes-talitos",
2700 .cra_blocksize = AES_BLOCK_SIZE,
2701 .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER |
2702 CRYPTO_ALG_ASYNC,
2703 .cra_ablkcipher = {
2704 .min_keysize = AES_MIN_KEY_SIZE,
2705 .max_keysize = AES_MAX_KEY_SIZE,
2706 .ivsize = AES_BLOCK_SIZE,
2707 }
2708 },
2709 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2710 DESC_HDR_SEL0_AESU,
2711 },
2712 { .type = CRYPTO_ALG_TYPE_ABLKCIPHER,
2713 .alg.crypto = {
Lee Nipper4de9d0b2009-03-29 15:52:32 +08002714 .cra_name = "cbc(aes)",
2715 .cra_driver_name = "cbc-aes-talitos",
2716 .cra_blocksize = AES_BLOCK_SIZE,
2717 .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER |
2718 CRYPTO_ALG_ASYNC,
Lee Nipper4de9d0b2009-03-29 15:52:32 +08002719 .cra_ablkcipher = {
Lee Nipper4de9d0b2009-03-29 15:52:32 +08002720 .min_keysize = AES_MIN_KEY_SIZE,
2721 .max_keysize = AES_MAX_KEY_SIZE,
2722 .ivsize = AES_BLOCK_SIZE,
2723 }
2724 },
2725 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2726 DESC_HDR_SEL0_AESU |
2727 DESC_HDR_MODE0_AESU_CBC,
2728 },
Lee Nipperd5e4aae2010-05-19 19:18:38 +10002729 { .type = CRYPTO_ALG_TYPE_ABLKCIPHER,
2730 .alg.crypto = {
LEROY Christophe5e75ae12015-12-01 12:44:15 +01002731 .cra_name = "ctr(aes)",
2732 .cra_driver_name = "ctr-aes-talitos",
2733 .cra_blocksize = AES_BLOCK_SIZE,
2734 .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER |
2735 CRYPTO_ALG_ASYNC,
2736 .cra_ablkcipher = {
2737 .min_keysize = AES_MIN_KEY_SIZE,
2738 .max_keysize = AES_MAX_KEY_SIZE,
2739 .ivsize = AES_BLOCK_SIZE,
2740 }
2741 },
LEROY Christophe70d355c2017-10-06 15:04:43 +02002742 .desc_hdr_template = DESC_HDR_TYPE_AESU_CTR_NONSNOOP |
LEROY Christophe5e75ae12015-12-01 12:44:15 +01002743 DESC_HDR_SEL0_AESU |
2744 DESC_HDR_MODE0_AESU_CTR,
2745 },
2746 { .type = CRYPTO_ALG_TYPE_ABLKCIPHER,
2747 .alg.crypto = {
2748 .cra_name = "ecb(des)",
2749 .cra_driver_name = "ecb-des-talitos",
2750 .cra_blocksize = DES_BLOCK_SIZE,
2751 .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER |
2752 CRYPTO_ALG_ASYNC,
2753 .cra_ablkcipher = {
2754 .min_keysize = DES_KEY_SIZE,
2755 .max_keysize = DES_KEY_SIZE,
2756 .ivsize = DES_BLOCK_SIZE,
2757 }
2758 },
2759 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2760 DESC_HDR_SEL0_DEU,
2761 },
2762 { .type = CRYPTO_ALG_TYPE_ABLKCIPHER,
2763 .alg.crypto = {
2764 .cra_name = "cbc(des)",
2765 .cra_driver_name = "cbc-des-talitos",
2766 .cra_blocksize = DES_BLOCK_SIZE,
2767 .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER |
2768 CRYPTO_ALG_ASYNC,
2769 .cra_ablkcipher = {
2770 .min_keysize = DES_KEY_SIZE,
2771 .max_keysize = DES_KEY_SIZE,
2772 .ivsize = DES_BLOCK_SIZE,
2773 }
2774 },
2775 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2776 DESC_HDR_SEL0_DEU |
2777 DESC_HDR_MODE0_DEU_CBC,
2778 },
2779 { .type = CRYPTO_ALG_TYPE_ABLKCIPHER,
2780 .alg.crypto = {
2781 .cra_name = "ecb(des3_ede)",
2782 .cra_driver_name = "ecb-3des-talitos",
2783 .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2784 .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER |
2785 CRYPTO_ALG_ASYNC,
2786 .cra_ablkcipher = {
2787 .min_keysize = DES3_EDE_KEY_SIZE,
2788 .max_keysize = DES3_EDE_KEY_SIZE,
2789 .ivsize = DES3_EDE_BLOCK_SIZE,
2790 }
2791 },
2792 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2793 DESC_HDR_SEL0_DEU |
2794 DESC_HDR_MODE0_DEU_3DES,
2795 },
2796 { .type = CRYPTO_ALG_TYPE_ABLKCIPHER,
2797 .alg.crypto = {
Lee Nipper4de9d0b2009-03-29 15:52:32 +08002798 .cra_name = "cbc(des3_ede)",
2799 .cra_driver_name = "cbc-3des-talitos",
2800 .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2801 .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER |
2802 CRYPTO_ALG_ASYNC,
Lee Nipper4de9d0b2009-03-29 15:52:32 +08002803 .cra_ablkcipher = {
Lee Nipper4de9d0b2009-03-29 15:52:32 +08002804 .min_keysize = DES3_EDE_KEY_SIZE,
2805 .max_keysize = DES3_EDE_KEY_SIZE,
2806 .ivsize = DES3_EDE_BLOCK_SIZE,
2807 }
2808 },
2809 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2810 DESC_HDR_SEL0_DEU |
2811 DESC_HDR_MODE0_DEU_CBC |
2812 DESC_HDR_MODE0_DEU_3DES,
Lee Nipper497f2e62010-05-19 19:20:36 +10002813 },
2814 /* AHASH algorithms. */
2815 { .type = CRYPTO_ALG_TYPE_AHASH,
2816 .alg.hash = {
Lee Nipper497f2e62010-05-19 19:20:36 +10002817 .halg.digestsize = MD5_DIGEST_SIZE,
Horia Geant?3639ca82016-04-21 19:24:55 +03002818 .halg.statesize = sizeof(struct talitos_export_state),
Lee Nipper497f2e62010-05-19 19:20:36 +10002819 .halg.base = {
2820 .cra_name = "md5",
2821 .cra_driver_name = "md5-talitos",
Martin Hicksb3988612015-03-03 08:21:34 -05002822 .cra_blocksize = MD5_HMAC_BLOCK_SIZE,
Lee Nipper497f2e62010-05-19 19:20:36 +10002823 .cra_flags = CRYPTO_ALG_TYPE_AHASH |
2824 CRYPTO_ALG_ASYNC,
Lee Nipper497f2e62010-05-19 19:20:36 +10002825 }
2826 },
2827 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2828 DESC_HDR_SEL0_MDEUA |
2829 DESC_HDR_MODE0_MDEU_MD5,
2830 },
2831 { .type = CRYPTO_ALG_TYPE_AHASH,
2832 .alg.hash = {
Lee Nipper497f2e62010-05-19 19:20:36 +10002833 .halg.digestsize = SHA1_DIGEST_SIZE,
Horia Geant?3639ca82016-04-21 19:24:55 +03002834 .halg.statesize = sizeof(struct talitos_export_state),
Lee Nipper497f2e62010-05-19 19:20:36 +10002835 .halg.base = {
2836 .cra_name = "sha1",
2837 .cra_driver_name = "sha1-talitos",
2838 .cra_blocksize = SHA1_BLOCK_SIZE,
2839 .cra_flags = CRYPTO_ALG_TYPE_AHASH |
2840 CRYPTO_ALG_ASYNC,
Lee Nipper497f2e62010-05-19 19:20:36 +10002841 }
2842 },
2843 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2844 DESC_HDR_SEL0_MDEUA |
2845 DESC_HDR_MODE0_MDEU_SHA1,
2846 },
2847 { .type = CRYPTO_ALG_TYPE_AHASH,
2848 .alg.hash = {
Kim Phillips60f208d2010-05-19 19:21:53 +10002849 .halg.digestsize = SHA224_DIGEST_SIZE,
Horia Geant?3639ca82016-04-21 19:24:55 +03002850 .halg.statesize = sizeof(struct talitos_export_state),
Kim Phillips60f208d2010-05-19 19:21:53 +10002851 .halg.base = {
2852 .cra_name = "sha224",
2853 .cra_driver_name = "sha224-talitos",
2854 .cra_blocksize = SHA224_BLOCK_SIZE,
2855 .cra_flags = CRYPTO_ALG_TYPE_AHASH |
2856 CRYPTO_ALG_ASYNC,
Kim Phillips60f208d2010-05-19 19:21:53 +10002857 }
2858 },
2859 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2860 DESC_HDR_SEL0_MDEUA |
2861 DESC_HDR_MODE0_MDEU_SHA224,
2862 },
2863 { .type = CRYPTO_ALG_TYPE_AHASH,
2864 .alg.hash = {
Lee Nipper497f2e62010-05-19 19:20:36 +10002865 .halg.digestsize = SHA256_DIGEST_SIZE,
Horia Geant?3639ca82016-04-21 19:24:55 +03002866 .halg.statesize = sizeof(struct talitos_export_state),
Lee Nipper497f2e62010-05-19 19:20:36 +10002867 .halg.base = {
2868 .cra_name = "sha256",
2869 .cra_driver_name = "sha256-talitos",
2870 .cra_blocksize = SHA256_BLOCK_SIZE,
2871 .cra_flags = CRYPTO_ALG_TYPE_AHASH |
2872 CRYPTO_ALG_ASYNC,
Lee Nipper497f2e62010-05-19 19:20:36 +10002873 }
2874 },
2875 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2876 DESC_HDR_SEL0_MDEUA |
2877 DESC_HDR_MODE0_MDEU_SHA256,
2878 },
2879 { .type = CRYPTO_ALG_TYPE_AHASH,
2880 .alg.hash = {
Lee Nipper497f2e62010-05-19 19:20:36 +10002881 .halg.digestsize = SHA384_DIGEST_SIZE,
Horia Geant?3639ca82016-04-21 19:24:55 +03002882 .halg.statesize = sizeof(struct talitos_export_state),
Lee Nipper497f2e62010-05-19 19:20:36 +10002883 .halg.base = {
2884 .cra_name = "sha384",
2885 .cra_driver_name = "sha384-talitos",
2886 .cra_blocksize = SHA384_BLOCK_SIZE,
2887 .cra_flags = CRYPTO_ALG_TYPE_AHASH |
2888 CRYPTO_ALG_ASYNC,
Lee Nipper497f2e62010-05-19 19:20:36 +10002889 }
2890 },
2891 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2892 DESC_HDR_SEL0_MDEUB |
2893 DESC_HDR_MODE0_MDEUB_SHA384,
2894 },
2895 { .type = CRYPTO_ALG_TYPE_AHASH,
2896 .alg.hash = {
Lee Nipper497f2e62010-05-19 19:20:36 +10002897 .halg.digestsize = SHA512_DIGEST_SIZE,
Horia Geant?3639ca82016-04-21 19:24:55 +03002898 .halg.statesize = sizeof(struct talitos_export_state),
Lee Nipper497f2e62010-05-19 19:20:36 +10002899 .halg.base = {
2900 .cra_name = "sha512",
2901 .cra_driver_name = "sha512-talitos",
2902 .cra_blocksize = SHA512_BLOCK_SIZE,
2903 .cra_flags = CRYPTO_ALG_TYPE_AHASH |
2904 CRYPTO_ALG_ASYNC,
Lee Nipper497f2e62010-05-19 19:20:36 +10002905 }
2906 },
2907 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2908 DESC_HDR_SEL0_MDEUB |
2909 DESC_HDR_MODE0_MDEUB_SHA512,
2910 },
Lee Nipper79b3a412011-11-21 16:13:25 +08002911 { .type = CRYPTO_ALG_TYPE_AHASH,
2912 .alg.hash = {
Lee Nipper79b3a412011-11-21 16:13:25 +08002913 .halg.digestsize = MD5_DIGEST_SIZE,
Horia Geant?3639ca82016-04-21 19:24:55 +03002914 .halg.statesize = sizeof(struct talitos_export_state),
Lee Nipper79b3a412011-11-21 16:13:25 +08002915 .halg.base = {
2916 .cra_name = "hmac(md5)",
2917 .cra_driver_name = "hmac-md5-talitos",
Martin Hicksb3988612015-03-03 08:21:34 -05002918 .cra_blocksize = MD5_HMAC_BLOCK_SIZE,
Lee Nipper79b3a412011-11-21 16:13:25 +08002919 .cra_flags = CRYPTO_ALG_TYPE_AHASH |
2920 CRYPTO_ALG_ASYNC,
Lee Nipper79b3a412011-11-21 16:13:25 +08002921 }
2922 },
2923 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2924 DESC_HDR_SEL0_MDEUA |
2925 DESC_HDR_MODE0_MDEU_MD5,
2926 },
2927 { .type = CRYPTO_ALG_TYPE_AHASH,
2928 .alg.hash = {
Lee Nipper79b3a412011-11-21 16:13:25 +08002929 .halg.digestsize = SHA1_DIGEST_SIZE,
Horia Geant?3639ca82016-04-21 19:24:55 +03002930 .halg.statesize = sizeof(struct talitos_export_state),
Lee Nipper79b3a412011-11-21 16:13:25 +08002931 .halg.base = {
2932 .cra_name = "hmac(sha1)",
2933 .cra_driver_name = "hmac-sha1-talitos",
2934 .cra_blocksize = SHA1_BLOCK_SIZE,
2935 .cra_flags = CRYPTO_ALG_TYPE_AHASH |
2936 CRYPTO_ALG_ASYNC,
Lee Nipper79b3a412011-11-21 16:13:25 +08002937 }
2938 },
2939 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2940 DESC_HDR_SEL0_MDEUA |
2941 DESC_HDR_MODE0_MDEU_SHA1,
2942 },
2943 { .type = CRYPTO_ALG_TYPE_AHASH,
2944 .alg.hash = {
Lee Nipper79b3a412011-11-21 16:13:25 +08002945 .halg.digestsize = SHA224_DIGEST_SIZE,
Horia Geant?3639ca82016-04-21 19:24:55 +03002946 .halg.statesize = sizeof(struct talitos_export_state),
Lee Nipper79b3a412011-11-21 16:13:25 +08002947 .halg.base = {
2948 .cra_name = "hmac(sha224)",
2949 .cra_driver_name = "hmac-sha224-talitos",
2950 .cra_blocksize = SHA224_BLOCK_SIZE,
2951 .cra_flags = CRYPTO_ALG_TYPE_AHASH |
2952 CRYPTO_ALG_ASYNC,
Lee Nipper79b3a412011-11-21 16:13:25 +08002953 }
2954 },
2955 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2956 DESC_HDR_SEL0_MDEUA |
2957 DESC_HDR_MODE0_MDEU_SHA224,
2958 },
2959 { .type = CRYPTO_ALG_TYPE_AHASH,
2960 .alg.hash = {
Lee Nipper79b3a412011-11-21 16:13:25 +08002961 .halg.digestsize = SHA256_DIGEST_SIZE,
Horia Geant?3639ca82016-04-21 19:24:55 +03002962 .halg.statesize = sizeof(struct talitos_export_state),
Lee Nipper79b3a412011-11-21 16:13:25 +08002963 .halg.base = {
2964 .cra_name = "hmac(sha256)",
2965 .cra_driver_name = "hmac-sha256-talitos",
2966 .cra_blocksize = SHA256_BLOCK_SIZE,
2967 .cra_flags = CRYPTO_ALG_TYPE_AHASH |
2968 CRYPTO_ALG_ASYNC,
Lee Nipper79b3a412011-11-21 16:13:25 +08002969 }
2970 },
2971 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2972 DESC_HDR_SEL0_MDEUA |
2973 DESC_HDR_MODE0_MDEU_SHA256,
2974 },
2975 { .type = CRYPTO_ALG_TYPE_AHASH,
2976 .alg.hash = {
Lee Nipper79b3a412011-11-21 16:13:25 +08002977 .halg.digestsize = SHA384_DIGEST_SIZE,
Horia Geant?3639ca82016-04-21 19:24:55 +03002978 .halg.statesize = sizeof(struct talitos_export_state),
Lee Nipper79b3a412011-11-21 16:13:25 +08002979 .halg.base = {
2980 .cra_name = "hmac(sha384)",
2981 .cra_driver_name = "hmac-sha384-talitos",
2982 .cra_blocksize = SHA384_BLOCK_SIZE,
2983 .cra_flags = CRYPTO_ALG_TYPE_AHASH |
2984 CRYPTO_ALG_ASYNC,
Lee Nipper79b3a412011-11-21 16:13:25 +08002985 }
2986 },
2987 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2988 DESC_HDR_SEL0_MDEUB |
2989 DESC_HDR_MODE0_MDEUB_SHA384,
2990 },
2991 { .type = CRYPTO_ALG_TYPE_AHASH,
2992 .alg.hash = {
Lee Nipper79b3a412011-11-21 16:13:25 +08002993 .halg.digestsize = SHA512_DIGEST_SIZE,
Horia Geant?3639ca82016-04-21 19:24:55 +03002994 .halg.statesize = sizeof(struct talitos_export_state),
Lee Nipper79b3a412011-11-21 16:13:25 +08002995 .halg.base = {
2996 .cra_name = "hmac(sha512)",
2997 .cra_driver_name = "hmac-sha512-talitos",
2998 .cra_blocksize = SHA512_BLOCK_SIZE,
2999 .cra_flags = CRYPTO_ALG_TYPE_AHASH |
3000 CRYPTO_ALG_ASYNC,
Lee Nipper79b3a412011-11-21 16:13:25 +08003001 }
3002 },
3003 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
3004 DESC_HDR_SEL0_MDEUB |
3005 DESC_HDR_MODE0_MDEUB_SHA512,
3006 }
Kim Phillips9c4a7962008-06-23 19:50:15 +08003007};
3008
3009struct talitos_crypto_alg {
3010 struct list_head entry;
3011 struct device *dev;
Lee Nipperacbf7c622010-05-19 19:19:33 +10003012 struct talitos_alg_template algt;
Kim Phillips9c4a7962008-06-23 19:50:15 +08003013};
3014
Jonas Eymann89d124c2016-04-19 20:33:47 +03003015static int talitos_init_common(struct talitos_ctx *ctx,
3016 struct talitos_crypto_alg *talitos_alg)
Kim Phillips9c4a7962008-06-23 19:50:15 +08003017{
Kim Phillips5228f0f2011-07-15 11:21:38 +08003018 struct talitos_private *priv;
Kim Phillips9c4a7962008-06-23 19:50:15 +08003019
3020 /* update context with ptr to dev */
3021 ctx->dev = talitos_alg->dev;
Kim Phillips19bbbc62009-03-29 15:53:59 +08003022
Kim Phillips5228f0f2011-07-15 11:21:38 +08003023 /* assign SEC channel to tfm in round-robin fashion */
3024 priv = dev_get_drvdata(ctx->dev);
3025 ctx->ch = atomic_inc_return(&priv->last_chan) &
3026 (priv->num_channels - 1);
3027
Kim Phillips9c4a7962008-06-23 19:50:15 +08003028 /* copy descriptor header template value */
Lee Nipperacbf7c622010-05-19 19:19:33 +10003029 ctx->desc_hdr_template = talitos_alg->algt.desc_hdr_template;
Kim Phillips9c4a7962008-06-23 19:50:15 +08003030
Kim Phillips602dba52011-07-15 11:21:39 +08003031 /* select done notification */
3032 ctx->desc_hdr_template |= DESC_HDR_DONE_NOTIFY;
3033
Lee Nipper497f2e62010-05-19 19:20:36 +10003034 return 0;
3035}
3036
Jonas Eymann89d124c2016-04-19 20:33:47 +03003037static int talitos_cra_init(struct crypto_tfm *tfm)
3038{
3039 struct crypto_alg *alg = tfm->__crt_alg;
3040 struct talitos_crypto_alg *talitos_alg;
3041 struct talitos_ctx *ctx = crypto_tfm_ctx(tfm);
3042
3043 if ((alg->cra_flags & CRYPTO_ALG_TYPE_MASK) == CRYPTO_ALG_TYPE_AHASH)
3044 talitos_alg = container_of(__crypto_ahash_alg(alg),
3045 struct talitos_crypto_alg,
3046 algt.alg.hash);
3047 else
3048 talitos_alg = container_of(alg, struct talitos_crypto_alg,
3049 algt.alg.crypto);
3050
3051 return talitos_init_common(ctx, talitos_alg);
3052}
3053
Herbert Xuaeb4c132015-07-30 17:53:22 +08003054static int talitos_cra_init_aead(struct crypto_aead *tfm)
Lee Nipper497f2e62010-05-19 19:20:36 +10003055{
Jonas Eymann89d124c2016-04-19 20:33:47 +03003056 struct aead_alg *alg = crypto_aead_alg(tfm);
3057 struct talitos_crypto_alg *talitos_alg;
3058 struct talitos_ctx *ctx = crypto_aead_ctx(tfm);
3059
3060 talitos_alg = container_of(alg, struct talitos_crypto_alg,
3061 algt.alg.aead);
3062
3063 return talitos_init_common(ctx, talitos_alg);
Kim Phillips9c4a7962008-06-23 19:50:15 +08003064}
3065
Lee Nipper497f2e62010-05-19 19:20:36 +10003066static int talitos_cra_init_ahash(struct crypto_tfm *tfm)
3067{
3068 struct talitos_ctx *ctx = crypto_tfm_ctx(tfm);
3069
3070 talitos_cra_init(tfm);
3071
3072 ctx->keylen = 0;
3073 crypto_ahash_set_reqsize(__crypto_ahash_cast(tfm),
3074 sizeof(struct talitos_ahash_req_ctx));
3075
3076 return 0;
3077}
3078
LEROY Christophe2e13ce02017-10-06 15:05:02 +02003079static void talitos_cra_exit(struct crypto_tfm *tfm)
3080{
3081 struct talitos_ctx *ctx = crypto_tfm_ctx(tfm);
3082 struct device *dev = ctx->dev;
3083
3084 if (ctx->keylen)
3085 dma_unmap_single(dev, ctx->dma_key, ctx->keylen, DMA_TO_DEVICE);
3086}
3087
Kim Phillips9c4a7962008-06-23 19:50:15 +08003088/*
3089 * given the alg's descriptor header template, determine whether descriptor
3090 * type and primary/secondary execution units required match the hw
3091 * capabilities description provided in the device tree node.
3092 */
3093static int hw_supports(struct device *dev, __be32 desc_hdr_template)
3094{
3095 struct talitos_private *priv = dev_get_drvdata(dev);
3096 int ret;
3097
3098 ret = (1 << DESC_TYPE(desc_hdr_template) & priv->desc_types) &&
3099 (1 << PRIMARY_EU(desc_hdr_template) & priv->exec_units);
3100
3101 if (SECONDARY_EU(desc_hdr_template))
3102 ret = ret && (1 << SECONDARY_EU(desc_hdr_template)
3103 & priv->exec_units);
3104
3105 return ret;
3106}
3107
Grant Likely2dc11582010-08-06 09:25:50 -06003108static int talitos_remove(struct platform_device *ofdev)
Kim Phillips9c4a7962008-06-23 19:50:15 +08003109{
3110 struct device *dev = &ofdev->dev;
3111 struct talitos_private *priv = dev_get_drvdata(dev);
3112 struct talitos_crypto_alg *t_alg, *n;
3113 int i;
3114
3115 list_for_each_entry_safe(t_alg, n, &priv->alg_list, entry) {
Lee Nipperacbf7c622010-05-19 19:19:33 +10003116 switch (t_alg->algt.type) {
3117 case CRYPTO_ALG_TYPE_ABLKCIPHER:
Lee Nipperacbf7c622010-05-19 19:19:33 +10003118 break;
Herbert Xuaeb4c132015-07-30 17:53:22 +08003119 case CRYPTO_ALG_TYPE_AEAD:
3120 crypto_unregister_aead(&t_alg->algt.alg.aead);
Lee Nipperacbf7c622010-05-19 19:19:33 +10003121 case CRYPTO_ALG_TYPE_AHASH:
3122 crypto_unregister_ahash(&t_alg->algt.alg.hash);
3123 break;
3124 }
Kim Phillips9c4a7962008-06-23 19:50:15 +08003125 list_del(&t_alg->entry);
Kim Phillips9c4a7962008-06-23 19:50:15 +08003126 }
3127
3128 if (hw_supports(dev, DESC_HDR_SEL0_RNG))
3129 talitos_unregister_rng(dev);
3130
Kim Phillipsc3e337f2011-11-21 16:13:27 +08003131 for (i = 0; i < 2; i++)
Kim Phillips2cdba3c2011-12-12 14:59:11 -06003132 if (priv->irq[i]) {
Kim Phillipsc3e337f2011-11-21 16:13:27 +08003133 free_irq(priv->irq[i], dev);
3134 irq_dispose_mapping(priv->irq[i]);
3135 }
Kim Phillips9c4a7962008-06-23 19:50:15 +08003136
Kim Phillipsc3e337f2011-11-21 16:13:27 +08003137 tasklet_kill(&priv->done_task[0]);
Kim Phillips2cdba3c2011-12-12 14:59:11 -06003138 if (priv->irq[1])
Kim Phillipsc3e337f2011-11-21 16:13:27 +08003139 tasklet_kill(&priv->done_task[1]);
Kim Phillips9c4a7962008-06-23 19:50:15 +08003140
Kim Phillips9c4a7962008-06-23 19:50:15 +08003141 return 0;
3142}
3143
3144static struct talitos_crypto_alg *talitos_alg_alloc(struct device *dev,
3145 struct talitos_alg_template
3146 *template)
3147{
Kim Phillips60f208d2010-05-19 19:21:53 +10003148 struct talitos_private *priv = dev_get_drvdata(dev);
Kim Phillips9c4a7962008-06-23 19:50:15 +08003149 struct talitos_crypto_alg *t_alg;
3150 struct crypto_alg *alg;
3151
LEROY Christophe24b92ff2017-10-06 15:04:49 +02003152 t_alg = devm_kzalloc(dev, sizeof(struct talitos_crypto_alg),
3153 GFP_KERNEL);
Kim Phillips9c4a7962008-06-23 19:50:15 +08003154 if (!t_alg)
3155 return ERR_PTR(-ENOMEM);
3156
Lee Nipperacbf7c622010-05-19 19:19:33 +10003157 t_alg->algt = *template;
3158
3159 switch (t_alg->algt.type) {
3160 case CRYPTO_ALG_TYPE_ABLKCIPHER:
Lee Nipper497f2e62010-05-19 19:20:36 +10003161 alg = &t_alg->algt.alg.crypto;
3162 alg->cra_init = talitos_cra_init;
LEROY Christophe2e13ce02017-10-06 15:05:02 +02003163 alg->cra_exit = talitos_cra_exit;
Kim Phillipsd4cd3282012-08-08 20:32:00 -05003164 alg->cra_type = &crypto_ablkcipher_type;
Kim Phillipsb286e002012-08-08 20:33:34 -05003165 alg->cra_ablkcipher.setkey = ablkcipher_setkey;
3166 alg->cra_ablkcipher.encrypt = ablkcipher_encrypt;
3167 alg->cra_ablkcipher.decrypt = ablkcipher_decrypt;
3168 alg->cra_ablkcipher.geniv = "eseqiv";
Lee Nipper497f2e62010-05-19 19:20:36 +10003169 break;
Lee Nipperacbf7c622010-05-19 19:19:33 +10003170 case CRYPTO_ALG_TYPE_AEAD:
Herbert Xuaeb4c132015-07-30 17:53:22 +08003171 alg = &t_alg->algt.alg.aead.base;
LEROY Christophe2e13ce02017-10-06 15:05:02 +02003172 alg->cra_exit = talitos_cra_exit;
Herbert Xuaeb4c132015-07-30 17:53:22 +08003173 t_alg->algt.alg.aead.init = talitos_cra_init_aead;
3174 t_alg->algt.alg.aead.setkey = aead_setkey;
3175 t_alg->algt.alg.aead.encrypt = aead_encrypt;
3176 t_alg->algt.alg.aead.decrypt = aead_decrypt;
LEROY Christophe6cda0752017-10-06 15:04:39 +02003177 if (!(priv->features & TALITOS_FTR_SHA224_HWINIT) &&
3178 !strncmp(alg->cra_name, "authenc(hmac(sha224)", 20)) {
LEROY Christophe24b92ff2017-10-06 15:04:49 +02003179 devm_kfree(dev, t_alg);
LEROY Christophe6cda0752017-10-06 15:04:39 +02003180 return ERR_PTR(-ENOTSUPP);
3181 }
Lee Nipperacbf7c622010-05-19 19:19:33 +10003182 break;
3183 case CRYPTO_ALG_TYPE_AHASH:
3184 alg = &t_alg->algt.alg.hash.halg.base;
Lee Nipper497f2e62010-05-19 19:20:36 +10003185 alg->cra_init = talitos_cra_init_ahash;
LEROY Christophead4cd512018-02-26 17:40:04 +01003186 alg->cra_exit = talitos_cra_exit;
Kim Phillipsd4cd3282012-08-08 20:32:00 -05003187 alg->cra_type = &crypto_ahash_type;
Kim Phillipsb286e002012-08-08 20:33:34 -05003188 t_alg->algt.alg.hash.init = ahash_init;
3189 t_alg->algt.alg.hash.update = ahash_update;
3190 t_alg->algt.alg.hash.final = ahash_final;
3191 t_alg->algt.alg.hash.finup = ahash_finup;
3192 t_alg->algt.alg.hash.digest = ahash_digest;
LEROY Christophe56136632017-09-12 11:03:39 +02003193 if (!strncmp(alg->cra_name, "hmac", 4))
3194 t_alg->algt.alg.hash.setkey = ahash_setkey;
Horia Geant?3639ca82016-04-21 19:24:55 +03003195 t_alg->algt.alg.hash.import = ahash_import;
3196 t_alg->algt.alg.hash.export = ahash_export;
Kim Phillipsb286e002012-08-08 20:33:34 -05003197
Lee Nipper79b3a412011-11-21 16:13:25 +08003198 if (!(priv->features & TALITOS_FTR_HMAC_OK) &&
Kim Phillips0b2730d2011-12-12 14:59:10 -06003199 !strncmp(alg->cra_name, "hmac", 4)) {
LEROY Christophe24b92ff2017-10-06 15:04:49 +02003200 devm_kfree(dev, t_alg);
Lee Nipper79b3a412011-11-21 16:13:25 +08003201 return ERR_PTR(-ENOTSUPP);
Kim Phillips0b2730d2011-12-12 14:59:10 -06003202 }
Kim Phillips60f208d2010-05-19 19:21:53 +10003203 if (!(priv->features & TALITOS_FTR_SHA224_HWINIT) &&
Lee Nipper79b3a412011-11-21 16:13:25 +08003204 (!strcmp(alg->cra_name, "sha224") ||
3205 !strcmp(alg->cra_name, "hmac(sha224)"))) {
Kim Phillips60f208d2010-05-19 19:21:53 +10003206 t_alg->algt.alg.hash.init = ahash_init_sha224_swinit;
3207 t_alg->algt.desc_hdr_template =
3208 DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
3209 DESC_HDR_SEL0_MDEUA |
3210 DESC_HDR_MODE0_MDEU_SHA256;
3211 }
Lee Nipper497f2e62010-05-19 19:20:36 +10003212 break;
Kim Phillips1d119112010-09-23 15:55:27 +08003213 default:
3214 dev_err(dev, "unknown algorithm type %d\n", t_alg->algt.type);
LEROY Christophe24b92ff2017-10-06 15:04:49 +02003215 devm_kfree(dev, t_alg);
Kim Phillips1d119112010-09-23 15:55:27 +08003216 return ERR_PTR(-EINVAL);
Lee Nipperacbf7c622010-05-19 19:19:33 +10003217 }
Kim Phillips9c4a7962008-06-23 19:50:15 +08003218
Kim Phillips9c4a7962008-06-23 19:50:15 +08003219 alg->cra_module = THIS_MODULE;
LEROY Christopheb0057762016-06-06 13:20:44 +02003220 if (t_alg->algt.priority)
3221 alg->cra_priority = t_alg->algt.priority;
3222 else
3223 alg->cra_priority = TALITOS_CRA_PRIORITY;
Kim Phillips9c4a7962008-06-23 19:50:15 +08003224 alg->cra_alignmask = 0;
Kim Phillips9c4a7962008-06-23 19:50:15 +08003225 alg->cra_ctxsize = sizeof(struct talitos_ctx);
Nikos Mavrogiannopoulosd912bb72011-11-01 13:39:56 +01003226 alg->cra_flags |= CRYPTO_ALG_KERN_DRIVER_ONLY;
Kim Phillips9c4a7962008-06-23 19:50:15 +08003227
Kim Phillips9c4a7962008-06-23 19:50:15 +08003228 t_alg->dev = dev;
3229
3230 return t_alg;
3231}
3232
Kim Phillipsc3e337f2011-11-21 16:13:27 +08003233static int talitos_probe_irq(struct platform_device *ofdev)
3234{
3235 struct device *dev = &ofdev->dev;
3236 struct device_node *np = ofdev->dev.of_node;
3237 struct talitos_private *priv = dev_get_drvdata(dev);
3238 int err;
LEROY Christophedd3c0982015-04-17 16:32:13 +02003239 bool is_sec1 = has_ftr_sec1(priv);
Kim Phillipsc3e337f2011-11-21 16:13:27 +08003240
3241 priv->irq[0] = irq_of_parse_and_map(np, 0);
Kim Phillips2cdba3c2011-12-12 14:59:11 -06003242 if (!priv->irq[0]) {
Kim Phillipsc3e337f2011-11-21 16:13:27 +08003243 dev_err(dev, "failed to map irq\n");
3244 return -EINVAL;
3245 }
LEROY Christophedd3c0982015-04-17 16:32:13 +02003246 if (is_sec1) {
3247 err = request_irq(priv->irq[0], talitos1_interrupt_4ch, 0,
3248 dev_driver_string(dev), dev);
3249 goto primary_out;
3250 }
Kim Phillipsc3e337f2011-11-21 16:13:27 +08003251
3252 priv->irq[1] = irq_of_parse_and_map(np, 1);
3253
3254 /* get the primary irq line */
Kim Phillips2cdba3c2011-12-12 14:59:11 -06003255 if (!priv->irq[1]) {
LEROY Christophedd3c0982015-04-17 16:32:13 +02003256 err = request_irq(priv->irq[0], talitos2_interrupt_4ch, 0,
Kim Phillipsc3e337f2011-11-21 16:13:27 +08003257 dev_driver_string(dev), dev);
3258 goto primary_out;
3259 }
3260
LEROY Christophedd3c0982015-04-17 16:32:13 +02003261 err = request_irq(priv->irq[0], talitos2_interrupt_ch0_2, 0,
Kim Phillipsc3e337f2011-11-21 16:13:27 +08003262 dev_driver_string(dev), dev);
3263 if (err)
3264 goto primary_out;
3265
3266 /* get the secondary irq line */
LEROY Christophedd3c0982015-04-17 16:32:13 +02003267 err = request_irq(priv->irq[1], talitos2_interrupt_ch1_3, 0,
Kim Phillipsc3e337f2011-11-21 16:13:27 +08003268 dev_driver_string(dev), dev);
3269 if (err) {
3270 dev_err(dev, "failed to request secondary irq\n");
3271 irq_dispose_mapping(priv->irq[1]);
Kim Phillips2cdba3c2011-12-12 14:59:11 -06003272 priv->irq[1] = 0;
Kim Phillipsc3e337f2011-11-21 16:13:27 +08003273 }
3274
3275 return err;
3276
3277primary_out:
3278 if (err) {
3279 dev_err(dev, "failed to request primary irq\n");
3280 irq_dispose_mapping(priv->irq[0]);
Kim Phillips2cdba3c2011-12-12 14:59:11 -06003281 priv->irq[0] = 0;
Kim Phillipsc3e337f2011-11-21 16:13:27 +08003282 }
3283
3284 return err;
3285}
3286
Grant Likely1c48a5c2011-02-17 02:43:24 -07003287static int talitos_probe(struct platform_device *ofdev)
Kim Phillips9c4a7962008-06-23 19:50:15 +08003288{
3289 struct device *dev = &ofdev->dev;
Grant Likely61c7a082010-04-13 16:12:29 -07003290 struct device_node *np = ofdev->dev.of_node;
Kim Phillips9c4a7962008-06-23 19:50:15 +08003291 struct talitos_private *priv;
Kim Phillips9c4a7962008-06-23 19:50:15 +08003292 int i, err;
LEROY Christophe5fa7fa12015-04-17 16:32:11 +02003293 int stride;
LEROY Christophefd5ea7f2017-10-06 15:04:53 +02003294 struct resource *res;
Kim Phillips9c4a7962008-06-23 19:50:15 +08003295
LEROY Christophe24b92ff2017-10-06 15:04:49 +02003296 priv = devm_kzalloc(dev, sizeof(struct talitos_private), GFP_KERNEL);
Kim Phillips9c4a7962008-06-23 19:50:15 +08003297 if (!priv)
3298 return -ENOMEM;
3299
Kevin Haof3de9cb2014-01-28 20:17:23 +08003300 INIT_LIST_HEAD(&priv->alg_list);
3301
Kim Phillips9c4a7962008-06-23 19:50:15 +08003302 dev_set_drvdata(dev, priv);
3303
3304 priv->ofdev = ofdev;
3305
Horia Geanta511d63c2012-03-30 17:49:53 +03003306 spin_lock_init(&priv->reg_lock);
3307
LEROY Christophefd5ea7f2017-10-06 15:04:53 +02003308 res = platform_get_resource(ofdev, IORESOURCE_MEM, 0);
3309 if (!res)
3310 return -ENXIO;
3311 priv->reg = devm_ioremap(dev, res->start, resource_size(res));
Kim Phillips9c4a7962008-06-23 19:50:15 +08003312 if (!priv->reg) {
3313 dev_err(dev, "failed to of_iomap\n");
3314 err = -ENOMEM;
3315 goto err_out;
3316 }
3317
3318 /* get SEC version capabilities from device tree */
LEROY Christophefa14c6c2017-10-06 15:04:51 +02003319 of_property_read_u32(np, "fsl,num-channels", &priv->num_channels);
3320 of_property_read_u32(np, "fsl,channel-fifo-len", &priv->chfifo_len);
3321 of_property_read_u32(np, "fsl,exec-units-mask", &priv->exec_units);
3322 of_property_read_u32(np, "fsl,descriptor-types-mask",
3323 &priv->desc_types);
Kim Phillips9c4a7962008-06-23 19:50:15 +08003324
3325 if (!is_power_of_2(priv->num_channels) || !priv->chfifo_len ||
3326 !priv->exec_units || !priv->desc_types) {
3327 dev_err(dev, "invalid property data in device tree node\n");
3328 err = -EINVAL;
3329 goto err_out;
3330 }
3331
Lee Nipperf3c85bc2008-07-30 16:26:57 +08003332 if (of_device_is_compatible(np, "fsl,sec3.0"))
3333 priv->features |= TALITOS_FTR_SRC_LINK_TBL_LEN_INCLUDES_EXTENT;
3334
Kim Phillipsfe5720e2008-10-12 20:33:14 +08003335 if (of_device_is_compatible(np, "fsl,sec2.1"))
Kim Phillips60f208d2010-05-19 19:21:53 +10003336 priv->features |= TALITOS_FTR_HW_AUTH_CHECK |
Lee Nipper79b3a412011-11-21 16:13:25 +08003337 TALITOS_FTR_SHA224_HWINIT |
3338 TALITOS_FTR_HMAC_OK;
Kim Phillipsfe5720e2008-10-12 20:33:14 +08003339
LEROY Christophe21590882015-04-17 16:32:05 +02003340 if (of_device_is_compatible(np, "fsl,sec1.0"))
3341 priv->features |= TALITOS_FTR_SEC1;
3342
LEROY Christophe5fa7fa12015-04-17 16:32:11 +02003343 if (of_device_is_compatible(np, "fsl,sec1.2")) {
3344 priv->reg_deu = priv->reg + TALITOS12_DEU;
3345 priv->reg_aesu = priv->reg + TALITOS12_AESU;
3346 priv->reg_mdeu = priv->reg + TALITOS12_MDEU;
3347 stride = TALITOS1_CH_STRIDE;
3348 } else if (of_device_is_compatible(np, "fsl,sec1.0")) {
3349 priv->reg_deu = priv->reg + TALITOS10_DEU;
3350 priv->reg_aesu = priv->reg + TALITOS10_AESU;
3351 priv->reg_mdeu = priv->reg + TALITOS10_MDEU;
3352 priv->reg_afeu = priv->reg + TALITOS10_AFEU;
3353 priv->reg_rngu = priv->reg + TALITOS10_RNGU;
3354 priv->reg_pkeu = priv->reg + TALITOS10_PKEU;
3355 stride = TALITOS1_CH_STRIDE;
3356 } else {
3357 priv->reg_deu = priv->reg + TALITOS2_DEU;
3358 priv->reg_aesu = priv->reg + TALITOS2_AESU;
3359 priv->reg_mdeu = priv->reg + TALITOS2_MDEU;
3360 priv->reg_afeu = priv->reg + TALITOS2_AFEU;
3361 priv->reg_rngu = priv->reg + TALITOS2_RNGU;
3362 priv->reg_pkeu = priv->reg + TALITOS2_PKEU;
3363 priv->reg_keu = priv->reg + TALITOS2_KEU;
3364 priv->reg_crcu = priv->reg + TALITOS2_CRCU;
3365 stride = TALITOS2_CH_STRIDE;
3366 }
3367
LEROY Christophedd3c0982015-04-17 16:32:13 +02003368 err = talitos_probe_irq(ofdev);
3369 if (err)
3370 goto err_out;
3371
3372 if (of_device_is_compatible(np, "fsl,sec1.0")) {
LEROY Christophe9c02e282017-10-06 15:04:55 +02003373 if (priv->num_channels == 1)
3374 tasklet_init(&priv->done_task[0], talitos1_done_ch0,
LEROY Christophedd3c0982015-04-17 16:32:13 +02003375 (unsigned long)dev);
LEROY Christophe9c02e282017-10-06 15:04:55 +02003376 else
3377 tasklet_init(&priv->done_task[0], talitos1_done_4ch,
3378 (unsigned long)dev);
3379 } else {
3380 if (priv->irq[1]) {
LEROY Christophedd3c0982015-04-17 16:32:13 +02003381 tasklet_init(&priv->done_task[0], talitos2_done_ch0_2,
3382 (unsigned long)dev);
3383 tasklet_init(&priv->done_task[1], talitos2_done_ch1_3,
3384 (unsigned long)dev);
LEROY Christophe9c02e282017-10-06 15:04:55 +02003385 } else if (priv->num_channels == 1) {
3386 tasklet_init(&priv->done_task[0], talitos2_done_ch0,
3387 (unsigned long)dev);
3388 } else {
3389 tasklet_init(&priv->done_task[0], talitos2_done_4ch,
3390 (unsigned long)dev);
LEROY Christophedd3c0982015-04-17 16:32:13 +02003391 }
3392 }
3393
LEROY Christophe24b92ff2017-10-06 15:04:49 +02003394 priv->chan = devm_kzalloc(dev, sizeof(struct talitos_channel) *
3395 priv->num_channels, GFP_KERNEL);
Kim Phillips4b9926282009-08-13 11:50:38 +10003396 if (!priv->chan) {
3397 dev_err(dev, "failed to allocate channel management space\n");
Kim Phillips9c4a7962008-06-23 19:50:15 +08003398 err = -ENOMEM;
3399 goto err_out;
3400 }
3401
Martin Hicksf641ddd2015-03-03 08:21:33 -05003402 priv->fifo_len = roundup_pow_of_two(priv->chfifo_len);
3403
Kim Phillipsc3e337f2011-11-21 16:13:27 +08003404 for (i = 0; i < priv->num_channels; i++) {
LEROY Christophe5fa7fa12015-04-17 16:32:11 +02003405 priv->chan[i].reg = priv->reg + stride * (i + 1);
Kim Phillips2cdba3c2011-12-12 14:59:11 -06003406 if (!priv->irq[1] || !(i & 1))
Kim Phillipsc3e337f2011-11-21 16:13:27 +08003407 priv->chan[i].reg += TALITOS_CH_BASE_OFFSET;
Kim Phillipsad42d5f2011-11-21 16:13:27 +08003408
Kim Phillips4b9926282009-08-13 11:50:38 +10003409 spin_lock_init(&priv->chan[i].head_lock);
3410 spin_lock_init(&priv->chan[i].tail_lock);
Kim Phillips9c4a7962008-06-23 19:50:15 +08003411
LEROY Christophe24b92ff2017-10-06 15:04:49 +02003412 priv->chan[i].fifo = devm_kzalloc(dev,
3413 sizeof(struct talitos_request) *
3414 priv->fifo_len, GFP_KERNEL);
Kim Phillips4b9926282009-08-13 11:50:38 +10003415 if (!priv->chan[i].fifo) {
Kim Phillips9c4a7962008-06-23 19:50:15 +08003416 dev_err(dev, "failed to allocate request fifo %d\n", i);
3417 err = -ENOMEM;
3418 goto err_out;
3419 }
Kim Phillips9c4a7962008-06-23 19:50:15 +08003420
Kim Phillips4b9926282009-08-13 11:50:38 +10003421 atomic_set(&priv->chan[i].submit_count,
3422 -(priv->chfifo_len - 1));
Martin Hicksf641ddd2015-03-03 08:21:33 -05003423 }
Kim Phillips9c4a7962008-06-23 19:50:15 +08003424
Kim Phillips81eb0242009-08-13 11:51:51 +10003425 dma_set_mask(dev, DMA_BIT_MASK(36));
3426
Kim Phillips9c4a7962008-06-23 19:50:15 +08003427 /* reset and initialize the h/w */
3428 err = init_device(dev);
3429 if (err) {
3430 dev_err(dev, "failed to initialize device\n");
3431 goto err_out;
3432 }
3433
3434 /* register the RNG, if available */
3435 if (hw_supports(dev, DESC_HDR_SEL0_RNG)) {
3436 err = talitos_register_rng(dev);
3437 if (err) {
3438 dev_err(dev, "failed to register hwrng: %d\n", err);
3439 goto err_out;
3440 } else
3441 dev_info(dev, "hwrng\n");
3442 }
3443
3444 /* register crypto algorithms the device supports */
Kim Phillips9c4a7962008-06-23 19:50:15 +08003445 for (i = 0; i < ARRAY_SIZE(driver_algs); i++) {
3446 if (hw_supports(dev, driver_algs[i].desc_hdr_template)) {
3447 struct talitos_crypto_alg *t_alg;
Herbert Xuaeb4c132015-07-30 17:53:22 +08003448 struct crypto_alg *alg = NULL;
Kim Phillips9c4a7962008-06-23 19:50:15 +08003449
3450 t_alg = talitos_alg_alloc(dev, &driver_algs[i]);
3451 if (IS_ERR(t_alg)) {
3452 err = PTR_ERR(t_alg);
Kim Phillips0b2730d2011-12-12 14:59:10 -06003453 if (err == -ENOTSUPP)
Lee Nipper79b3a412011-11-21 16:13:25 +08003454 continue;
Kim Phillips9c4a7962008-06-23 19:50:15 +08003455 goto err_out;
3456 }
3457
Lee Nipperacbf7c622010-05-19 19:19:33 +10003458 switch (t_alg->algt.type) {
3459 case CRYPTO_ALG_TYPE_ABLKCIPHER:
Lee Nipperacbf7c622010-05-19 19:19:33 +10003460 err = crypto_register_alg(
3461 &t_alg->algt.alg.crypto);
Herbert Xuaeb4c132015-07-30 17:53:22 +08003462 alg = &t_alg->algt.alg.crypto;
Lee Nipperacbf7c622010-05-19 19:19:33 +10003463 break;
Herbert Xuaeb4c132015-07-30 17:53:22 +08003464
3465 case CRYPTO_ALG_TYPE_AEAD:
3466 err = crypto_register_aead(
3467 &t_alg->algt.alg.aead);
3468 alg = &t_alg->algt.alg.aead.base;
3469 break;
3470
Lee Nipperacbf7c622010-05-19 19:19:33 +10003471 case CRYPTO_ALG_TYPE_AHASH:
3472 err = crypto_register_ahash(
3473 &t_alg->algt.alg.hash);
Herbert Xuaeb4c132015-07-30 17:53:22 +08003474 alg = &t_alg->algt.alg.hash.halg.base;
Lee Nipperacbf7c622010-05-19 19:19:33 +10003475 break;
3476 }
Kim Phillips9c4a7962008-06-23 19:50:15 +08003477 if (err) {
3478 dev_err(dev, "%s alg registration failed\n",
Herbert Xuaeb4c132015-07-30 17:53:22 +08003479 alg->cra_driver_name);
LEROY Christophe24b92ff2017-10-06 15:04:49 +02003480 devm_kfree(dev, t_alg);
Horia Geanta991155b2013-03-20 16:31:38 +02003481 } else
Kim Phillips9c4a7962008-06-23 19:50:15 +08003482 list_add_tail(&t_alg->entry, &priv->alg_list);
Kim Phillips9c4a7962008-06-23 19:50:15 +08003483 }
3484 }
Kim Phillips5b859b6e2011-11-21 16:13:26 +08003485 if (!list_empty(&priv->alg_list))
3486 dev_info(dev, "%s algorithms registered in /proc/crypto\n",
3487 (char *)of_get_property(np, "compatible", NULL));
Kim Phillips9c4a7962008-06-23 19:50:15 +08003488
3489 return 0;
3490
3491err_out:
3492 talitos_remove(ofdev);
Kim Phillips9c4a7962008-06-23 19:50:15 +08003493
3494 return err;
3495}
3496
Márton Németh6c3f9752010-01-17 21:54:01 +11003497static const struct of_device_id talitos_match[] = {
LEROY Christophe0635b7db2015-04-17 16:32:20 +02003498#ifdef CONFIG_CRYPTO_DEV_TALITOS1
3499 {
3500 .compatible = "fsl,sec1.0",
3501 },
3502#endif
3503#ifdef CONFIG_CRYPTO_DEV_TALITOS2
Kim Phillips9c4a7962008-06-23 19:50:15 +08003504 {
3505 .compatible = "fsl,sec2.0",
3506 },
LEROY Christophe0635b7db2015-04-17 16:32:20 +02003507#endif
Kim Phillips9c4a7962008-06-23 19:50:15 +08003508 {},
3509};
3510MODULE_DEVICE_TABLE(of, talitos_match);
3511
Grant Likely1c48a5c2011-02-17 02:43:24 -07003512static struct platform_driver talitos_driver = {
Grant Likely40182942010-04-13 16:13:02 -07003513 .driver = {
3514 .name = "talitos",
Grant Likely40182942010-04-13 16:13:02 -07003515 .of_match_table = talitos_match,
3516 },
Kim Phillips9c4a7962008-06-23 19:50:15 +08003517 .probe = talitos_probe,
Al Viro596f1032008-11-22 17:34:24 +00003518 .remove = talitos_remove,
Kim Phillips9c4a7962008-06-23 19:50:15 +08003519};
3520
Axel Lin741e8c22011-11-26 21:26:19 +08003521module_platform_driver(talitos_driver);
Kim Phillips9c4a7962008-06-23 19:50:15 +08003522
3523MODULE_LICENSE("GPL");
3524MODULE_AUTHOR("Kim Phillips <kim.phillips@freescale.com>");
3525MODULE_DESCRIPTION("Freescale integrated security engine (SEC) driver");