blob: f3b540153d0fc7bd5e5a035b6d199e4ff40bac2b [file] [log] [blame]
Kim Phillips9c4a7962008-06-23 19:50:15 +08001/*
2 * talitos - Freescale Integrated Security Engine (SEC) device driver
3 *
Kim Phillips5228f0f2011-07-15 11:21:38 +08004 * Copyright (c) 2008-2011 Freescale Semiconductor, Inc.
Kim Phillips9c4a7962008-06-23 19:50:15 +08005 *
6 * Scatterlist Crypto API glue code copied from files with the following:
7 * Copyright (c) 2006-2007 Herbert Xu <herbert@gondor.apana.org.au>
8 *
9 * Crypto algorithm registration code copied from hifn driver:
10 * 2007+ Copyright (c) Evgeniy Polyakov <johnpol@2ka.mipt.ru>
11 * All rights reserved.
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 */
27
28#include <linux/kernel.h>
29#include <linux/module.h>
30#include <linux/mod_devicetable.h>
31#include <linux/device.h>
32#include <linux/interrupt.h>
33#include <linux/crypto.h>
34#include <linux/hw_random.h>
Rob Herring5af50732013-09-17 14:28:33 -050035#include <linux/of_address.h>
36#include <linux/of_irq.h>
Kim Phillips9c4a7962008-06-23 19:50:15 +080037#include <linux/of_platform.h>
38#include <linux/dma-mapping.h>
39#include <linux/io.h>
40#include <linux/spinlock.h>
41#include <linux/rtnetlink.h>
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090042#include <linux/slab.h>
Kim Phillips9c4a7962008-06-23 19:50:15 +080043
44#include <crypto/algapi.h>
45#include <crypto/aes.h>
Lee Nipper3952f172008-07-10 18:29:18 +080046#include <crypto/des.h>
Kim Phillips9c4a7962008-06-23 19:50:15 +080047#include <crypto/sha.h>
Lee Nipper497f2e62010-05-19 19:20:36 +100048#include <crypto/md5.h>
Herbert Xue98014a2015-05-11 17:47:48 +080049#include <crypto/internal/aead.h>
Kim Phillips9c4a7962008-06-23 19:50:15 +080050#include <crypto/authenc.h>
Lee Nipper4de9d0b2009-03-29 15:52:32 +080051#include <crypto/skcipher.h>
Lee Nipperacbf7c622010-05-19 19:19:33 +100052#include <crypto/hash.h>
53#include <crypto/internal/hash.h>
Lee Nipper4de9d0b2009-03-29 15:52:32 +080054#include <crypto/scatterwalk.h>
Kim Phillips9c4a7962008-06-23 19:50:15 +080055
56#include "talitos.h"
57
LEROY Christophe922f9dc2015-04-17 16:32:07 +020058static void to_talitos_ptr(struct talitos_ptr *ptr, dma_addr_t dma_addr,
59 bool is_sec1)
Kim Phillips81eb0242009-08-13 11:51:51 +100060{
LEROY Christopheedc6bd62015-04-17 16:31:53 +020061 ptr->ptr = cpu_to_be32(lower_32_bits(dma_addr));
LEROY Christophe922f9dc2015-04-17 16:32:07 +020062 if (!is_sec1)
63 ptr->eptr = upper_32_bits(dma_addr);
Kim Phillips81eb0242009-08-13 11:51:51 +100064}
65
Horia Geant?42e8b0d2015-05-11 20:04:56 +030066static void to_talitos_ptr_len(struct talitos_ptr *ptr, unsigned int len,
LEROY Christophe922f9dc2015-04-17 16:32:07 +020067 bool is_sec1)
LEROY Christophe538caf82015-04-17 16:31:59 +020068{
LEROY Christophe922f9dc2015-04-17 16:32:07 +020069 if (is_sec1) {
70 ptr->res = 0;
71 ptr->len1 = cpu_to_be16(len);
72 } else {
73 ptr->len = cpu_to_be16(len);
74 }
LEROY Christophe538caf82015-04-17 16:31:59 +020075}
76
LEROY Christophe922f9dc2015-04-17 16:32:07 +020077static unsigned short from_talitos_ptr_len(struct talitos_ptr *ptr,
78 bool is_sec1)
LEROY Christophe538caf82015-04-17 16:31:59 +020079{
LEROY Christophe922f9dc2015-04-17 16:32:07 +020080 if (is_sec1)
81 return be16_to_cpu(ptr->len1);
82 else
83 return be16_to_cpu(ptr->len);
LEROY Christophe538caf82015-04-17 16:31:59 +020084}
85
LEROY Christophe922f9dc2015-04-17 16:32:07 +020086static void to_talitos_ptr_extent_clear(struct talitos_ptr *ptr, bool is_sec1)
LEROY Christophe185eb792015-04-17 16:31:55 +020087{
LEROY Christophe922f9dc2015-04-17 16:32:07 +020088 if (!is_sec1)
89 ptr->j_extent = 0;
LEROY Christophe185eb792015-04-17 16:31:55 +020090}
91
Kim Phillips9c4a7962008-06-23 19:50:15 +080092/*
93 * map virtual single (contiguous) pointer to h/w descriptor pointer
94 */
95static void map_single_talitos_ptr(struct device *dev,
LEROY Christopheedc6bd62015-04-17 16:31:53 +020096 struct talitos_ptr *ptr,
Horia Geant?42e8b0d2015-05-11 20:04:56 +030097 unsigned int len, void *data,
Kim Phillips9c4a7962008-06-23 19:50:15 +080098 enum dma_data_direction dir)
99{
Kim Phillips81eb0242009-08-13 11:51:51 +1000100 dma_addr_t dma_addr = dma_map_single(dev, data, len, dir);
LEROY Christophe922f9dc2015-04-17 16:32:07 +0200101 struct talitos_private *priv = dev_get_drvdata(dev);
102 bool is_sec1 = has_ftr_sec1(priv);
Kim Phillips81eb0242009-08-13 11:51:51 +1000103
LEROY Christophe922f9dc2015-04-17 16:32:07 +0200104 to_talitos_ptr_len(ptr, len, is_sec1);
105 to_talitos_ptr(ptr, dma_addr, is_sec1);
106 to_talitos_ptr_extent_clear(ptr, is_sec1);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800107}
108
109/*
110 * unmap bus single (contiguous) h/w descriptor pointer
111 */
112static void unmap_single_talitos_ptr(struct device *dev,
LEROY Christopheedc6bd62015-04-17 16:31:53 +0200113 struct talitos_ptr *ptr,
Kim Phillips9c4a7962008-06-23 19:50:15 +0800114 enum dma_data_direction dir)
115{
LEROY Christophe922f9dc2015-04-17 16:32:07 +0200116 struct talitos_private *priv = dev_get_drvdata(dev);
117 bool is_sec1 = has_ftr_sec1(priv);
118
LEROY Christopheedc6bd62015-04-17 16:31:53 +0200119 dma_unmap_single(dev, be32_to_cpu(ptr->ptr),
LEROY Christophe922f9dc2015-04-17 16:32:07 +0200120 from_talitos_ptr_len(ptr, is_sec1), dir);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800121}
122
123static int reset_channel(struct device *dev, int ch)
124{
125 struct talitos_private *priv = dev_get_drvdata(dev);
126 unsigned int timeout = TALITOS_TIMEOUT;
LEROY Christophedd3c0982015-04-17 16:32:13 +0200127 bool is_sec1 = has_ftr_sec1(priv);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800128
LEROY Christophedd3c0982015-04-17 16:32:13 +0200129 if (is_sec1) {
130 setbits32(priv->chan[ch].reg + TALITOS_CCCR_LO,
131 TALITOS1_CCCR_LO_RESET);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800132
LEROY Christophedd3c0982015-04-17 16:32:13 +0200133 while ((in_be32(priv->chan[ch].reg + TALITOS_CCCR_LO) &
134 TALITOS1_CCCR_LO_RESET) && --timeout)
135 cpu_relax();
136 } else {
137 setbits32(priv->chan[ch].reg + TALITOS_CCCR,
138 TALITOS2_CCCR_RESET);
139
140 while ((in_be32(priv->chan[ch].reg + TALITOS_CCCR) &
141 TALITOS2_CCCR_RESET) && --timeout)
142 cpu_relax();
143 }
Kim Phillips9c4a7962008-06-23 19:50:15 +0800144
145 if (timeout == 0) {
146 dev_err(dev, "failed to reset channel %d\n", ch);
147 return -EIO;
148 }
149
Kim Phillips81eb0242009-08-13 11:51:51 +1000150 /* set 36-bit addressing, done writeback enable and done IRQ enable */
Kim Phillipsad42d5f2011-11-21 16:13:27 +0800151 setbits32(priv->chan[ch].reg + TALITOS_CCCR_LO, TALITOS_CCCR_LO_EAE |
Kim Phillips81eb0242009-08-13 11:51:51 +1000152 TALITOS_CCCR_LO_CDWE | TALITOS_CCCR_LO_CDIE);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800153
Kim Phillipsfe5720e2008-10-12 20:33:14 +0800154 /* and ICCR writeback, if available */
155 if (priv->features & TALITOS_FTR_HW_AUTH_CHECK)
Kim Phillipsad42d5f2011-11-21 16:13:27 +0800156 setbits32(priv->chan[ch].reg + TALITOS_CCCR_LO,
Kim Phillipsfe5720e2008-10-12 20:33:14 +0800157 TALITOS_CCCR_LO_IWSE);
158
Kim Phillips9c4a7962008-06-23 19:50:15 +0800159 return 0;
160}
161
162static int reset_device(struct device *dev)
163{
164 struct talitos_private *priv = dev_get_drvdata(dev);
165 unsigned int timeout = TALITOS_TIMEOUT;
LEROY Christophedd3c0982015-04-17 16:32:13 +0200166 bool is_sec1 = has_ftr_sec1(priv);
167 u32 mcr = is_sec1 ? TALITOS1_MCR_SWR : TALITOS2_MCR_SWR;
Kim Phillips9c4a7962008-06-23 19:50:15 +0800168
Kim Phillipsc3e337f2011-11-21 16:13:27 +0800169 setbits32(priv->reg + TALITOS_MCR, mcr);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800170
LEROY Christophedd3c0982015-04-17 16:32:13 +0200171 while ((in_be32(priv->reg + TALITOS_MCR) & mcr)
Kim Phillips9c4a7962008-06-23 19:50:15 +0800172 && --timeout)
173 cpu_relax();
174
Kim Phillips2cdba3c2011-12-12 14:59:11 -0600175 if (priv->irq[1]) {
Kim Phillipsc3e337f2011-11-21 16:13:27 +0800176 mcr = TALITOS_MCR_RCA1 | TALITOS_MCR_RCA3;
177 setbits32(priv->reg + TALITOS_MCR, mcr);
178 }
179
Kim Phillips9c4a7962008-06-23 19:50:15 +0800180 if (timeout == 0) {
181 dev_err(dev, "failed to reset device\n");
182 return -EIO;
183 }
184
185 return 0;
186}
187
188/*
189 * Reset and initialize the device
190 */
191static int init_device(struct device *dev)
192{
193 struct talitos_private *priv = dev_get_drvdata(dev);
194 int ch, err;
LEROY Christophedd3c0982015-04-17 16:32:13 +0200195 bool is_sec1 = has_ftr_sec1(priv);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800196
197 /*
198 * Master reset
199 * errata documentation: warning: certain SEC interrupts
200 * are not fully cleared by writing the MCR:SWR bit,
201 * set bit twice to completely reset
202 */
203 err = reset_device(dev);
204 if (err)
205 return err;
206
207 err = reset_device(dev);
208 if (err)
209 return err;
210
211 /* reset channels */
212 for (ch = 0; ch < priv->num_channels; ch++) {
213 err = reset_channel(dev, ch);
214 if (err)
215 return err;
216 }
217
218 /* enable channel done and error interrupts */
LEROY Christophedd3c0982015-04-17 16:32:13 +0200219 if (is_sec1) {
220 clrbits32(priv->reg + TALITOS_IMR, TALITOS1_IMR_INIT);
221 clrbits32(priv->reg + TALITOS_IMR_LO, TALITOS1_IMR_LO_INIT);
222 /* disable parity error check in DEU (erroneous? test vect.) */
223 setbits32(priv->reg_deu + TALITOS_EUICR, TALITOS1_DEUICR_KPE);
224 } else {
225 setbits32(priv->reg + TALITOS_IMR, TALITOS2_IMR_INIT);
226 setbits32(priv->reg + TALITOS_IMR_LO, TALITOS2_IMR_LO_INIT);
227 }
Kim Phillips9c4a7962008-06-23 19:50:15 +0800228
Kim Phillipsfe5720e2008-10-12 20:33:14 +0800229 /* disable integrity check error interrupts (use writeback instead) */
230 if (priv->features & TALITOS_FTR_HW_AUTH_CHECK)
LEROY Christophe5fa7fa12015-04-17 16:32:11 +0200231 setbits32(priv->reg_mdeu + TALITOS_EUICR_LO,
Kim Phillipsfe5720e2008-10-12 20:33:14 +0800232 TALITOS_MDEUICR_LO_ICE);
233
Kim Phillips9c4a7962008-06-23 19:50:15 +0800234 return 0;
235}
236
237/**
238 * talitos_submit - submits a descriptor to the device for processing
239 * @dev: the SEC device to be used
Kim Phillips5228f0f2011-07-15 11:21:38 +0800240 * @ch: the SEC device channel to be used
Kim Phillips9c4a7962008-06-23 19:50:15 +0800241 * @desc: the descriptor to be processed by the device
242 * @callback: whom to call when processing is complete
243 * @context: a handle for use by caller (optional)
244 *
245 * desc must contain valid dma-mapped (bus physical) address pointers.
246 * callback must check err and feedback in descriptor header
247 * for device processing status.
248 */
Horia Geanta865d5062012-07-03 19:16:52 +0300249int talitos_submit(struct device *dev, int ch, struct talitos_desc *desc,
250 void (*callback)(struct device *dev,
251 struct talitos_desc *desc,
252 void *context, int error),
253 void *context)
Kim Phillips9c4a7962008-06-23 19:50:15 +0800254{
255 struct talitos_private *priv = dev_get_drvdata(dev);
256 struct talitos_request *request;
Kim Phillips5228f0f2011-07-15 11:21:38 +0800257 unsigned long flags;
Kim Phillips9c4a7962008-06-23 19:50:15 +0800258 int head;
LEROY Christophe7d607c6a2015-04-17 16:32:09 +0200259 bool is_sec1 = has_ftr_sec1(priv);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800260
Kim Phillips4b9926282009-08-13 11:50:38 +1000261 spin_lock_irqsave(&priv->chan[ch].head_lock, flags);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800262
Kim Phillips4b9926282009-08-13 11:50:38 +1000263 if (!atomic_inc_not_zero(&priv->chan[ch].submit_count)) {
Kim Phillipsec6644d2008-07-17 20:16:40 +0800264 /* h/w fifo is full */
Kim Phillips4b9926282009-08-13 11:50:38 +1000265 spin_unlock_irqrestore(&priv->chan[ch].head_lock, flags);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800266 return -EAGAIN;
267 }
268
Kim Phillips4b9926282009-08-13 11:50:38 +1000269 head = priv->chan[ch].head;
270 request = &priv->chan[ch].fifo[head];
Kim Phillipsec6644d2008-07-17 20:16:40 +0800271
Kim Phillips9c4a7962008-06-23 19:50:15 +0800272 /* map descriptor and save caller data */
LEROY Christophe7d607c6a2015-04-17 16:32:09 +0200273 if (is_sec1) {
274 desc->hdr1 = desc->hdr;
275 desc->next_desc = 0;
276 request->dma_desc = dma_map_single(dev, &desc->hdr1,
277 TALITOS_DESC_SIZE,
278 DMA_BIDIRECTIONAL);
279 } else {
280 request->dma_desc = dma_map_single(dev, desc,
281 TALITOS_DESC_SIZE,
282 DMA_BIDIRECTIONAL);
283 }
Kim Phillips9c4a7962008-06-23 19:50:15 +0800284 request->callback = callback;
285 request->context = context;
286
287 /* increment fifo head */
Kim Phillips4b9926282009-08-13 11:50:38 +1000288 priv->chan[ch].head = (priv->chan[ch].head + 1) & (priv->fifo_len - 1);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800289
290 smp_wmb();
291 request->desc = desc;
292
293 /* GO! */
294 wmb();
Kim Phillipsad42d5f2011-11-21 16:13:27 +0800295 out_be32(priv->chan[ch].reg + TALITOS_FF,
296 upper_32_bits(request->dma_desc));
297 out_be32(priv->chan[ch].reg + TALITOS_FF_LO,
Kim Phillipsa7524472010-09-23 15:56:38 +0800298 lower_32_bits(request->dma_desc));
Kim Phillips9c4a7962008-06-23 19:50:15 +0800299
Kim Phillips4b9926282009-08-13 11:50:38 +1000300 spin_unlock_irqrestore(&priv->chan[ch].head_lock, flags);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800301
302 return -EINPROGRESS;
303}
Horia Geanta865d5062012-07-03 19:16:52 +0300304EXPORT_SYMBOL(talitos_submit);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800305
306/*
307 * process what was done, notify callback of error if not
308 */
309static void flush_channel(struct device *dev, int ch, int error, int reset_ch)
310{
311 struct talitos_private *priv = dev_get_drvdata(dev);
312 struct talitos_request *request, saved_req;
313 unsigned long flags;
314 int tail, status;
LEROY Christophe7d607c6a2015-04-17 16:32:09 +0200315 bool is_sec1 = has_ftr_sec1(priv);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800316
Kim Phillips4b9926282009-08-13 11:50:38 +1000317 spin_lock_irqsave(&priv->chan[ch].tail_lock, flags);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800318
Kim Phillips4b9926282009-08-13 11:50:38 +1000319 tail = priv->chan[ch].tail;
320 while (priv->chan[ch].fifo[tail].desc) {
LEROY Christophe7d607c6a2015-04-17 16:32:09 +0200321 __be32 hdr;
322
Kim Phillips4b9926282009-08-13 11:50:38 +1000323 request = &priv->chan[ch].fifo[tail];
Kim Phillips9c4a7962008-06-23 19:50:15 +0800324
325 /* descriptors with their done bits set don't get the error */
326 rmb();
LEROY Christophe7d607c6a2015-04-17 16:32:09 +0200327 hdr = is_sec1 ? request->desc->hdr1 : request->desc->hdr;
328
329 if ((hdr & DESC_HDR_DONE) == DESC_HDR_DONE)
Kim Phillips9c4a7962008-06-23 19:50:15 +0800330 status = 0;
Lee Nipperca38a812008-12-20 17:09:25 +1100331 else
Kim Phillips9c4a7962008-06-23 19:50:15 +0800332 if (!error)
333 break;
334 else
335 status = error;
336
337 dma_unmap_single(dev, request->dma_desc,
LEROY Christophe7d607c6a2015-04-17 16:32:09 +0200338 TALITOS_DESC_SIZE,
Kim Phillipse938e462009-03-29 15:53:23 +0800339 DMA_BIDIRECTIONAL);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800340
341 /* copy entries so we can call callback outside lock */
342 saved_req.desc = request->desc;
343 saved_req.callback = request->callback;
344 saved_req.context = request->context;
345
346 /* release request entry in fifo */
347 smp_wmb();
348 request->desc = NULL;
349
350 /* increment fifo tail */
Kim Phillips4b9926282009-08-13 11:50:38 +1000351 priv->chan[ch].tail = (tail + 1) & (priv->fifo_len - 1);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800352
Kim Phillips4b9926282009-08-13 11:50:38 +1000353 spin_unlock_irqrestore(&priv->chan[ch].tail_lock, flags);
Kim Phillipsec6644d2008-07-17 20:16:40 +0800354
Kim Phillips4b9926282009-08-13 11:50:38 +1000355 atomic_dec(&priv->chan[ch].submit_count);
Kim Phillipsec6644d2008-07-17 20:16:40 +0800356
Kim Phillips9c4a7962008-06-23 19:50:15 +0800357 saved_req.callback(dev, saved_req.desc, saved_req.context,
358 status);
359 /* channel may resume processing in single desc error case */
360 if (error && !reset_ch && status == error)
361 return;
Kim Phillips4b9926282009-08-13 11:50:38 +1000362 spin_lock_irqsave(&priv->chan[ch].tail_lock, flags);
363 tail = priv->chan[ch].tail;
Kim Phillips9c4a7962008-06-23 19:50:15 +0800364 }
365
Kim Phillips4b9926282009-08-13 11:50:38 +1000366 spin_unlock_irqrestore(&priv->chan[ch].tail_lock, flags);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800367}
368
369/*
370 * process completed requests for channels that have done status
371 */
LEROY Christophedd3c0982015-04-17 16:32:13 +0200372#define DEF_TALITOS1_DONE(name, ch_done_mask) \
373static void talitos1_done_##name(unsigned long data) \
374{ \
375 struct device *dev = (struct device *)data; \
376 struct talitos_private *priv = dev_get_drvdata(dev); \
377 unsigned long flags; \
378 \
379 if (ch_done_mask & 0x10000000) \
380 flush_channel(dev, 0, 0, 0); \
381 if (priv->num_channels == 1) \
382 goto out; \
383 if (ch_done_mask & 0x40000000) \
384 flush_channel(dev, 1, 0, 0); \
385 if (ch_done_mask & 0x00010000) \
386 flush_channel(dev, 2, 0, 0); \
387 if (ch_done_mask & 0x00040000) \
388 flush_channel(dev, 3, 0, 0); \
389 \
390out: \
391 /* At this point, all completed channels have been processed */ \
392 /* Unmask done interrupts for channels completed later on. */ \
393 spin_lock_irqsave(&priv->reg_lock, flags); \
394 clrbits32(priv->reg + TALITOS_IMR, ch_done_mask); \
395 clrbits32(priv->reg + TALITOS_IMR_LO, TALITOS1_IMR_LO_INIT); \
396 spin_unlock_irqrestore(&priv->reg_lock, flags); \
397}
398
399DEF_TALITOS1_DONE(4ch, TALITOS1_ISR_4CHDONE)
400
401#define DEF_TALITOS2_DONE(name, ch_done_mask) \
402static void talitos2_done_##name(unsigned long data) \
Kim Phillipsc3e337f2011-11-21 16:13:27 +0800403{ \
404 struct device *dev = (struct device *)data; \
405 struct talitos_private *priv = dev_get_drvdata(dev); \
Horia Geanta511d63c2012-03-30 17:49:53 +0300406 unsigned long flags; \
Kim Phillipsc3e337f2011-11-21 16:13:27 +0800407 \
408 if (ch_done_mask & 1) \
409 flush_channel(dev, 0, 0, 0); \
410 if (priv->num_channels == 1) \
411 goto out; \
412 if (ch_done_mask & (1 << 2)) \
413 flush_channel(dev, 1, 0, 0); \
414 if (ch_done_mask & (1 << 4)) \
415 flush_channel(dev, 2, 0, 0); \
416 if (ch_done_mask & (1 << 6)) \
417 flush_channel(dev, 3, 0, 0); \
418 \
419out: \
420 /* At this point, all completed channels have been processed */ \
421 /* Unmask done interrupts for channels completed later on. */ \
Horia Geanta511d63c2012-03-30 17:49:53 +0300422 spin_lock_irqsave(&priv->reg_lock, flags); \
Kim Phillipsc3e337f2011-11-21 16:13:27 +0800423 setbits32(priv->reg + TALITOS_IMR, ch_done_mask); \
LEROY Christophedd3c0982015-04-17 16:32:13 +0200424 setbits32(priv->reg + TALITOS_IMR_LO, TALITOS2_IMR_LO_INIT); \
Horia Geanta511d63c2012-03-30 17:49:53 +0300425 spin_unlock_irqrestore(&priv->reg_lock, flags); \
Kim Phillips9c4a7962008-06-23 19:50:15 +0800426}
LEROY Christophedd3c0982015-04-17 16:32:13 +0200427
428DEF_TALITOS2_DONE(4ch, TALITOS2_ISR_4CHDONE)
429DEF_TALITOS2_DONE(ch0_2, TALITOS2_ISR_CH_0_2_DONE)
430DEF_TALITOS2_DONE(ch1_3, TALITOS2_ISR_CH_1_3_DONE)
Kim Phillips9c4a7962008-06-23 19:50:15 +0800431
432/*
433 * locate current (offending) descriptor
434 */
Kim Phillips3e721ae2011-10-21 15:20:28 +0200435static u32 current_desc_hdr(struct device *dev, int ch)
Kim Phillips9c4a7962008-06-23 19:50:15 +0800436{
437 struct talitos_private *priv = dev_get_drvdata(dev);
Horia Geantab62ffd82013-11-13 12:20:37 +0200438 int tail, iter;
Kim Phillips9c4a7962008-06-23 19:50:15 +0800439 dma_addr_t cur_desc;
440
Horia Geantab62ffd82013-11-13 12:20:37 +0200441 cur_desc = ((u64)in_be32(priv->chan[ch].reg + TALITOS_CDPR)) << 32;
442 cur_desc |= in_be32(priv->chan[ch].reg + TALITOS_CDPR_LO);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800443
Horia Geantab62ffd82013-11-13 12:20:37 +0200444 if (!cur_desc) {
445 dev_err(dev, "CDPR is NULL, giving up search for offending descriptor\n");
446 return 0;
447 }
448
449 tail = priv->chan[ch].tail;
450
451 iter = tail;
452 while (priv->chan[ch].fifo[iter].dma_desc != cur_desc) {
453 iter = (iter + 1) & (priv->fifo_len - 1);
454 if (iter == tail) {
Kim Phillips9c4a7962008-06-23 19:50:15 +0800455 dev_err(dev, "couldn't locate current descriptor\n");
Kim Phillips3e721ae2011-10-21 15:20:28 +0200456 return 0;
Kim Phillips9c4a7962008-06-23 19:50:15 +0800457 }
458 }
459
Horia Geantab62ffd82013-11-13 12:20:37 +0200460 return priv->chan[ch].fifo[iter].desc->hdr;
Kim Phillips9c4a7962008-06-23 19:50:15 +0800461}
462
463/*
464 * user diagnostics; report root cause of error based on execution unit status
465 */
Kim Phillips3e721ae2011-10-21 15:20:28 +0200466static void report_eu_error(struct device *dev, int ch, u32 desc_hdr)
Kim Phillips9c4a7962008-06-23 19:50:15 +0800467{
468 struct talitos_private *priv = dev_get_drvdata(dev);
469 int i;
470
Kim Phillips3e721ae2011-10-21 15:20:28 +0200471 if (!desc_hdr)
Kim Phillipsad42d5f2011-11-21 16:13:27 +0800472 desc_hdr = in_be32(priv->chan[ch].reg + TALITOS_DESCBUF);
Kim Phillips3e721ae2011-10-21 15:20:28 +0200473
474 switch (desc_hdr & DESC_HDR_SEL0_MASK) {
Kim Phillips9c4a7962008-06-23 19:50:15 +0800475 case DESC_HDR_SEL0_AFEU:
476 dev_err(dev, "AFEUISR 0x%08x_%08x\n",
LEROY Christophe5fa7fa12015-04-17 16:32:11 +0200477 in_be32(priv->reg_afeu + TALITOS_EUISR),
478 in_be32(priv->reg_afeu + TALITOS_EUISR_LO));
Kim Phillips9c4a7962008-06-23 19:50:15 +0800479 break;
480 case DESC_HDR_SEL0_DEU:
481 dev_err(dev, "DEUISR 0x%08x_%08x\n",
LEROY Christophe5fa7fa12015-04-17 16:32:11 +0200482 in_be32(priv->reg_deu + TALITOS_EUISR),
483 in_be32(priv->reg_deu + TALITOS_EUISR_LO));
Kim Phillips9c4a7962008-06-23 19:50:15 +0800484 break;
485 case DESC_HDR_SEL0_MDEUA:
486 case DESC_HDR_SEL0_MDEUB:
487 dev_err(dev, "MDEUISR 0x%08x_%08x\n",
LEROY Christophe5fa7fa12015-04-17 16:32:11 +0200488 in_be32(priv->reg_mdeu + TALITOS_EUISR),
489 in_be32(priv->reg_mdeu + TALITOS_EUISR_LO));
Kim Phillips9c4a7962008-06-23 19:50:15 +0800490 break;
491 case DESC_HDR_SEL0_RNG:
492 dev_err(dev, "RNGUISR 0x%08x_%08x\n",
LEROY Christophe5fa7fa12015-04-17 16:32:11 +0200493 in_be32(priv->reg_rngu + TALITOS_ISR),
494 in_be32(priv->reg_rngu + TALITOS_ISR_LO));
Kim Phillips9c4a7962008-06-23 19:50:15 +0800495 break;
496 case DESC_HDR_SEL0_PKEU:
497 dev_err(dev, "PKEUISR 0x%08x_%08x\n",
LEROY Christophe5fa7fa12015-04-17 16:32:11 +0200498 in_be32(priv->reg_pkeu + TALITOS_EUISR),
499 in_be32(priv->reg_pkeu + TALITOS_EUISR_LO));
Kim Phillips9c4a7962008-06-23 19:50:15 +0800500 break;
501 case DESC_HDR_SEL0_AESU:
502 dev_err(dev, "AESUISR 0x%08x_%08x\n",
LEROY Christophe5fa7fa12015-04-17 16:32:11 +0200503 in_be32(priv->reg_aesu + TALITOS_EUISR),
504 in_be32(priv->reg_aesu + TALITOS_EUISR_LO));
Kim Phillips9c4a7962008-06-23 19:50:15 +0800505 break;
506 case DESC_HDR_SEL0_CRCU:
507 dev_err(dev, "CRCUISR 0x%08x_%08x\n",
LEROY Christophe5fa7fa12015-04-17 16:32:11 +0200508 in_be32(priv->reg_crcu + TALITOS_EUISR),
509 in_be32(priv->reg_crcu + TALITOS_EUISR_LO));
Kim Phillips9c4a7962008-06-23 19:50:15 +0800510 break;
511 case DESC_HDR_SEL0_KEU:
512 dev_err(dev, "KEUISR 0x%08x_%08x\n",
LEROY Christophe5fa7fa12015-04-17 16:32:11 +0200513 in_be32(priv->reg_pkeu + TALITOS_EUISR),
514 in_be32(priv->reg_pkeu + TALITOS_EUISR_LO));
Kim Phillips9c4a7962008-06-23 19:50:15 +0800515 break;
516 }
517
Kim Phillips3e721ae2011-10-21 15:20:28 +0200518 switch (desc_hdr & DESC_HDR_SEL1_MASK) {
Kim Phillips9c4a7962008-06-23 19:50:15 +0800519 case DESC_HDR_SEL1_MDEUA:
520 case DESC_HDR_SEL1_MDEUB:
521 dev_err(dev, "MDEUISR 0x%08x_%08x\n",
LEROY Christophe5fa7fa12015-04-17 16:32:11 +0200522 in_be32(priv->reg_mdeu + TALITOS_EUISR),
523 in_be32(priv->reg_mdeu + TALITOS_EUISR_LO));
Kim Phillips9c4a7962008-06-23 19:50:15 +0800524 break;
525 case DESC_HDR_SEL1_CRCU:
526 dev_err(dev, "CRCUISR 0x%08x_%08x\n",
LEROY Christophe5fa7fa12015-04-17 16:32:11 +0200527 in_be32(priv->reg_crcu + TALITOS_EUISR),
528 in_be32(priv->reg_crcu + TALITOS_EUISR_LO));
Kim Phillips9c4a7962008-06-23 19:50:15 +0800529 break;
530 }
531
532 for (i = 0; i < 8; i++)
533 dev_err(dev, "DESCBUF 0x%08x_%08x\n",
Kim Phillipsad42d5f2011-11-21 16:13:27 +0800534 in_be32(priv->chan[ch].reg + TALITOS_DESCBUF + 8*i),
535 in_be32(priv->chan[ch].reg + TALITOS_DESCBUF_LO + 8*i));
Kim Phillips9c4a7962008-06-23 19:50:15 +0800536}
537
538/*
539 * recover from error interrupts
540 */
Kim Phillips5e718a02011-12-12 14:59:12 -0600541static void talitos_error(struct device *dev, u32 isr, u32 isr_lo)
Kim Phillips9c4a7962008-06-23 19:50:15 +0800542{
Kim Phillips9c4a7962008-06-23 19:50:15 +0800543 struct talitos_private *priv = dev_get_drvdata(dev);
544 unsigned int timeout = TALITOS_TIMEOUT;
LEROY Christophedd3c0982015-04-17 16:32:13 +0200545 int ch, error, reset_dev = 0;
Horia Geant?42e8b0d2015-05-11 20:04:56 +0300546 u32 v_lo;
LEROY Christophedd3c0982015-04-17 16:32:13 +0200547 bool is_sec1 = has_ftr_sec1(priv);
548 int reset_ch = is_sec1 ? 1 : 0; /* only SEC2 supports continuation */
Kim Phillips9c4a7962008-06-23 19:50:15 +0800549
550 for (ch = 0; ch < priv->num_channels; ch++) {
551 /* skip channels without errors */
LEROY Christophedd3c0982015-04-17 16:32:13 +0200552 if (is_sec1) {
553 /* bits 29, 31, 17, 19 */
554 if (!(isr & (1 << (29 + (ch & 1) * 2 - (ch & 2) * 6))))
555 continue;
556 } else {
557 if (!(isr & (1 << (ch * 2 + 1))))
558 continue;
559 }
Kim Phillips9c4a7962008-06-23 19:50:15 +0800560
561 error = -EINVAL;
562
Kim Phillipsad42d5f2011-11-21 16:13:27 +0800563 v_lo = in_be32(priv->chan[ch].reg + TALITOS_CCPSR_LO);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800564
565 if (v_lo & TALITOS_CCPSR_LO_DOF) {
566 dev_err(dev, "double fetch fifo overflow error\n");
567 error = -EAGAIN;
568 reset_ch = 1;
569 }
570 if (v_lo & TALITOS_CCPSR_LO_SOF) {
571 /* h/w dropped descriptor */
572 dev_err(dev, "single fetch fifo overflow error\n");
573 error = -EAGAIN;
574 }
575 if (v_lo & TALITOS_CCPSR_LO_MDTE)
576 dev_err(dev, "master data transfer error\n");
577 if (v_lo & TALITOS_CCPSR_LO_SGDLZ)
LEROY Christophedd3c0982015-04-17 16:32:13 +0200578 dev_err(dev, is_sec1 ? "pointeur not complete error\n"
579 : "s/g data length zero error\n");
Kim Phillips9c4a7962008-06-23 19:50:15 +0800580 if (v_lo & TALITOS_CCPSR_LO_FPZ)
LEROY Christophedd3c0982015-04-17 16:32:13 +0200581 dev_err(dev, is_sec1 ? "parity error\n"
582 : "fetch pointer zero error\n");
Kim Phillips9c4a7962008-06-23 19:50:15 +0800583 if (v_lo & TALITOS_CCPSR_LO_IDH)
584 dev_err(dev, "illegal descriptor header error\n");
585 if (v_lo & TALITOS_CCPSR_LO_IEU)
LEROY Christophedd3c0982015-04-17 16:32:13 +0200586 dev_err(dev, is_sec1 ? "static assignment error\n"
587 : "invalid exec unit error\n");
Kim Phillips9c4a7962008-06-23 19:50:15 +0800588 if (v_lo & TALITOS_CCPSR_LO_EU)
Kim Phillips3e721ae2011-10-21 15:20:28 +0200589 report_eu_error(dev, ch, current_desc_hdr(dev, ch));
LEROY Christophedd3c0982015-04-17 16:32:13 +0200590 if (!is_sec1) {
591 if (v_lo & TALITOS_CCPSR_LO_GB)
592 dev_err(dev, "gather boundary error\n");
593 if (v_lo & TALITOS_CCPSR_LO_GRL)
594 dev_err(dev, "gather return/length error\n");
595 if (v_lo & TALITOS_CCPSR_LO_SB)
596 dev_err(dev, "scatter boundary error\n");
597 if (v_lo & TALITOS_CCPSR_LO_SRL)
598 dev_err(dev, "scatter return/length error\n");
599 }
Kim Phillips9c4a7962008-06-23 19:50:15 +0800600
601 flush_channel(dev, ch, error, reset_ch);
602
603 if (reset_ch) {
604 reset_channel(dev, ch);
605 } else {
Kim Phillipsad42d5f2011-11-21 16:13:27 +0800606 setbits32(priv->chan[ch].reg + TALITOS_CCCR,
LEROY Christophedd3c0982015-04-17 16:32:13 +0200607 TALITOS2_CCCR_CONT);
Kim Phillipsad42d5f2011-11-21 16:13:27 +0800608 setbits32(priv->chan[ch].reg + TALITOS_CCCR_LO, 0);
609 while ((in_be32(priv->chan[ch].reg + TALITOS_CCCR) &
LEROY Christophedd3c0982015-04-17 16:32:13 +0200610 TALITOS2_CCCR_CONT) && --timeout)
Kim Phillips9c4a7962008-06-23 19:50:15 +0800611 cpu_relax();
612 if (timeout == 0) {
613 dev_err(dev, "failed to restart channel %d\n",
614 ch);
615 reset_dev = 1;
616 }
617 }
618 }
LEROY Christophedd3c0982015-04-17 16:32:13 +0200619 if (reset_dev || (is_sec1 && isr & ~TALITOS1_ISR_4CHERR) ||
620 (!is_sec1 && isr & ~TALITOS2_ISR_4CHERR) || isr_lo) {
621 if (is_sec1 && (isr_lo & TALITOS1_ISR_TEA_ERR))
622 dev_err(dev, "TEA error: ISR 0x%08x_%08x\n",
623 isr, isr_lo);
624 else
625 dev_err(dev, "done overflow, internal time out, or "
626 "rngu error: ISR 0x%08x_%08x\n", isr, isr_lo);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800627
628 /* purge request queues */
629 for (ch = 0; ch < priv->num_channels; ch++)
630 flush_channel(dev, ch, -EIO, 1);
631
632 /* reset and reinitialize the device */
633 init_device(dev);
634 }
635}
636
LEROY Christophedd3c0982015-04-17 16:32:13 +0200637#define DEF_TALITOS1_INTERRUPT(name, ch_done_mask, ch_err_mask, tlet) \
638static irqreturn_t talitos1_interrupt_##name(int irq, void *data) \
639{ \
640 struct device *dev = data; \
641 struct talitos_private *priv = dev_get_drvdata(dev); \
642 u32 isr, isr_lo; \
643 unsigned long flags; \
644 \
645 spin_lock_irqsave(&priv->reg_lock, flags); \
646 isr = in_be32(priv->reg + TALITOS_ISR); \
647 isr_lo = in_be32(priv->reg + TALITOS_ISR_LO); \
648 /* Acknowledge interrupt */ \
649 out_be32(priv->reg + TALITOS_ICR, isr & (ch_done_mask | ch_err_mask)); \
650 out_be32(priv->reg + TALITOS_ICR_LO, isr_lo); \
651 \
652 if (unlikely(isr & ch_err_mask || isr_lo & TALITOS1_IMR_LO_INIT)) { \
653 spin_unlock_irqrestore(&priv->reg_lock, flags); \
654 talitos_error(dev, isr & ch_err_mask, isr_lo); \
655 } \
656 else { \
657 if (likely(isr & ch_done_mask)) { \
658 /* mask further done interrupts. */ \
659 setbits32(priv->reg + TALITOS_IMR, ch_done_mask); \
660 /* done_task will unmask done interrupts at exit */ \
661 tasklet_schedule(&priv->done_task[tlet]); \
662 } \
663 spin_unlock_irqrestore(&priv->reg_lock, flags); \
664 } \
665 \
666 return (isr & (ch_done_mask | ch_err_mask) || isr_lo) ? IRQ_HANDLED : \
667 IRQ_NONE; \
668}
669
670DEF_TALITOS1_INTERRUPT(4ch, TALITOS1_ISR_4CHDONE, TALITOS1_ISR_4CHERR, 0)
671
672#define DEF_TALITOS2_INTERRUPT(name, ch_done_mask, ch_err_mask, tlet) \
673static irqreturn_t talitos2_interrupt_##name(int irq, void *data) \
Kim Phillipsc3e337f2011-11-21 16:13:27 +0800674{ \
675 struct device *dev = data; \
676 struct talitos_private *priv = dev_get_drvdata(dev); \
677 u32 isr, isr_lo; \
Horia Geanta511d63c2012-03-30 17:49:53 +0300678 unsigned long flags; \
Kim Phillipsc3e337f2011-11-21 16:13:27 +0800679 \
Horia Geanta511d63c2012-03-30 17:49:53 +0300680 spin_lock_irqsave(&priv->reg_lock, flags); \
Kim Phillipsc3e337f2011-11-21 16:13:27 +0800681 isr = in_be32(priv->reg + TALITOS_ISR); \
682 isr_lo = in_be32(priv->reg + TALITOS_ISR_LO); \
683 /* Acknowledge interrupt */ \
684 out_be32(priv->reg + TALITOS_ICR, isr & (ch_done_mask | ch_err_mask)); \
685 out_be32(priv->reg + TALITOS_ICR_LO, isr_lo); \
686 \
Horia Geanta511d63c2012-03-30 17:49:53 +0300687 if (unlikely(isr & ch_err_mask || isr_lo)) { \
688 spin_unlock_irqrestore(&priv->reg_lock, flags); \
689 talitos_error(dev, isr & ch_err_mask, isr_lo); \
690 } \
691 else { \
Kim Phillipsc3e337f2011-11-21 16:13:27 +0800692 if (likely(isr & ch_done_mask)) { \
693 /* mask further done interrupts. */ \
694 clrbits32(priv->reg + TALITOS_IMR, ch_done_mask); \
695 /* done_task will unmask done interrupts at exit */ \
696 tasklet_schedule(&priv->done_task[tlet]); \
697 } \
Horia Geanta511d63c2012-03-30 17:49:53 +0300698 spin_unlock_irqrestore(&priv->reg_lock, flags); \
699 } \
Kim Phillipsc3e337f2011-11-21 16:13:27 +0800700 \
701 return (isr & (ch_done_mask | ch_err_mask) || isr_lo) ? IRQ_HANDLED : \
702 IRQ_NONE; \
Kim Phillips9c4a7962008-06-23 19:50:15 +0800703}
LEROY Christophedd3c0982015-04-17 16:32:13 +0200704
705DEF_TALITOS2_INTERRUPT(4ch, TALITOS2_ISR_4CHDONE, TALITOS2_ISR_4CHERR, 0)
706DEF_TALITOS2_INTERRUPT(ch0_2, TALITOS2_ISR_CH_0_2_DONE, TALITOS2_ISR_CH_0_2_ERR,
707 0)
708DEF_TALITOS2_INTERRUPT(ch1_3, TALITOS2_ISR_CH_1_3_DONE, TALITOS2_ISR_CH_1_3_ERR,
709 1)
Kim Phillips9c4a7962008-06-23 19:50:15 +0800710
711/*
712 * hwrng
713 */
714static int talitos_rng_data_present(struct hwrng *rng, int wait)
715{
716 struct device *dev = (struct device *)rng->priv;
717 struct talitos_private *priv = dev_get_drvdata(dev);
718 u32 ofl;
719 int i;
720
721 for (i = 0; i < 20; i++) {
LEROY Christophe5fa7fa12015-04-17 16:32:11 +0200722 ofl = in_be32(priv->reg_rngu + TALITOS_EUSR_LO) &
Kim Phillips9c4a7962008-06-23 19:50:15 +0800723 TALITOS_RNGUSR_LO_OFL;
724 if (ofl || !wait)
725 break;
726 udelay(10);
727 }
728
729 return !!ofl;
730}
731
732static int talitos_rng_data_read(struct hwrng *rng, u32 *data)
733{
734 struct device *dev = (struct device *)rng->priv;
735 struct talitos_private *priv = dev_get_drvdata(dev);
736
737 /* rng fifo requires 64-bit accesses */
LEROY Christophe5fa7fa12015-04-17 16:32:11 +0200738 *data = in_be32(priv->reg_rngu + TALITOS_EU_FIFO);
739 *data = in_be32(priv->reg_rngu + TALITOS_EU_FIFO_LO);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800740
741 return sizeof(u32);
742}
743
744static int talitos_rng_init(struct hwrng *rng)
745{
746 struct device *dev = (struct device *)rng->priv;
747 struct talitos_private *priv = dev_get_drvdata(dev);
748 unsigned int timeout = TALITOS_TIMEOUT;
749
LEROY Christophe5fa7fa12015-04-17 16:32:11 +0200750 setbits32(priv->reg_rngu + TALITOS_EURCR_LO, TALITOS_RNGURCR_LO_SR);
751 while (!(in_be32(priv->reg_rngu + TALITOS_EUSR_LO)
752 & TALITOS_RNGUSR_LO_RD)
Kim Phillips9c4a7962008-06-23 19:50:15 +0800753 && --timeout)
754 cpu_relax();
755 if (timeout == 0) {
756 dev_err(dev, "failed to reset rng hw\n");
757 return -ENODEV;
758 }
759
760 /* start generating */
LEROY Christophe5fa7fa12015-04-17 16:32:11 +0200761 setbits32(priv->reg_rngu + TALITOS_EUDSR_LO, 0);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800762
763 return 0;
764}
765
766static int talitos_register_rng(struct device *dev)
767{
768 struct talitos_private *priv = dev_get_drvdata(dev);
Aaron Sierra35a3bb32015-08-05 16:52:08 -0500769 int err;
Kim Phillips9c4a7962008-06-23 19:50:15 +0800770
771 priv->rng.name = dev_driver_string(dev),
772 priv->rng.init = talitos_rng_init,
773 priv->rng.data_present = talitos_rng_data_present,
774 priv->rng.data_read = talitos_rng_data_read,
775 priv->rng.priv = (unsigned long)dev;
776
Aaron Sierra35a3bb32015-08-05 16:52:08 -0500777 err = hwrng_register(&priv->rng);
778 if (!err)
779 priv->rng_registered = true;
780
781 return err;
Kim Phillips9c4a7962008-06-23 19:50:15 +0800782}
783
784static void talitos_unregister_rng(struct device *dev)
785{
786 struct talitos_private *priv = dev_get_drvdata(dev);
787
Aaron Sierra35a3bb32015-08-05 16:52:08 -0500788 if (!priv->rng_registered)
789 return;
790
Kim Phillips9c4a7962008-06-23 19:50:15 +0800791 hwrng_unregister(&priv->rng);
Aaron Sierra35a3bb32015-08-05 16:52:08 -0500792 priv->rng_registered = false;
Kim Phillips9c4a7962008-06-23 19:50:15 +0800793}
794
795/*
796 * crypto alg
797 */
798#define TALITOS_CRA_PRIORITY 3000
Horia Geanta357fb602012-07-03 19:16:53 +0300799#define TALITOS_MAX_KEY_SIZE 96
Lee Nipper3952f172008-07-10 18:29:18 +0800800#define TALITOS_MAX_IV_LENGTH 16 /* max of AES_BLOCK_SIZE, DES3_EDE_BLOCK_SIZE */
Lee Nipper70bcaca2008-07-03 19:08:46 +0800801
Kim Phillips9c4a7962008-06-23 19:50:15 +0800802struct talitos_ctx {
803 struct device *dev;
Kim Phillips5228f0f2011-07-15 11:21:38 +0800804 int ch;
Kim Phillips9c4a7962008-06-23 19:50:15 +0800805 __be32 desc_hdr_template;
806 u8 key[TALITOS_MAX_KEY_SIZE];
Lee Nipper70bcaca2008-07-03 19:08:46 +0800807 u8 iv[TALITOS_MAX_IV_LENGTH];
Kim Phillips9c4a7962008-06-23 19:50:15 +0800808 unsigned int keylen;
809 unsigned int enckeylen;
810 unsigned int authkeylen;
Kim Phillips9c4a7962008-06-23 19:50:15 +0800811};
812
Lee Nipper497f2e62010-05-19 19:20:36 +1000813#define HASH_MAX_BLOCK_SIZE SHA512_BLOCK_SIZE
814#define TALITOS_MDEU_MAX_CONTEXT_SIZE TALITOS_MDEU_CONTEXT_SIZE_SHA384_SHA512
815
816struct talitos_ahash_req_ctx {
Kim Phillips60f208d2010-05-19 19:21:53 +1000817 u32 hw_context[TALITOS_MDEU_MAX_CONTEXT_SIZE / sizeof(u32)];
Lee Nipper497f2e62010-05-19 19:20:36 +1000818 unsigned int hw_context_size;
819 u8 buf[HASH_MAX_BLOCK_SIZE];
820 u8 bufnext[HASH_MAX_BLOCK_SIZE];
Kim Phillips60f208d2010-05-19 19:21:53 +1000821 unsigned int swinit;
Lee Nipper497f2e62010-05-19 19:20:36 +1000822 unsigned int first;
823 unsigned int last;
824 unsigned int to_hash_later;
Horia Geant?42e8b0d2015-05-11 20:04:56 +0300825 unsigned int nbuf;
Lee Nipper497f2e62010-05-19 19:20:36 +1000826 struct scatterlist bufsl[2];
827 struct scatterlist *psrc;
828};
829
Horia Geant?3639ca82016-04-21 19:24:55 +0300830struct talitos_export_state {
831 u32 hw_context[TALITOS_MDEU_MAX_CONTEXT_SIZE / sizeof(u32)];
832 u8 buf[HASH_MAX_BLOCK_SIZE];
833 unsigned int swinit;
834 unsigned int first;
835 unsigned int last;
836 unsigned int to_hash_later;
837 unsigned int nbuf;
838};
839
Lee Nipper56af8cd2009-03-29 15:50:50 +0800840static int aead_setkey(struct crypto_aead *authenc,
841 const u8 *key, unsigned int keylen)
Kim Phillips9c4a7962008-06-23 19:50:15 +0800842{
843 struct talitos_ctx *ctx = crypto_aead_ctx(authenc);
Mathias Krausec306a982013-10-15 13:49:34 +0200844 struct crypto_authenc_keys keys;
Kim Phillips9c4a7962008-06-23 19:50:15 +0800845
Mathias Krausec306a982013-10-15 13:49:34 +0200846 if (crypto_authenc_extractkeys(&keys, key, keylen) != 0)
Kim Phillips9c4a7962008-06-23 19:50:15 +0800847 goto badkey;
848
Mathias Krausec306a982013-10-15 13:49:34 +0200849 if (keys.authkeylen + keys.enckeylen > TALITOS_MAX_KEY_SIZE)
Kim Phillips9c4a7962008-06-23 19:50:15 +0800850 goto badkey;
851
Mathias Krausec306a982013-10-15 13:49:34 +0200852 memcpy(ctx->key, keys.authkey, keys.authkeylen);
853 memcpy(&ctx->key[keys.authkeylen], keys.enckey, keys.enckeylen);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800854
Mathias Krausec306a982013-10-15 13:49:34 +0200855 ctx->keylen = keys.authkeylen + keys.enckeylen;
856 ctx->enckeylen = keys.enckeylen;
857 ctx->authkeylen = keys.authkeylen;
Kim Phillips9c4a7962008-06-23 19:50:15 +0800858
859 return 0;
860
861badkey:
862 crypto_aead_set_flags(authenc, CRYPTO_TFM_RES_BAD_KEY_LEN);
863 return -EINVAL;
864}
865
866/*
Lee Nipper56af8cd2009-03-29 15:50:50 +0800867 * talitos_edesc - s/w-extended descriptor
Kim Phillips9c4a7962008-06-23 19:50:15 +0800868 * @src_nents: number of segments in input scatterlist
869 * @dst_nents: number of segments in output scatterlist
Herbert Xuaeb4c132015-07-30 17:53:22 +0800870 * @icv_ool: whether ICV is out-of-line
Horia Geanta79fd31d2012-08-02 17:16:40 +0300871 * @iv_dma: dma address of iv for checking continuity and link table
Kim Phillips9c4a7962008-06-23 19:50:15 +0800872 * @dma_len: length of dma mapped link_tbl space
LEROY Christophe6f65f6a2015-04-17 16:32:15 +0200873 * @dma_link_tbl: bus physical address of link_tbl/buf
Kim Phillips9c4a7962008-06-23 19:50:15 +0800874 * @desc: h/w descriptor
LEROY Christophe6f65f6a2015-04-17 16:32:15 +0200875 * @link_tbl: input and output h/w link tables (if {src,dst}_nents > 1) (SEC2)
876 * @buf: input and output buffeur (if {src,dst}_nents > 1) (SEC1)
Kim Phillips9c4a7962008-06-23 19:50:15 +0800877 *
878 * if decrypting (with authcheck), or either one of src_nents or dst_nents
879 * is greater than 1, an integrity check value is concatenated to the end
880 * of link_tbl data
881 */
Lee Nipper56af8cd2009-03-29 15:50:50 +0800882struct talitos_edesc {
Kim Phillips9c4a7962008-06-23 19:50:15 +0800883 int src_nents;
884 int dst_nents;
Herbert Xuaeb4c132015-07-30 17:53:22 +0800885 bool icv_ool;
Horia Geanta79fd31d2012-08-02 17:16:40 +0300886 dma_addr_t iv_dma;
Kim Phillips9c4a7962008-06-23 19:50:15 +0800887 int dma_len;
888 dma_addr_t dma_link_tbl;
889 struct talitos_desc desc;
LEROY Christophe6f65f6a2015-04-17 16:32:15 +0200890 union {
891 struct talitos_ptr link_tbl[0];
892 u8 buf[0];
893 };
Kim Phillips9c4a7962008-06-23 19:50:15 +0800894};
895
Lee Nipper4de9d0b2009-03-29 15:52:32 +0800896static void talitos_sg_unmap(struct device *dev,
897 struct talitos_edesc *edesc,
898 struct scatterlist *src,
899 struct scatterlist *dst)
900{
901 unsigned int src_nents = edesc->src_nents ? : 1;
902 unsigned int dst_nents = edesc->dst_nents ? : 1;
903
904 if (src != dst) {
LABBE Corentinb8a011d2015-09-23 13:55:25 +0200905 dma_unmap_sg(dev, src, src_nents, DMA_TO_DEVICE);
Lee Nipper4de9d0b2009-03-29 15:52:32 +0800906
Lee Nipper497f2e62010-05-19 19:20:36 +1000907 if (dst) {
LABBE Corentinb8a011d2015-09-23 13:55:25 +0200908 dma_unmap_sg(dev, dst, dst_nents, DMA_FROM_DEVICE);
Lee Nipper497f2e62010-05-19 19:20:36 +1000909 }
Lee Nipper4de9d0b2009-03-29 15:52:32 +0800910 } else
LABBE Corentinb8a011d2015-09-23 13:55:25 +0200911 dma_unmap_sg(dev, src, src_nents, DMA_BIDIRECTIONAL);
Lee Nipper4de9d0b2009-03-29 15:52:32 +0800912}
913
Kim Phillips9c4a7962008-06-23 19:50:15 +0800914static void ipsec_esp_unmap(struct device *dev,
Lee Nipper56af8cd2009-03-29 15:50:50 +0800915 struct talitos_edesc *edesc,
Kim Phillips9c4a7962008-06-23 19:50:15 +0800916 struct aead_request *areq)
917{
918 unmap_single_talitos_ptr(dev, &edesc->desc.ptr[6], DMA_FROM_DEVICE);
919 unmap_single_talitos_ptr(dev, &edesc->desc.ptr[3], DMA_TO_DEVICE);
920 unmap_single_talitos_ptr(dev, &edesc->desc.ptr[2], DMA_TO_DEVICE);
921 unmap_single_talitos_ptr(dev, &edesc->desc.ptr[0], DMA_TO_DEVICE);
922
Lee Nipper4de9d0b2009-03-29 15:52:32 +0800923 talitos_sg_unmap(dev, edesc, areq->src, areq->dst);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800924
925 if (edesc->dma_len)
926 dma_unmap_single(dev, edesc->dma_link_tbl, edesc->dma_len,
927 DMA_BIDIRECTIONAL);
928}
929
930/*
931 * ipsec_esp descriptor callbacks
932 */
933static void ipsec_esp_encrypt_done(struct device *dev,
934 struct talitos_desc *desc, void *context,
935 int err)
936{
937 struct aead_request *areq = context;
Kim Phillips9c4a7962008-06-23 19:50:15 +0800938 struct crypto_aead *authenc = crypto_aead_reqtfm(areq);
Herbert Xuaeb4c132015-07-30 17:53:22 +0800939 unsigned int authsize = crypto_aead_authsize(authenc);
Kim Phillips19bbbc62009-03-29 15:53:59 +0800940 struct talitos_edesc *edesc;
Kim Phillips9c4a7962008-06-23 19:50:15 +0800941 struct scatterlist *sg;
942 void *icvdata;
943
Kim Phillips19bbbc62009-03-29 15:53:59 +0800944 edesc = container_of(desc, struct talitos_edesc, desc);
945
Kim Phillips9c4a7962008-06-23 19:50:15 +0800946 ipsec_esp_unmap(dev, edesc, areq);
947
948 /* copy the generated ICV to dst */
Herbert Xuaeb4c132015-07-30 17:53:22 +0800949 if (edesc->icv_ool) {
Kim Phillips9c4a7962008-06-23 19:50:15 +0800950 icvdata = &edesc->link_tbl[edesc->src_nents +
Herbert Xuaeb4c132015-07-30 17:53:22 +0800951 edesc->dst_nents + 2];
Kim Phillips9c4a7962008-06-23 19:50:15 +0800952 sg = sg_last(areq->dst, edesc->dst_nents);
Herbert Xuaeb4c132015-07-30 17:53:22 +0800953 memcpy((char *)sg_virt(sg) + sg->length - authsize,
954 icvdata, authsize);
Kim Phillips9c4a7962008-06-23 19:50:15 +0800955 }
956
957 kfree(edesc);
958
959 aead_request_complete(areq, err);
960}
961
Kim Phillipsfe5720e2008-10-12 20:33:14 +0800962static void ipsec_esp_decrypt_swauth_done(struct device *dev,
Kim Phillipse938e462009-03-29 15:53:23 +0800963 struct talitos_desc *desc,
964 void *context, int err)
Kim Phillips9c4a7962008-06-23 19:50:15 +0800965{
966 struct aead_request *req = context;
Kim Phillips9c4a7962008-06-23 19:50:15 +0800967 struct crypto_aead *authenc = crypto_aead_reqtfm(req);
Herbert Xuaeb4c132015-07-30 17:53:22 +0800968 unsigned int authsize = crypto_aead_authsize(authenc);
Kim Phillips19bbbc62009-03-29 15:53:59 +0800969 struct talitos_edesc *edesc;
Kim Phillips9c4a7962008-06-23 19:50:15 +0800970 struct scatterlist *sg;
Herbert Xuaeb4c132015-07-30 17:53:22 +0800971 char *oicv, *icv;
Kim Phillips9c4a7962008-06-23 19:50:15 +0800972
Kim Phillips19bbbc62009-03-29 15:53:59 +0800973 edesc = container_of(desc, struct talitos_edesc, desc);
974
Kim Phillips9c4a7962008-06-23 19:50:15 +0800975 ipsec_esp_unmap(dev, edesc, req);
976
977 if (!err) {
978 /* auth check */
Kim Phillips9c4a7962008-06-23 19:50:15 +0800979 sg = sg_last(req->dst, edesc->dst_nents ? : 1);
Herbert Xuaeb4c132015-07-30 17:53:22 +0800980 icv = (char *)sg_virt(sg) + sg->length - authsize;
981
982 if (edesc->dma_len) {
983 oicv = (char *)&edesc->link_tbl[edesc->src_nents +
984 edesc->dst_nents + 2];
985 if (edesc->icv_ool)
986 icv = oicv + authsize;
987 } else
988 oicv = (char *)&edesc->link_tbl[0];
989
David Gstir79960942015-11-15 17:14:42 +0100990 err = crypto_memneq(oicv, icv, authsize) ? -EBADMSG : 0;
Kim Phillips9c4a7962008-06-23 19:50:15 +0800991 }
992
993 kfree(edesc);
994
995 aead_request_complete(req, err);
996}
997
Kim Phillipsfe5720e2008-10-12 20:33:14 +0800998static void ipsec_esp_decrypt_hwauth_done(struct device *dev,
Kim Phillipse938e462009-03-29 15:53:23 +0800999 struct talitos_desc *desc,
1000 void *context, int err)
Kim Phillipsfe5720e2008-10-12 20:33:14 +08001001{
1002 struct aead_request *req = context;
Kim Phillips19bbbc62009-03-29 15:53:59 +08001003 struct talitos_edesc *edesc;
1004
1005 edesc = container_of(desc, struct talitos_edesc, desc);
Kim Phillipsfe5720e2008-10-12 20:33:14 +08001006
1007 ipsec_esp_unmap(dev, edesc, req);
1008
1009 /* check ICV auth status */
Kim Phillipse938e462009-03-29 15:53:23 +08001010 if (!err && ((desc->hdr_lo & DESC_HDR_LO_ICCR1_MASK) !=
1011 DESC_HDR_LO_ICCR1_PASS))
1012 err = -EBADMSG;
Kim Phillipsfe5720e2008-10-12 20:33:14 +08001013
1014 kfree(edesc);
1015
1016 aead_request_complete(req, err);
1017}
1018
Kim Phillips9c4a7962008-06-23 19:50:15 +08001019/*
1020 * convert scatterlist to SEC h/w link table format
1021 * stop at cryptlen bytes
1022 */
Herbert Xuaeb4c132015-07-30 17:53:22 +08001023static int sg_to_link_tbl_offset(struct scatterlist *sg, int sg_count,
1024 unsigned int offset, int cryptlen,
1025 struct talitos_ptr *link_tbl_ptr)
Kim Phillips9c4a7962008-06-23 19:50:15 +08001026{
Lee Nipper70bcaca2008-07-03 19:08:46 +08001027 int n_sg = sg_count;
Herbert Xuaeb4c132015-07-30 17:53:22 +08001028 int count = 0;
Lee Nipper70bcaca2008-07-03 19:08:46 +08001029
Herbert Xuaeb4c132015-07-30 17:53:22 +08001030 while (cryptlen && sg && n_sg--) {
1031 unsigned int len = sg_dma_len(sg);
1032
1033 if (offset >= len) {
1034 offset -= len;
1035 goto next;
1036 }
1037
1038 len -= offset;
1039
1040 if (len > cryptlen)
1041 len = cryptlen;
1042
1043 to_talitos_ptr(link_tbl_ptr + count,
1044 sg_dma_address(sg) + offset, 0);
1045 link_tbl_ptr[count].len = cpu_to_be16(len);
1046 link_tbl_ptr[count].j_extent = 0;
1047 count++;
1048 cryptlen -= len;
1049 offset = 0;
1050
1051next:
Cristian Stoica5be4d4c2015-01-20 10:06:16 +02001052 sg = sg_next(sg);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001053 }
1054
Kim Phillips9c4a7962008-06-23 19:50:15 +08001055 /* tag end of link table */
Herbert Xuaeb4c132015-07-30 17:53:22 +08001056 if (count > 0)
1057 link_tbl_ptr[count - 1].j_extent = DESC_PTR_LNKTBL_RETURN;
Lee Nipper70bcaca2008-07-03 19:08:46 +08001058
Herbert Xuaeb4c132015-07-30 17:53:22 +08001059 return count;
1060}
1061
1062static inline int sg_to_link_tbl(struct scatterlist *sg, int sg_count,
1063 int cryptlen,
1064 struct talitos_ptr *link_tbl_ptr)
1065{
1066 return sg_to_link_tbl_offset(sg, sg_count, 0, cryptlen,
1067 link_tbl_ptr);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001068}
1069
1070/*
1071 * fill in and submit ipsec_esp descriptor
1072 */
Lee Nipper56af8cd2009-03-29 15:50:50 +08001073static int ipsec_esp(struct talitos_edesc *edesc, struct aead_request *areq,
Herbert Xuaeb4c132015-07-30 17:53:22 +08001074 void (*callback)(struct device *dev,
1075 struct talitos_desc *desc,
1076 void *context, int error))
Kim Phillips9c4a7962008-06-23 19:50:15 +08001077{
1078 struct crypto_aead *aead = crypto_aead_reqtfm(areq);
Herbert Xuaeb4c132015-07-30 17:53:22 +08001079 unsigned int authsize = crypto_aead_authsize(aead);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001080 struct talitos_ctx *ctx = crypto_aead_ctx(aead);
1081 struct device *dev = ctx->dev;
1082 struct talitos_desc *desc = &edesc->desc;
1083 unsigned int cryptlen = areq->cryptlen;
Kim Phillipse41256f2009-08-13 11:49:06 +10001084 unsigned int ivsize = crypto_aead_ivsize(aead);
Herbert Xuaeb4c132015-07-30 17:53:22 +08001085 int tbl_off = 0;
Kim Phillipsfa86a262008-07-17 20:20:06 +08001086 int sg_count, ret;
Kim Phillipsfe5720e2008-10-12 20:33:14 +08001087 int sg_link_tbl_len;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001088
1089 /* hmac key */
1090 map_single_talitos_ptr(dev, &desc->ptr[0], ctx->authkeylen, &ctx->key,
LEROY Christophea2b35aa2015-04-17 16:31:57 +02001091 DMA_TO_DEVICE);
Horia Geanta79fd31d2012-08-02 17:16:40 +03001092
LABBE Corentinb8a011d2015-09-23 13:55:25 +02001093 sg_count = dma_map_sg(dev, areq->src, edesc->src_nents ?: 1,
1094 (areq->src == areq->dst) ? DMA_BIDIRECTIONAL
1095 : DMA_TO_DEVICE);
Herbert Xuaeb4c132015-07-30 17:53:22 +08001096
Kim Phillips9c4a7962008-06-23 19:50:15 +08001097 /* hmac data */
Herbert Xuaeb4c132015-07-30 17:53:22 +08001098 desc->ptr[1].len = cpu_to_be16(areq->assoclen);
1099 if (sg_count > 1 &&
1100 (ret = sg_to_link_tbl_offset(areq->src, sg_count, 0,
1101 areq->assoclen,
1102 &edesc->link_tbl[tbl_off])) > 1) {
1103 tbl_off += ret;
Horia Geanta79fd31d2012-08-02 17:16:40 +03001104
1105 to_talitos_ptr(&desc->ptr[1], edesc->dma_link_tbl + tbl_off *
LEROY Christophe922f9dc2015-04-17 16:32:07 +02001106 sizeof(struct talitos_ptr), 0);
Horia Geanta79fd31d2012-08-02 17:16:40 +03001107 desc->ptr[1].j_extent = DESC_PTR_LNKTBL_JUMP;
1108
Horia Geanta79fd31d2012-08-02 17:16:40 +03001109 dma_sync_single_for_device(dev, edesc->dma_link_tbl,
1110 edesc->dma_len, DMA_BIDIRECTIONAL);
1111 } else {
Herbert Xuaeb4c132015-07-30 17:53:22 +08001112 to_talitos_ptr(&desc->ptr[1], sg_dma_address(areq->src), 0);
Horia Geanta79fd31d2012-08-02 17:16:40 +03001113 desc->ptr[1].j_extent = 0;
1114 }
1115
Kim Phillips9c4a7962008-06-23 19:50:15 +08001116 /* cipher iv */
LEROY Christophe922f9dc2015-04-17 16:32:07 +02001117 to_talitos_ptr(&desc->ptr[2], edesc->iv_dma, 0);
Horia Geanta79fd31d2012-08-02 17:16:40 +03001118 desc->ptr[2].len = cpu_to_be16(ivsize);
1119 desc->ptr[2].j_extent = 0;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001120
1121 /* cipher key */
1122 map_single_talitos_ptr(dev, &desc->ptr[3], ctx->enckeylen,
LEROY Christophea2b35aa2015-04-17 16:31:57 +02001123 (char *)&ctx->key + ctx->authkeylen,
Kim Phillips9c4a7962008-06-23 19:50:15 +08001124 DMA_TO_DEVICE);
1125
1126 /*
1127 * cipher in
1128 * map and adjust cipher len to aead request cryptlen.
1129 * extent is bytes of HMAC postpended to ciphertext,
1130 * typically 12 for ipsec
1131 */
1132 desc->ptr[4].len = cpu_to_be16(cryptlen);
1133 desc->ptr[4].j_extent = authsize;
1134
Herbert Xuaeb4c132015-07-30 17:53:22 +08001135 sg_link_tbl_len = cryptlen;
1136 if (edesc->desc.hdr & DESC_HDR_MODE1_MDEU_CICV)
1137 sg_link_tbl_len += authsize;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001138
Herbert Xuaeb4c132015-07-30 17:53:22 +08001139 if (sg_count > 1 &&
1140 (ret = sg_to_link_tbl_offset(areq->src, sg_count, areq->assoclen,
1141 sg_link_tbl_len,
1142 &edesc->link_tbl[tbl_off])) > 1) {
1143 tbl_off += ret;
1144 desc->ptr[4].j_extent |= DESC_PTR_LNKTBL_JUMP;
1145 to_talitos_ptr(&desc->ptr[4], edesc->dma_link_tbl +
1146 tbl_off *
1147 sizeof(struct talitos_ptr), 0);
1148 dma_sync_single_for_device(dev, edesc->dma_link_tbl,
1149 edesc->dma_len,
1150 DMA_BIDIRECTIONAL);
1151 } else
LEROY Christophe922f9dc2015-04-17 16:32:07 +02001152 to_talitos_ptr(&desc->ptr[4], sg_dma_address(areq->src), 0);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001153
1154 /* cipher out */
1155 desc->ptr[5].len = cpu_to_be16(cryptlen);
1156 desc->ptr[5].j_extent = authsize;
1157
Kim Phillipse938e462009-03-29 15:53:23 +08001158 if (areq->src != areq->dst)
LABBE Corentinb8a011d2015-09-23 13:55:25 +02001159 sg_count = dma_map_sg(dev, areq->dst, edesc->dst_nents ? : 1,
1160 DMA_FROM_DEVICE);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001161
Herbert Xuaeb4c132015-07-30 17:53:22 +08001162 edesc->icv_ool = false;
1163
1164 if (sg_count > 1 &&
1165 (sg_count = sg_to_link_tbl_offset(areq->dst, sg_count,
1166 areq->assoclen, cryptlen,
1167 &edesc->link_tbl[tbl_off])) >
1168 1) {
Horia Geanta79fd31d2012-08-02 17:16:40 +03001169 struct talitos_ptr *tbl_ptr = &edesc->link_tbl[tbl_off];
Kim Phillips9c4a7962008-06-23 19:50:15 +08001170
Kim Phillips81eb0242009-08-13 11:51:51 +10001171 to_talitos_ptr(&desc->ptr[5], edesc->dma_link_tbl +
LEROY Christophe922f9dc2015-04-17 16:32:07 +02001172 tbl_off * sizeof(struct talitos_ptr), 0);
Kim Phillipsfe5720e2008-10-12 20:33:14 +08001173
Lee Nipperf3c85bc2008-07-30 16:26:57 +08001174 /* Add an entry to the link table for ICV data */
Horia Geanta79fd31d2012-08-02 17:16:40 +03001175 tbl_ptr += sg_count - 1;
1176 tbl_ptr->j_extent = 0;
1177 tbl_ptr++;
1178 tbl_ptr->j_extent = DESC_PTR_LNKTBL_RETURN;
1179 tbl_ptr->len = cpu_to_be16(authsize);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001180
1181 /* icv data follows link tables */
Horia Geanta79fd31d2012-08-02 17:16:40 +03001182 to_talitos_ptr(tbl_ptr, edesc->dma_link_tbl +
Herbert Xuaeb4c132015-07-30 17:53:22 +08001183 (edesc->src_nents + edesc->dst_nents +
1184 2) * sizeof(struct talitos_ptr) +
1185 authsize, 0);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001186 desc->ptr[5].j_extent |= DESC_PTR_LNKTBL_JUMP;
1187 dma_sync_single_for_device(ctx->dev, edesc->dma_link_tbl,
1188 edesc->dma_len, DMA_BIDIRECTIONAL);
Herbert Xuaeb4c132015-07-30 17:53:22 +08001189
1190 edesc->icv_ool = true;
1191 } else
1192 to_talitos_ptr(&desc->ptr[5], sg_dma_address(areq->dst), 0);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001193
1194 /* iv out */
LEROY Christophea2b35aa2015-04-17 16:31:57 +02001195 map_single_talitos_ptr(dev, &desc->ptr[6], ivsize, ctx->iv,
Kim Phillips9c4a7962008-06-23 19:50:15 +08001196 DMA_FROM_DEVICE);
1197
Kim Phillips5228f0f2011-07-15 11:21:38 +08001198 ret = talitos_submit(dev, ctx->ch, desc, callback, areq);
Kim Phillipsfa86a262008-07-17 20:20:06 +08001199 if (ret != -EINPROGRESS) {
1200 ipsec_esp_unmap(dev, edesc, areq);
1201 kfree(edesc);
1202 }
1203 return ret;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001204}
1205
Kim Phillips9c4a7962008-06-23 19:50:15 +08001206/*
Lee Nipper56af8cd2009-03-29 15:50:50 +08001207 * allocate and map the extended descriptor
Kim Phillips9c4a7962008-06-23 19:50:15 +08001208 */
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001209static struct talitos_edesc *talitos_edesc_alloc(struct device *dev,
1210 struct scatterlist *src,
1211 struct scatterlist *dst,
Horia Geanta79fd31d2012-08-02 17:16:40 +03001212 u8 *iv,
1213 unsigned int assoclen,
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001214 unsigned int cryptlen,
1215 unsigned int authsize,
Horia Geanta79fd31d2012-08-02 17:16:40 +03001216 unsigned int ivsize,
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001217 int icv_stashing,
Horia Geanta62293a32013-11-28 15:11:17 +02001218 u32 cryptoflags,
1219 bool encrypt)
Kim Phillips9c4a7962008-06-23 19:50:15 +08001220{
Lee Nipper56af8cd2009-03-29 15:50:50 +08001221 struct talitos_edesc *edesc;
Herbert Xuaeb4c132015-07-30 17:53:22 +08001222 int src_nents, dst_nents, alloc_len, dma_len;
Horia Geanta79fd31d2012-08-02 17:16:40 +03001223 dma_addr_t iv_dma = 0;
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001224 gfp_t flags = cryptoflags & CRYPTO_TFM_REQ_MAY_SLEEP ? GFP_KERNEL :
Kim Phillips586725f2008-07-17 20:19:18 +08001225 GFP_ATOMIC;
LEROY Christophe6f65f6a2015-04-17 16:32:15 +02001226 struct talitos_private *priv = dev_get_drvdata(dev);
1227 bool is_sec1 = has_ftr_sec1(priv);
1228 int max_len = is_sec1 ? TALITOS1_MAX_DATA_LEN : TALITOS2_MAX_DATA_LEN;
LABBE Corentin8e409fe2015-11-04 21:13:34 +01001229 void *err;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001230
LEROY Christophe6f65f6a2015-04-17 16:32:15 +02001231 if (cryptlen + authsize > max_len) {
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001232 dev_err(dev, "length exceeds h/w max limit\n");
Kim Phillips9c4a7962008-06-23 19:50:15 +08001233 return ERR_PTR(-EINVAL);
1234 }
1235
Horia Geanta935e99a2013-11-19 14:57:49 +02001236 if (ivsize)
Horia Geanta79fd31d2012-08-02 17:16:40 +03001237 iv_dma = dma_map_single(dev, iv, ivsize, DMA_TO_DEVICE);
1238
Horia Geanta62293a32013-11-28 15:11:17 +02001239 if (!dst || dst == src) {
LABBE Corentinb8a011d2015-09-23 13:55:25 +02001240 src_nents = sg_nents_for_len(src,
1241 assoclen + cryptlen + authsize);
LABBE Corentin8e409fe2015-11-04 21:13:34 +01001242 if (src_nents < 0) {
1243 dev_err(dev, "Invalid number of src SG.\n");
1244 err = ERR_PTR(-EINVAL);
1245 goto error_sg;
1246 }
Horia Geanta62293a32013-11-28 15:11:17 +02001247 src_nents = (src_nents == 1) ? 0 : src_nents;
1248 dst_nents = dst ? src_nents : 0;
1249 } else { /* dst && dst != src*/
LABBE Corentinb8a011d2015-09-23 13:55:25 +02001250 src_nents = sg_nents_for_len(src, assoclen + cryptlen +
1251 (encrypt ? 0 : authsize));
LABBE Corentin8e409fe2015-11-04 21:13:34 +01001252 if (src_nents < 0) {
1253 dev_err(dev, "Invalid number of src SG.\n");
1254 err = ERR_PTR(-EINVAL);
1255 goto error_sg;
1256 }
Horia Geanta62293a32013-11-28 15:11:17 +02001257 src_nents = (src_nents == 1) ? 0 : src_nents;
LABBE Corentinb8a011d2015-09-23 13:55:25 +02001258 dst_nents = sg_nents_for_len(dst, assoclen + cryptlen +
1259 (encrypt ? authsize : 0));
LABBE Corentin8e409fe2015-11-04 21:13:34 +01001260 if (dst_nents < 0) {
1261 dev_err(dev, "Invalid number of dst SG.\n");
1262 err = ERR_PTR(-EINVAL);
1263 goto error_sg;
1264 }
Horia Geanta62293a32013-11-28 15:11:17 +02001265 dst_nents = (dst_nents == 1) ? 0 : dst_nents;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001266 }
1267
1268 /*
1269 * allocate space for base edesc plus the link tables,
Herbert Xuaeb4c132015-07-30 17:53:22 +08001270 * allowing for two separate entries for AD and generated ICV (+ 2),
1271 * and space for two sets of ICVs (stashed and generated)
Kim Phillips9c4a7962008-06-23 19:50:15 +08001272 */
Lee Nipper56af8cd2009-03-29 15:50:50 +08001273 alloc_len = sizeof(struct talitos_edesc);
Herbert Xuaeb4c132015-07-30 17:53:22 +08001274 if (src_nents || dst_nents) {
LEROY Christophe6f65f6a2015-04-17 16:32:15 +02001275 if (is_sec1)
Dan Carpenter608f37d2015-05-11 13:10:09 +03001276 dma_len = (src_nents ? cryptlen : 0) +
1277 (dst_nents ? cryptlen : 0);
LEROY Christophe6f65f6a2015-04-17 16:32:15 +02001278 else
Herbert Xuaeb4c132015-07-30 17:53:22 +08001279 dma_len = (src_nents + dst_nents + 2) *
1280 sizeof(struct talitos_ptr) + authsize * 2;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001281 alloc_len += dma_len;
1282 } else {
1283 dma_len = 0;
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001284 alloc_len += icv_stashing ? authsize : 0;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001285 }
1286
Kim Phillips586725f2008-07-17 20:19:18 +08001287 edesc = kmalloc(alloc_len, GFP_DMA | flags);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001288 if (!edesc) {
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001289 dev_err(dev, "could not allocate edescriptor\n");
LABBE Corentin8e409fe2015-11-04 21:13:34 +01001290 err = ERR_PTR(-ENOMEM);
1291 goto error_sg;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001292 }
1293
1294 edesc->src_nents = src_nents;
1295 edesc->dst_nents = dst_nents;
Horia Geanta79fd31d2012-08-02 17:16:40 +03001296 edesc->iv_dma = iv_dma;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001297 edesc->dma_len = dma_len;
Lee Nipper497f2e62010-05-19 19:20:36 +10001298 if (dma_len)
1299 edesc->dma_link_tbl = dma_map_single(dev, &edesc->link_tbl[0],
1300 edesc->dma_len,
1301 DMA_BIDIRECTIONAL);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001302
1303 return edesc;
LABBE Corentin8e409fe2015-11-04 21:13:34 +01001304error_sg:
1305 if (iv_dma)
1306 dma_unmap_single(dev, iv_dma, ivsize, DMA_TO_DEVICE);
1307 return err;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001308}
1309
Horia Geanta79fd31d2012-08-02 17:16:40 +03001310static struct talitos_edesc *aead_edesc_alloc(struct aead_request *areq, u8 *iv,
Horia Geanta62293a32013-11-28 15:11:17 +02001311 int icv_stashing, bool encrypt)
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001312{
1313 struct crypto_aead *authenc = crypto_aead_reqtfm(areq);
Herbert Xuaeb4c132015-07-30 17:53:22 +08001314 unsigned int authsize = crypto_aead_authsize(authenc);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001315 struct talitos_ctx *ctx = crypto_aead_ctx(authenc);
Horia Geanta79fd31d2012-08-02 17:16:40 +03001316 unsigned int ivsize = crypto_aead_ivsize(authenc);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001317
Herbert Xuaeb4c132015-07-30 17:53:22 +08001318 return talitos_edesc_alloc(ctx->dev, areq->src, areq->dst,
Horia Geanta79fd31d2012-08-02 17:16:40 +03001319 iv, areq->assoclen, areq->cryptlen,
Herbert Xuaeb4c132015-07-30 17:53:22 +08001320 authsize, ivsize, icv_stashing,
Horia Geanta62293a32013-11-28 15:11:17 +02001321 areq->base.flags, encrypt);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001322}
1323
Lee Nipper56af8cd2009-03-29 15:50:50 +08001324static int aead_encrypt(struct aead_request *req)
Kim Phillips9c4a7962008-06-23 19:50:15 +08001325{
1326 struct crypto_aead *authenc = crypto_aead_reqtfm(req);
1327 struct talitos_ctx *ctx = crypto_aead_ctx(authenc);
Lee Nipper56af8cd2009-03-29 15:50:50 +08001328 struct talitos_edesc *edesc;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001329
1330 /* allocate extended descriptor */
Horia Geanta62293a32013-11-28 15:11:17 +02001331 edesc = aead_edesc_alloc(req, req->iv, 0, true);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001332 if (IS_ERR(edesc))
1333 return PTR_ERR(edesc);
1334
1335 /* set encrypt */
Lee Nipper70bcaca2008-07-03 19:08:46 +08001336 edesc->desc.hdr = ctx->desc_hdr_template | DESC_HDR_MODE0_ENCRYPT;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001337
Herbert Xuaeb4c132015-07-30 17:53:22 +08001338 return ipsec_esp(edesc, req, ipsec_esp_encrypt_done);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001339}
1340
Lee Nipper56af8cd2009-03-29 15:50:50 +08001341static int aead_decrypt(struct aead_request *req)
Kim Phillips9c4a7962008-06-23 19:50:15 +08001342{
1343 struct crypto_aead *authenc = crypto_aead_reqtfm(req);
Herbert Xuaeb4c132015-07-30 17:53:22 +08001344 unsigned int authsize = crypto_aead_authsize(authenc);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001345 struct talitos_ctx *ctx = crypto_aead_ctx(authenc);
Kim Phillipsfe5720e2008-10-12 20:33:14 +08001346 struct talitos_private *priv = dev_get_drvdata(ctx->dev);
Lee Nipper56af8cd2009-03-29 15:50:50 +08001347 struct talitos_edesc *edesc;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001348 struct scatterlist *sg;
1349 void *icvdata;
1350
1351 req->cryptlen -= authsize;
1352
1353 /* allocate extended descriptor */
Horia Geanta62293a32013-11-28 15:11:17 +02001354 edesc = aead_edesc_alloc(req, req->iv, 1, false);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001355 if (IS_ERR(edesc))
1356 return PTR_ERR(edesc);
1357
Kim Phillipsfe5720e2008-10-12 20:33:14 +08001358 if ((priv->features & TALITOS_FTR_HW_AUTH_CHECK) &&
Kim Phillipse938e462009-03-29 15:53:23 +08001359 ((!edesc->src_nents && !edesc->dst_nents) ||
1360 priv->features & TALITOS_FTR_SRC_LINK_TBL_LEN_INCLUDES_EXTENT)) {
Kim Phillips9c4a7962008-06-23 19:50:15 +08001361
Kim Phillipsfe5720e2008-10-12 20:33:14 +08001362 /* decrypt and check the ICV */
Kim Phillipse938e462009-03-29 15:53:23 +08001363 edesc->desc.hdr = ctx->desc_hdr_template |
1364 DESC_HDR_DIR_INBOUND |
Kim Phillipsfe5720e2008-10-12 20:33:14 +08001365 DESC_HDR_MODE1_MDEU_CICV;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001366
Kim Phillipsfe5720e2008-10-12 20:33:14 +08001367 /* reset integrity check result bits */
1368 edesc->desc.hdr_lo = 0;
Kim Phillips9c4a7962008-06-23 19:50:15 +08001369
Herbert Xuaeb4c132015-07-30 17:53:22 +08001370 return ipsec_esp(edesc, req, ipsec_esp_decrypt_hwauth_done);
Kim Phillipsfe5720e2008-10-12 20:33:14 +08001371 }
Kim Phillipse938e462009-03-29 15:53:23 +08001372
1373 /* Have to check the ICV with software */
1374 edesc->desc.hdr = ctx->desc_hdr_template | DESC_HDR_DIR_INBOUND;
1375
1376 /* stash incoming ICV for later cmp with ICV generated by the h/w */
1377 if (edesc->dma_len)
Herbert Xuaeb4c132015-07-30 17:53:22 +08001378 icvdata = (char *)&edesc->link_tbl[edesc->src_nents +
1379 edesc->dst_nents + 2];
Kim Phillipse938e462009-03-29 15:53:23 +08001380 else
1381 icvdata = &edesc->link_tbl[0];
1382
1383 sg = sg_last(req->src, edesc->src_nents ? : 1);
1384
Herbert Xuaeb4c132015-07-30 17:53:22 +08001385 memcpy(icvdata, (char *)sg_virt(sg) + sg->length - authsize, authsize);
Kim Phillipse938e462009-03-29 15:53:23 +08001386
Herbert Xuaeb4c132015-07-30 17:53:22 +08001387 return ipsec_esp(edesc, req, ipsec_esp_decrypt_swauth_done);
Kim Phillips9c4a7962008-06-23 19:50:15 +08001388}
1389
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001390static int ablkcipher_setkey(struct crypto_ablkcipher *cipher,
1391 const u8 *key, unsigned int keylen)
1392{
1393 struct talitos_ctx *ctx = crypto_ablkcipher_ctx(cipher);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001394
1395 memcpy(&ctx->key, key, keylen);
1396 ctx->keylen = keylen;
1397
1398 return 0;
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001399}
1400
LEROY Christophe032d1972015-04-17 16:31:51 +02001401static void unmap_sg_talitos_ptr(struct device *dev, struct scatterlist *src,
1402 struct scatterlist *dst, unsigned int len,
1403 struct talitos_edesc *edesc)
1404{
LEROY Christophe6f65f6a2015-04-17 16:32:15 +02001405 struct talitos_private *priv = dev_get_drvdata(dev);
1406 bool is_sec1 = has_ftr_sec1(priv);
1407
1408 if (is_sec1) {
1409 if (!edesc->src_nents) {
1410 dma_unmap_sg(dev, src, 1,
1411 dst != src ? DMA_TO_DEVICE
1412 : DMA_BIDIRECTIONAL);
1413 }
1414 if (dst && edesc->dst_nents) {
1415 dma_sync_single_for_device(dev,
1416 edesc->dma_link_tbl + len,
1417 len, DMA_FROM_DEVICE);
1418 sg_copy_from_buffer(dst, edesc->dst_nents ? : 1,
1419 edesc->buf + len, len);
1420 } else if (dst && dst != src) {
1421 dma_unmap_sg(dev, dst, 1, DMA_FROM_DEVICE);
1422 }
1423 } else {
1424 talitos_sg_unmap(dev, edesc, src, dst);
1425 }
LEROY Christophe032d1972015-04-17 16:31:51 +02001426}
1427
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001428static void common_nonsnoop_unmap(struct device *dev,
1429 struct talitos_edesc *edesc,
1430 struct ablkcipher_request *areq)
1431{
1432 unmap_single_talitos_ptr(dev, &edesc->desc.ptr[5], DMA_FROM_DEVICE);
LEROY Christophe032d1972015-04-17 16:31:51 +02001433
1434 unmap_sg_talitos_ptr(dev, areq->src, areq->dst, areq->nbytes, edesc);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001435 unmap_single_talitos_ptr(dev, &edesc->desc.ptr[2], DMA_TO_DEVICE);
1436 unmap_single_talitos_ptr(dev, &edesc->desc.ptr[1], DMA_TO_DEVICE);
1437
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001438 if (edesc->dma_len)
1439 dma_unmap_single(dev, edesc->dma_link_tbl, edesc->dma_len,
1440 DMA_BIDIRECTIONAL);
1441}
1442
1443static void ablkcipher_done(struct device *dev,
1444 struct talitos_desc *desc, void *context,
1445 int err)
1446{
1447 struct ablkcipher_request *areq = context;
Kim Phillips19bbbc62009-03-29 15:53:59 +08001448 struct talitos_edesc *edesc;
1449
1450 edesc = container_of(desc, struct talitos_edesc, desc);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001451
1452 common_nonsnoop_unmap(dev, edesc, areq);
1453
1454 kfree(edesc);
1455
1456 areq->base.complete(&areq->base, err);
1457}
1458
LEROY Christophe032d1972015-04-17 16:31:51 +02001459int map_sg_in_talitos_ptr(struct device *dev, struct scatterlist *src,
1460 unsigned int len, struct talitos_edesc *edesc,
1461 enum dma_data_direction dir, struct talitos_ptr *ptr)
1462{
1463 int sg_count;
LEROY Christophe922f9dc2015-04-17 16:32:07 +02001464 struct talitos_private *priv = dev_get_drvdata(dev);
1465 bool is_sec1 = has_ftr_sec1(priv);
LEROY Christophe032d1972015-04-17 16:31:51 +02001466
LEROY Christophe922f9dc2015-04-17 16:32:07 +02001467 to_talitos_ptr_len(ptr, len, is_sec1);
LEROY Christophe032d1972015-04-17 16:31:51 +02001468
LEROY Christophe6f65f6a2015-04-17 16:32:15 +02001469 if (is_sec1) {
1470 sg_count = edesc->src_nents ? : 1;
LEROY Christophe032d1972015-04-17 16:31:51 +02001471
LEROY Christophe6f65f6a2015-04-17 16:32:15 +02001472 if (sg_count == 1) {
1473 dma_map_sg(dev, src, 1, dir);
LEROY Christophe922f9dc2015-04-17 16:32:07 +02001474 to_talitos_ptr(ptr, sg_dma_address(src), is_sec1);
LEROY Christophe6f65f6a2015-04-17 16:32:15 +02001475 } else {
1476 sg_copy_to_buffer(src, sg_count, edesc->buf, len);
1477 to_talitos_ptr(ptr, edesc->dma_link_tbl, is_sec1);
1478 dma_sync_single_for_device(dev, edesc->dma_link_tbl,
1479 len, DMA_TO_DEVICE);
1480 }
1481 } else {
1482 to_talitos_ptr_extent_clear(ptr, is_sec1);
1483
LABBE Corentinb8a011d2015-09-23 13:55:25 +02001484 sg_count = dma_map_sg(dev, src, edesc->src_nents ? : 1, dir);
LEROY Christophe6f65f6a2015-04-17 16:32:15 +02001485
1486 if (sg_count == 1) {
1487 to_talitos_ptr(ptr, sg_dma_address(src), is_sec1);
1488 } else {
1489 sg_count = sg_to_link_tbl(src, sg_count, len,
1490 &edesc->link_tbl[0]);
1491 if (sg_count > 1) {
1492 to_talitos_ptr(ptr, edesc->dma_link_tbl, 0);
1493 ptr->j_extent |= DESC_PTR_LNKTBL_JUMP;
1494 dma_sync_single_for_device(dev,
1495 edesc->dma_link_tbl,
1496 edesc->dma_len,
1497 DMA_BIDIRECTIONAL);
1498 } else {
1499 /* Only one segment now, so no link tbl needed*/
1500 to_talitos_ptr(ptr, sg_dma_address(src),
1501 is_sec1);
1502 }
LEROY Christophe032d1972015-04-17 16:31:51 +02001503 }
1504 }
1505 return sg_count;
1506}
1507
1508void map_sg_out_talitos_ptr(struct device *dev, struct scatterlist *dst,
1509 unsigned int len, struct talitos_edesc *edesc,
1510 enum dma_data_direction dir,
1511 struct talitos_ptr *ptr, int sg_count)
1512{
LEROY Christophe922f9dc2015-04-17 16:32:07 +02001513 struct talitos_private *priv = dev_get_drvdata(dev);
1514 bool is_sec1 = has_ftr_sec1(priv);
1515
LEROY Christophe032d1972015-04-17 16:31:51 +02001516 if (dir != DMA_NONE)
LABBE Corentinb8a011d2015-09-23 13:55:25 +02001517 sg_count = dma_map_sg(dev, dst, edesc->dst_nents ? : 1, dir);
LEROY Christophe032d1972015-04-17 16:31:51 +02001518
LEROY Christophe6f65f6a2015-04-17 16:32:15 +02001519 to_talitos_ptr_len(ptr, len, is_sec1);
LEROY Christophe032d1972015-04-17 16:31:51 +02001520
LEROY Christophe6f65f6a2015-04-17 16:32:15 +02001521 if (is_sec1) {
1522 if (sg_count == 1) {
1523 if (dir != DMA_NONE)
1524 dma_map_sg(dev, dst, 1, dir);
1525 to_talitos_ptr(ptr, sg_dma_address(dst), is_sec1);
1526 } else {
1527 to_talitos_ptr(ptr, edesc->dma_link_tbl + len, is_sec1);
1528 dma_sync_single_for_device(dev,
1529 edesc->dma_link_tbl + len,
1530 len, DMA_FROM_DEVICE);
1531 }
1532 } else {
1533 to_talitos_ptr_extent_clear(ptr, is_sec1);
1534
1535 if (sg_count == 1) {
1536 to_talitos_ptr(ptr, sg_dma_address(dst), is_sec1);
1537 } else {
1538 struct talitos_ptr *link_tbl_ptr =
1539 &edesc->link_tbl[edesc->src_nents + 1];
1540
1541 to_talitos_ptr(ptr, edesc->dma_link_tbl +
1542 (edesc->src_nents + 1) *
1543 sizeof(struct talitos_ptr), 0);
1544 ptr->j_extent |= DESC_PTR_LNKTBL_JUMP;
Horia Geant?42e8b0d2015-05-11 20:04:56 +03001545 sg_to_link_tbl(dst, sg_count, len, link_tbl_ptr);
LEROY Christophe6f65f6a2015-04-17 16:32:15 +02001546 dma_sync_single_for_device(dev, edesc->dma_link_tbl,
1547 edesc->dma_len,
1548 DMA_BIDIRECTIONAL);
1549 }
LEROY Christophe032d1972015-04-17 16:31:51 +02001550 }
1551}
1552
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001553static int common_nonsnoop(struct talitos_edesc *edesc,
1554 struct ablkcipher_request *areq,
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001555 void (*callback) (struct device *dev,
1556 struct talitos_desc *desc,
1557 void *context, int error))
1558{
1559 struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(areq);
1560 struct talitos_ctx *ctx = crypto_ablkcipher_ctx(cipher);
1561 struct device *dev = ctx->dev;
1562 struct talitos_desc *desc = &edesc->desc;
1563 unsigned int cryptlen = areq->nbytes;
Horia Geanta79fd31d2012-08-02 17:16:40 +03001564 unsigned int ivsize = crypto_ablkcipher_ivsize(cipher);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001565 int sg_count, ret;
LEROY Christophe922f9dc2015-04-17 16:32:07 +02001566 struct talitos_private *priv = dev_get_drvdata(dev);
1567 bool is_sec1 = has_ftr_sec1(priv);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001568
1569 /* first DWORD empty */
LEROY Christophe2529bc32015-04-17 16:31:49 +02001570 desc->ptr[0] = zero_entry;
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001571
1572 /* cipher iv */
LEROY Christophe922f9dc2015-04-17 16:32:07 +02001573 to_talitos_ptr(&desc->ptr[1], edesc->iv_dma, is_sec1);
1574 to_talitos_ptr_len(&desc->ptr[1], ivsize, is_sec1);
1575 to_talitos_ptr_extent_clear(&desc->ptr[1], is_sec1);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001576
1577 /* cipher key */
1578 map_single_talitos_ptr(dev, &desc->ptr[2], ctx->keylen,
LEROY Christophea2b35aa2015-04-17 16:31:57 +02001579 (char *)&ctx->key, DMA_TO_DEVICE);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001580
1581 /*
1582 * cipher in
1583 */
LEROY Christophe032d1972015-04-17 16:31:51 +02001584 sg_count = map_sg_in_talitos_ptr(dev, areq->src, cryptlen, edesc,
1585 (areq->src == areq->dst) ?
1586 DMA_BIDIRECTIONAL : DMA_TO_DEVICE,
1587 &desc->ptr[3]);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001588
1589 /* cipher out */
LEROY Christophe032d1972015-04-17 16:31:51 +02001590 map_sg_out_talitos_ptr(dev, areq->dst, cryptlen, edesc,
1591 (areq->src == areq->dst) ? DMA_NONE
1592 : DMA_FROM_DEVICE,
1593 &desc->ptr[4], sg_count);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001594
1595 /* iv out */
LEROY Christophea2b35aa2015-04-17 16:31:57 +02001596 map_single_talitos_ptr(dev, &desc->ptr[5], ivsize, ctx->iv,
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001597 DMA_FROM_DEVICE);
1598
1599 /* last DWORD empty */
LEROY Christophe2529bc32015-04-17 16:31:49 +02001600 desc->ptr[6] = zero_entry;
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001601
Kim Phillips5228f0f2011-07-15 11:21:38 +08001602 ret = talitos_submit(dev, ctx->ch, desc, callback, areq);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001603 if (ret != -EINPROGRESS) {
1604 common_nonsnoop_unmap(dev, edesc, areq);
1605 kfree(edesc);
1606 }
1607 return ret;
1608}
1609
Kim Phillipse938e462009-03-29 15:53:23 +08001610static struct talitos_edesc *ablkcipher_edesc_alloc(struct ablkcipher_request *
Horia Geanta62293a32013-11-28 15:11:17 +02001611 areq, bool encrypt)
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001612{
1613 struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(areq);
1614 struct talitos_ctx *ctx = crypto_ablkcipher_ctx(cipher);
Horia Geanta79fd31d2012-08-02 17:16:40 +03001615 unsigned int ivsize = crypto_ablkcipher_ivsize(cipher);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001616
Herbert Xuaeb4c132015-07-30 17:53:22 +08001617 return talitos_edesc_alloc(ctx->dev, areq->src, areq->dst,
Horia Geanta79fd31d2012-08-02 17:16:40 +03001618 areq->info, 0, areq->nbytes, 0, ivsize, 0,
Horia Geanta62293a32013-11-28 15:11:17 +02001619 areq->base.flags, encrypt);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001620}
1621
1622static int ablkcipher_encrypt(struct ablkcipher_request *areq)
1623{
1624 struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(areq);
1625 struct talitos_ctx *ctx = crypto_ablkcipher_ctx(cipher);
1626 struct talitos_edesc *edesc;
1627
1628 /* allocate extended descriptor */
Horia Geanta62293a32013-11-28 15:11:17 +02001629 edesc = ablkcipher_edesc_alloc(areq, true);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001630 if (IS_ERR(edesc))
1631 return PTR_ERR(edesc);
1632
1633 /* set encrypt */
1634 edesc->desc.hdr = ctx->desc_hdr_template | DESC_HDR_MODE0_ENCRYPT;
1635
Kim Phillipsfebec542011-07-15 11:21:39 +08001636 return common_nonsnoop(edesc, areq, ablkcipher_done);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001637}
1638
1639static int ablkcipher_decrypt(struct ablkcipher_request *areq)
1640{
1641 struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(areq);
1642 struct talitos_ctx *ctx = crypto_ablkcipher_ctx(cipher);
1643 struct talitos_edesc *edesc;
1644
1645 /* allocate extended descriptor */
Horia Geanta62293a32013-11-28 15:11:17 +02001646 edesc = ablkcipher_edesc_alloc(areq, false);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001647 if (IS_ERR(edesc))
1648 return PTR_ERR(edesc);
1649
1650 edesc->desc.hdr = ctx->desc_hdr_template | DESC_HDR_DIR_INBOUND;
1651
Kim Phillipsfebec542011-07-15 11:21:39 +08001652 return common_nonsnoop(edesc, areq, ablkcipher_done);
Lee Nipper4de9d0b2009-03-29 15:52:32 +08001653}
1654
Lee Nipper497f2e62010-05-19 19:20:36 +10001655static void common_nonsnoop_hash_unmap(struct device *dev,
1656 struct talitos_edesc *edesc,
1657 struct ahash_request *areq)
1658{
1659 struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
LEROY Christophe922f9dc2015-04-17 16:32:07 +02001660 struct talitos_private *priv = dev_get_drvdata(dev);
1661 bool is_sec1 = has_ftr_sec1(priv);
Lee Nipper497f2e62010-05-19 19:20:36 +10001662
1663 unmap_single_talitos_ptr(dev, &edesc->desc.ptr[5], DMA_FROM_DEVICE);
1664
LEROY Christophe032d1972015-04-17 16:31:51 +02001665 unmap_sg_talitos_ptr(dev, req_ctx->psrc, NULL, 0, edesc);
1666
Lee Nipper497f2e62010-05-19 19:20:36 +10001667 /* When using hashctx-in, must unmap it. */
LEROY Christophe922f9dc2015-04-17 16:32:07 +02001668 if (from_talitos_ptr_len(&edesc->desc.ptr[1], is_sec1))
Lee Nipper497f2e62010-05-19 19:20:36 +10001669 unmap_single_talitos_ptr(dev, &edesc->desc.ptr[1],
1670 DMA_TO_DEVICE);
1671
LEROY Christophe922f9dc2015-04-17 16:32:07 +02001672 if (from_talitos_ptr_len(&edesc->desc.ptr[2], is_sec1))
Lee Nipper497f2e62010-05-19 19:20:36 +10001673 unmap_single_talitos_ptr(dev, &edesc->desc.ptr[2],
1674 DMA_TO_DEVICE);
1675
Lee Nipper497f2e62010-05-19 19:20:36 +10001676 if (edesc->dma_len)
1677 dma_unmap_single(dev, edesc->dma_link_tbl, edesc->dma_len,
1678 DMA_BIDIRECTIONAL);
1679
1680}
1681
1682static void ahash_done(struct device *dev,
1683 struct talitos_desc *desc, void *context,
1684 int err)
1685{
1686 struct ahash_request *areq = context;
1687 struct talitos_edesc *edesc =
1688 container_of(desc, struct talitos_edesc, desc);
1689 struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
1690
1691 if (!req_ctx->last && req_ctx->to_hash_later) {
1692 /* Position any partial block for next update/final/finup */
1693 memcpy(req_ctx->buf, req_ctx->bufnext, req_ctx->to_hash_later);
Lee Nipper5e833bc2010-06-16 15:29:15 +10001694 req_ctx->nbuf = req_ctx->to_hash_later;
Lee Nipper497f2e62010-05-19 19:20:36 +10001695 }
1696 common_nonsnoop_hash_unmap(dev, edesc, areq);
1697
1698 kfree(edesc);
1699
1700 areq->base.complete(&areq->base, err);
1701}
1702
LEROY Christophe2d029052015-04-17 16:32:18 +02001703/*
1704 * SEC1 doesn't like hashing of 0 sized message, so we do the padding
1705 * ourself and submit a padded block
1706 */
1707void talitos_handle_buggy_hash(struct talitos_ctx *ctx,
1708 struct talitos_edesc *edesc,
1709 struct talitos_ptr *ptr)
1710{
1711 static u8 padded_hash[64] = {
1712 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1713 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1714 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1715 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1716 };
1717
1718 pr_err_once("Bug in SEC1, padding ourself\n");
1719 edesc->desc.hdr &= ~DESC_HDR_MODE0_MDEU_PAD;
1720 map_single_talitos_ptr(ctx->dev, ptr, sizeof(padded_hash),
1721 (char *)padded_hash, DMA_TO_DEVICE);
1722}
1723
Lee Nipper497f2e62010-05-19 19:20:36 +10001724static int common_nonsnoop_hash(struct talitos_edesc *edesc,
1725 struct ahash_request *areq, unsigned int length,
1726 void (*callback) (struct device *dev,
1727 struct talitos_desc *desc,
1728 void *context, int error))
1729{
1730 struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
1731 struct talitos_ctx *ctx = crypto_ahash_ctx(tfm);
1732 struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
1733 struct device *dev = ctx->dev;
1734 struct talitos_desc *desc = &edesc->desc;
LEROY Christophe032d1972015-04-17 16:31:51 +02001735 int ret;
LEROY Christophe922f9dc2015-04-17 16:32:07 +02001736 struct talitos_private *priv = dev_get_drvdata(dev);
1737 bool is_sec1 = has_ftr_sec1(priv);
Lee Nipper497f2e62010-05-19 19:20:36 +10001738
1739 /* first DWORD empty */
1740 desc->ptr[0] = zero_entry;
1741
Kim Phillips60f208d2010-05-19 19:21:53 +10001742 /* hash context in */
1743 if (!req_ctx->first || req_ctx->swinit) {
Lee Nipper497f2e62010-05-19 19:20:36 +10001744 map_single_talitos_ptr(dev, &desc->ptr[1],
1745 req_ctx->hw_context_size,
LEROY Christophea2b35aa2015-04-17 16:31:57 +02001746 (char *)req_ctx->hw_context,
Lee Nipper497f2e62010-05-19 19:20:36 +10001747 DMA_TO_DEVICE);
Kim Phillips60f208d2010-05-19 19:21:53 +10001748 req_ctx->swinit = 0;
Lee Nipper497f2e62010-05-19 19:20:36 +10001749 } else {
1750 desc->ptr[1] = zero_entry;
1751 /* Indicate next op is not the first. */
1752 req_ctx->first = 0;
1753 }
1754
1755 /* HMAC key */
1756 if (ctx->keylen)
1757 map_single_talitos_ptr(dev, &desc->ptr[2], ctx->keylen,
LEROY Christophea2b35aa2015-04-17 16:31:57 +02001758 (char *)&ctx->key, DMA_TO_DEVICE);
Lee Nipper497f2e62010-05-19 19:20:36 +10001759 else
1760 desc->ptr[2] = zero_entry;
1761
1762 /*
1763 * data in
1764 */
LEROY Christophe032d1972015-04-17 16:31:51 +02001765 map_sg_in_talitos_ptr(dev, req_ctx->psrc, length, edesc,
1766 DMA_TO_DEVICE, &desc->ptr[3]);
Lee Nipper497f2e62010-05-19 19:20:36 +10001767
1768 /* fifth DWORD empty */
1769 desc->ptr[4] = zero_entry;
1770
1771 /* hash/HMAC out -or- hash context out */
1772 if (req_ctx->last)
1773 map_single_talitos_ptr(dev, &desc->ptr[5],
1774 crypto_ahash_digestsize(tfm),
LEROY Christophea2b35aa2015-04-17 16:31:57 +02001775 areq->result, DMA_FROM_DEVICE);
Lee Nipper497f2e62010-05-19 19:20:36 +10001776 else
1777 map_single_talitos_ptr(dev, &desc->ptr[5],
1778 req_ctx->hw_context_size,
LEROY Christophea2b35aa2015-04-17 16:31:57 +02001779 req_ctx->hw_context, DMA_FROM_DEVICE);
Lee Nipper497f2e62010-05-19 19:20:36 +10001780
1781 /* last DWORD empty */
1782 desc->ptr[6] = zero_entry;
1783
LEROY Christophe2d029052015-04-17 16:32:18 +02001784 if (is_sec1 && from_talitos_ptr_len(&desc->ptr[3], true) == 0)
1785 talitos_handle_buggy_hash(ctx, edesc, &desc->ptr[3]);
1786
Kim Phillips5228f0f2011-07-15 11:21:38 +08001787 ret = talitos_submit(dev, ctx->ch, desc, callback, areq);
Lee Nipper497f2e62010-05-19 19:20:36 +10001788 if (ret != -EINPROGRESS) {
1789 common_nonsnoop_hash_unmap(dev, edesc, areq);
1790 kfree(edesc);
1791 }
1792 return ret;
1793}
1794
1795static struct talitos_edesc *ahash_edesc_alloc(struct ahash_request *areq,
1796 unsigned int nbytes)
1797{
1798 struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
1799 struct talitos_ctx *ctx = crypto_ahash_ctx(tfm);
1800 struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
1801
Herbert Xuaeb4c132015-07-30 17:53:22 +08001802 return talitos_edesc_alloc(ctx->dev, req_ctx->psrc, NULL, NULL, 0,
Horia Geanta62293a32013-11-28 15:11:17 +02001803 nbytes, 0, 0, 0, areq->base.flags, false);
Lee Nipper497f2e62010-05-19 19:20:36 +10001804}
1805
1806static int ahash_init(struct ahash_request *areq)
1807{
1808 struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
1809 struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
1810
1811 /* Initialize the context */
Lee Nipper5e833bc2010-06-16 15:29:15 +10001812 req_ctx->nbuf = 0;
Kim Phillips60f208d2010-05-19 19:21:53 +10001813 req_ctx->first = 1; /* first indicates h/w must init its context */
1814 req_ctx->swinit = 0; /* assume h/w init of context */
Lee Nipper497f2e62010-05-19 19:20:36 +10001815 req_ctx->hw_context_size =
1816 (crypto_ahash_digestsize(tfm) <= SHA256_DIGEST_SIZE)
1817 ? TALITOS_MDEU_CONTEXT_SIZE_MD5_SHA1_SHA256
1818 : TALITOS_MDEU_CONTEXT_SIZE_SHA384_SHA512;
1819
1820 return 0;
1821}
1822
Kim Phillips60f208d2010-05-19 19:21:53 +10001823/*
1824 * on h/w without explicit sha224 support, we initialize h/w context
1825 * manually with sha224 constants, and tell it to run sha256.
1826 */
1827static int ahash_init_sha224_swinit(struct ahash_request *areq)
1828{
1829 struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
1830
1831 ahash_init(areq);
1832 req_ctx->swinit = 1;/* prevent h/w initting context with sha256 values*/
1833
Kim Phillipsa7524472010-09-23 15:56:38 +08001834 req_ctx->hw_context[0] = SHA224_H0;
1835 req_ctx->hw_context[1] = SHA224_H1;
1836 req_ctx->hw_context[2] = SHA224_H2;
1837 req_ctx->hw_context[3] = SHA224_H3;
1838 req_ctx->hw_context[4] = SHA224_H4;
1839 req_ctx->hw_context[5] = SHA224_H5;
1840 req_ctx->hw_context[6] = SHA224_H6;
1841 req_ctx->hw_context[7] = SHA224_H7;
Kim Phillips60f208d2010-05-19 19:21:53 +10001842
1843 /* init 64-bit count */
1844 req_ctx->hw_context[8] = 0;
1845 req_ctx->hw_context[9] = 0;
1846
1847 return 0;
1848}
1849
Lee Nipper497f2e62010-05-19 19:20:36 +10001850static int ahash_process_req(struct ahash_request *areq, unsigned int nbytes)
1851{
1852 struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
1853 struct talitos_ctx *ctx = crypto_ahash_ctx(tfm);
1854 struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
1855 struct talitos_edesc *edesc;
1856 unsigned int blocksize =
1857 crypto_tfm_alg_blocksize(crypto_ahash_tfm(tfm));
1858 unsigned int nbytes_to_hash;
1859 unsigned int to_hash_later;
Lee Nipper5e833bc2010-06-16 15:29:15 +10001860 unsigned int nsg;
LABBE Corentin8e409fe2015-11-04 21:13:34 +01001861 int nents;
Lee Nipper497f2e62010-05-19 19:20:36 +10001862
Lee Nipper5e833bc2010-06-16 15:29:15 +10001863 if (!req_ctx->last && (nbytes + req_ctx->nbuf <= blocksize)) {
1864 /* Buffer up to one whole block */
LABBE Corentin8e409fe2015-11-04 21:13:34 +01001865 nents = sg_nents_for_len(areq->src, nbytes);
1866 if (nents < 0) {
1867 dev_err(ctx->dev, "Invalid number of src SG.\n");
1868 return nents;
1869 }
1870 sg_copy_to_buffer(areq->src, nents,
Lee Nipper5e833bc2010-06-16 15:29:15 +10001871 req_ctx->buf + req_ctx->nbuf, nbytes);
1872 req_ctx->nbuf += nbytes;
Lee Nipper497f2e62010-05-19 19:20:36 +10001873 return 0;
1874 }
1875
Lee Nipper5e833bc2010-06-16 15:29:15 +10001876 /* At least (blocksize + 1) bytes are available to hash */
1877 nbytes_to_hash = nbytes + req_ctx->nbuf;
1878 to_hash_later = nbytes_to_hash & (blocksize - 1);
1879
1880 if (req_ctx->last)
1881 to_hash_later = 0;
1882 else if (to_hash_later)
1883 /* There is a partial block. Hash the full block(s) now */
1884 nbytes_to_hash -= to_hash_later;
1885 else {
1886 /* Keep one block buffered */
1887 nbytes_to_hash -= blocksize;
1888 to_hash_later = blocksize;
1889 }
1890
1891 /* Chain in any previously buffered data */
1892 if (req_ctx->nbuf) {
1893 nsg = (req_ctx->nbuf < nbytes_to_hash) ? 2 : 1;
1894 sg_init_table(req_ctx->bufsl, nsg);
1895 sg_set_buf(req_ctx->bufsl, req_ctx->buf, req_ctx->nbuf);
1896 if (nsg > 1)
Dan Williamsc56f6d12015-08-07 18:15:13 +02001897 sg_chain(req_ctx->bufsl, 2, areq->src);
Lee Nipper497f2e62010-05-19 19:20:36 +10001898 req_ctx->psrc = req_ctx->bufsl;
Lee Nipper5e833bc2010-06-16 15:29:15 +10001899 } else
Lee Nipper497f2e62010-05-19 19:20:36 +10001900 req_ctx->psrc = areq->src;
Lee Nipper497f2e62010-05-19 19:20:36 +10001901
Lee Nipper5e833bc2010-06-16 15:29:15 +10001902 if (to_hash_later) {
LABBE Corentin8e409fe2015-11-04 21:13:34 +01001903 nents = sg_nents_for_len(areq->src, nbytes);
1904 if (nents < 0) {
1905 dev_err(ctx->dev, "Invalid number of src SG.\n");
1906 return nents;
1907 }
Akinobu Mitad0525722013-07-08 16:01:55 -07001908 sg_pcopy_to_buffer(areq->src, nents,
Lee Nipper5e833bc2010-06-16 15:29:15 +10001909 req_ctx->bufnext,
1910 to_hash_later,
1911 nbytes - to_hash_later);
Lee Nipper497f2e62010-05-19 19:20:36 +10001912 }
Lee Nipper5e833bc2010-06-16 15:29:15 +10001913 req_ctx->to_hash_later = to_hash_later;
Lee Nipper497f2e62010-05-19 19:20:36 +10001914
Lee Nipper5e833bc2010-06-16 15:29:15 +10001915 /* Allocate extended descriptor */
Lee Nipper497f2e62010-05-19 19:20:36 +10001916 edesc = ahash_edesc_alloc(areq, nbytes_to_hash);
1917 if (IS_ERR(edesc))
1918 return PTR_ERR(edesc);
1919
1920 edesc->desc.hdr = ctx->desc_hdr_template;
1921
1922 /* On last one, request SEC to pad; otherwise continue */
1923 if (req_ctx->last)
1924 edesc->desc.hdr |= DESC_HDR_MODE0_MDEU_PAD;
1925 else
1926 edesc->desc.hdr |= DESC_HDR_MODE0_MDEU_CONT;
1927
Kim Phillips60f208d2010-05-19 19:21:53 +10001928 /* request SEC to INIT hash. */
1929 if (req_ctx->first && !req_ctx->swinit)
Lee Nipper497f2e62010-05-19 19:20:36 +10001930 edesc->desc.hdr |= DESC_HDR_MODE0_MDEU_INIT;
1931
1932 /* When the tfm context has a keylen, it's an HMAC.
1933 * A first or last (ie. not middle) descriptor must request HMAC.
1934 */
1935 if (ctx->keylen && (req_ctx->first || req_ctx->last))
1936 edesc->desc.hdr |= DESC_HDR_MODE0_MDEU_HMAC;
1937
1938 return common_nonsnoop_hash(edesc, areq, nbytes_to_hash,
1939 ahash_done);
1940}
1941
1942static int ahash_update(struct ahash_request *areq)
1943{
1944 struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
1945
1946 req_ctx->last = 0;
1947
1948 return ahash_process_req(areq, areq->nbytes);
1949}
1950
1951static int ahash_final(struct ahash_request *areq)
1952{
1953 struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
1954
1955 req_ctx->last = 1;
1956
1957 return ahash_process_req(areq, 0);
1958}
1959
1960static int ahash_finup(struct ahash_request *areq)
1961{
1962 struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
1963
1964 req_ctx->last = 1;
1965
1966 return ahash_process_req(areq, areq->nbytes);
1967}
1968
1969static int ahash_digest(struct ahash_request *areq)
1970{
1971 struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
Kim Phillips60f208d2010-05-19 19:21:53 +10001972 struct crypto_ahash *ahash = crypto_ahash_reqtfm(areq);
Lee Nipper497f2e62010-05-19 19:20:36 +10001973
Kim Phillips60f208d2010-05-19 19:21:53 +10001974 ahash->init(areq);
Lee Nipper497f2e62010-05-19 19:20:36 +10001975 req_ctx->last = 1;
1976
1977 return ahash_process_req(areq, areq->nbytes);
1978}
1979
Horia Geant?3639ca82016-04-21 19:24:55 +03001980static int ahash_export(struct ahash_request *areq, void *out)
1981{
1982 struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
1983 struct talitos_export_state *export = out;
1984
1985 memcpy(export->hw_context, req_ctx->hw_context,
1986 req_ctx->hw_context_size);
1987 memcpy(export->buf, req_ctx->buf, req_ctx->nbuf);
1988 export->swinit = req_ctx->swinit;
1989 export->first = req_ctx->first;
1990 export->last = req_ctx->last;
1991 export->to_hash_later = req_ctx->to_hash_later;
1992 export->nbuf = req_ctx->nbuf;
1993
1994 return 0;
1995}
1996
1997static int ahash_import(struct ahash_request *areq, const void *in)
1998{
1999 struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
2000 struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
2001 const struct talitos_export_state *export = in;
2002
2003 memset(req_ctx, 0, sizeof(*req_ctx));
2004 req_ctx->hw_context_size =
2005 (crypto_ahash_digestsize(tfm) <= SHA256_DIGEST_SIZE)
2006 ? TALITOS_MDEU_CONTEXT_SIZE_MD5_SHA1_SHA256
2007 : TALITOS_MDEU_CONTEXT_SIZE_SHA384_SHA512;
2008 memcpy(req_ctx->hw_context, export->hw_context,
2009 req_ctx->hw_context_size);
2010 memcpy(req_ctx->buf, export->buf, export->nbuf);
2011 req_ctx->swinit = export->swinit;
2012 req_ctx->first = export->first;
2013 req_ctx->last = export->last;
2014 req_ctx->to_hash_later = export->to_hash_later;
2015 req_ctx->nbuf = export->nbuf;
2016
2017 return 0;
2018}
2019
Lee Nipper79b3a412011-11-21 16:13:25 +08002020struct keyhash_result {
2021 struct completion completion;
2022 int err;
2023};
2024
2025static void keyhash_complete(struct crypto_async_request *req, int err)
2026{
2027 struct keyhash_result *res = req->data;
2028
2029 if (err == -EINPROGRESS)
2030 return;
2031
2032 res->err = err;
2033 complete(&res->completion);
2034}
2035
2036static int keyhash(struct crypto_ahash *tfm, const u8 *key, unsigned int keylen,
2037 u8 *hash)
2038{
2039 struct talitos_ctx *ctx = crypto_tfm_ctx(crypto_ahash_tfm(tfm));
2040
2041 struct scatterlist sg[1];
2042 struct ahash_request *req;
2043 struct keyhash_result hresult;
2044 int ret;
2045
2046 init_completion(&hresult.completion);
2047
2048 req = ahash_request_alloc(tfm, GFP_KERNEL);
2049 if (!req)
2050 return -ENOMEM;
2051
2052 /* Keep tfm keylen == 0 during hash of the long key */
2053 ctx->keylen = 0;
2054 ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
2055 keyhash_complete, &hresult);
2056
2057 sg_init_one(&sg[0], key, keylen);
2058
2059 ahash_request_set_crypt(req, sg, hash, keylen);
2060 ret = crypto_ahash_digest(req);
2061 switch (ret) {
2062 case 0:
2063 break;
2064 case -EINPROGRESS:
2065 case -EBUSY:
2066 ret = wait_for_completion_interruptible(
2067 &hresult.completion);
2068 if (!ret)
2069 ret = hresult.err;
2070 break;
2071 default:
2072 break;
2073 }
2074 ahash_request_free(req);
2075
2076 return ret;
2077}
2078
2079static int ahash_setkey(struct crypto_ahash *tfm, const u8 *key,
2080 unsigned int keylen)
2081{
2082 struct talitos_ctx *ctx = crypto_tfm_ctx(crypto_ahash_tfm(tfm));
2083 unsigned int blocksize =
2084 crypto_tfm_alg_blocksize(crypto_ahash_tfm(tfm));
2085 unsigned int digestsize = crypto_ahash_digestsize(tfm);
2086 unsigned int keysize = keylen;
2087 u8 hash[SHA512_DIGEST_SIZE];
2088 int ret;
2089
2090 if (keylen <= blocksize)
2091 memcpy(ctx->key, key, keysize);
2092 else {
2093 /* Must get the hash of the long key */
2094 ret = keyhash(tfm, key, keylen, hash);
2095
2096 if (ret) {
2097 crypto_ahash_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN);
2098 return -EINVAL;
2099 }
2100
2101 keysize = digestsize;
2102 memcpy(ctx->key, hash, digestsize);
2103 }
2104
2105 ctx->keylen = keysize;
2106
2107 return 0;
2108}
2109
2110
Kim Phillips9c4a7962008-06-23 19:50:15 +08002111struct talitos_alg_template {
Lee Nipperd5e4aae2010-05-19 19:18:38 +10002112 u32 type;
2113 union {
2114 struct crypto_alg crypto;
Lee Nipperacbf7c622010-05-19 19:19:33 +10002115 struct ahash_alg hash;
Herbert Xuaeb4c132015-07-30 17:53:22 +08002116 struct aead_alg aead;
Lee Nipperd5e4aae2010-05-19 19:18:38 +10002117 } alg;
Kim Phillips9c4a7962008-06-23 19:50:15 +08002118 __be32 desc_hdr_template;
2119};
2120
2121static struct talitos_alg_template driver_algs[] = {
Horia Geanta991155b2013-03-20 16:31:38 +02002122 /* AEAD algorithms. These use a single-pass ipsec_esp descriptor */
Lee Nipperd5e4aae2010-05-19 19:18:38 +10002123 { .type = CRYPTO_ALG_TYPE_AEAD,
Herbert Xuaeb4c132015-07-30 17:53:22 +08002124 .alg.aead = {
2125 .base = {
2126 .cra_name = "authenc(hmac(sha1),cbc(aes))",
2127 .cra_driver_name = "authenc-hmac-sha1-"
2128 "cbc-aes-talitos",
2129 .cra_blocksize = AES_BLOCK_SIZE,
2130 .cra_flags = CRYPTO_ALG_ASYNC,
2131 },
2132 .ivsize = AES_BLOCK_SIZE,
2133 .maxauthsize = SHA1_DIGEST_SIZE,
Lee Nipper56af8cd2009-03-29 15:50:50 +08002134 },
Kim Phillips9c4a7962008-06-23 19:50:15 +08002135 .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
2136 DESC_HDR_SEL0_AESU |
2137 DESC_HDR_MODE0_AESU_CBC |
2138 DESC_HDR_SEL1_MDEUA |
2139 DESC_HDR_MODE1_MDEU_INIT |
2140 DESC_HDR_MODE1_MDEU_PAD |
2141 DESC_HDR_MODE1_MDEU_SHA1_HMAC,
Lee Nipper70bcaca2008-07-03 19:08:46 +08002142 },
Lee Nipperd5e4aae2010-05-19 19:18:38 +10002143 { .type = CRYPTO_ALG_TYPE_AEAD,
Herbert Xuaeb4c132015-07-30 17:53:22 +08002144 .alg.aead = {
2145 .base = {
2146 .cra_name = "authenc(hmac(sha1),"
2147 "cbc(des3_ede))",
2148 .cra_driver_name = "authenc-hmac-sha1-"
2149 "cbc-3des-talitos",
2150 .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2151 .cra_flags = CRYPTO_ALG_ASYNC,
2152 },
2153 .ivsize = DES3_EDE_BLOCK_SIZE,
2154 .maxauthsize = SHA1_DIGEST_SIZE,
Lee Nipper56af8cd2009-03-29 15:50:50 +08002155 },
Lee Nipper70bcaca2008-07-03 19:08:46 +08002156 .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
2157 DESC_HDR_SEL0_DEU |
2158 DESC_HDR_MODE0_DEU_CBC |
2159 DESC_HDR_MODE0_DEU_3DES |
2160 DESC_HDR_SEL1_MDEUA |
2161 DESC_HDR_MODE1_MDEU_INIT |
2162 DESC_HDR_MODE1_MDEU_PAD |
2163 DESC_HDR_MODE1_MDEU_SHA1_HMAC,
Lee Nipper3952f172008-07-10 18:29:18 +08002164 },
Horia Geanta357fb602012-07-03 19:16:53 +03002165 { .type = CRYPTO_ALG_TYPE_AEAD,
Herbert Xuaeb4c132015-07-30 17:53:22 +08002166 .alg.aead = {
2167 .base = {
2168 .cra_name = "authenc(hmac(sha224),cbc(aes))",
2169 .cra_driver_name = "authenc-hmac-sha224-"
2170 "cbc-aes-talitos",
2171 .cra_blocksize = AES_BLOCK_SIZE,
2172 .cra_flags = CRYPTO_ALG_ASYNC,
2173 },
2174 .ivsize = AES_BLOCK_SIZE,
2175 .maxauthsize = SHA224_DIGEST_SIZE,
Horia Geanta357fb602012-07-03 19:16:53 +03002176 },
2177 .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
2178 DESC_HDR_SEL0_AESU |
2179 DESC_HDR_MODE0_AESU_CBC |
2180 DESC_HDR_SEL1_MDEUA |
2181 DESC_HDR_MODE1_MDEU_INIT |
2182 DESC_HDR_MODE1_MDEU_PAD |
2183 DESC_HDR_MODE1_MDEU_SHA224_HMAC,
2184 },
2185 { .type = CRYPTO_ALG_TYPE_AEAD,
Herbert Xuaeb4c132015-07-30 17:53:22 +08002186 .alg.aead = {
2187 .base = {
2188 .cra_name = "authenc(hmac(sha224),"
2189 "cbc(des3_ede))",
2190 .cra_driver_name = "authenc-hmac-sha224-"
2191 "cbc-3des-talitos",
2192 .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2193 .cra_flags = CRYPTO_ALG_ASYNC,
2194 },
2195 .ivsize = DES3_EDE_BLOCK_SIZE,
2196 .maxauthsize = SHA224_DIGEST_SIZE,
Horia Geanta357fb602012-07-03 19:16:53 +03002197 },
2198 .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
2199 DESC_HDR_SEL0_DEU |
2200 DESC_HDR_MODE0_DEU_CBC |
2201 DESC_HDR_MODE0_DEU_3DES |
2202 DESC_HDR_SEL1_MDEUA |
2203 DESC_HDR_MODE1_MDEU_INIT |
2204 DESC_HDR_MODE1_MDEU_PAD |
2205 DESC_HDR_MODE1_MDEU_SHA224_HMAC,
2206 },
Lee Nipperd5e4aae2010-05-19 19:18:38 +10002207 { .type = CRYPTO_ALG_TYPE_AEAD,
Herbert Xuaeb4c132015-07-30 17:53:22 +08002208 .alg.aead = {
2209 .base = {
2210 .cra_name = "authenc(hmac(sha256),cbc(aes))",
2211 .cra_driver_name = "authenc-hmac-sha256-"
2212 "cbc-aes-talitos",
2213 .cra_blocksize = AES_BLOCK_SIZE,
2214 .cra_flags = CRYPTO_ALG_ASYNC,
2215 },
2216 .ivsize = AES_BLOCK_SIZE,
2217 .maxauthsize = SHA256_DIGEST_SIZE,
Lee Nipper56af8cd2009-03-29 15:50:50 +08002218 },
Lee Nipper3952f172008-07-10 18:29:18 +08002219 .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
2220 DESC_HDR_SEL0_AESU |
2221 DESC_HDR_MODE0_AESU_CBC |
2222 DESC_HDR_SEL1_MDEUA |
2223 DESC_HDR_MODE1_MDEU_INIT |
2224 DESC_HDR_MODE1_MDEU_PAD |
2225 DESC_HDR_MODE1_MDEU_SHA256_HMAC,
2226 },
Lee Nipperd5e4aae2010-05-19 19:18:38 +10002227 { .type = CRYPTO_ALG_TYPE_AEAD,
Herbert Xuaeb4c132015-07-30 17:53:22 +08002228 .alg.aead = {
2229 .base = {
2230 .cra_name = "authenc(hmac(sha256),"
2231 "cbc(des3_ede))",
2232 .cra_driver_name = "authenc-hmac-sha256-"
2233 "cbc-3des-talitos",
2234 .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2235 .cra_flags = CRYPTO_ALG_ASYNC,
2236 },
2237 .ivsize = DES3_EDE_BLOCK_SIZE,
2238 .maxauthsize = SHA256_DIGEST_SIZE,
Lee Nipper56af8cd2009-03-29 15:50:50 +08002239 },
Lee Nipper3952f172008-07-10 18:29:18 +08002240 .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
2241 DESC_HDR_SEL0_DEU |
2242 DESC_HDR_MODE0_DEU_CBC |
2243 DESC_HDR_MODE0_DEU_3DES |
2244 DESC_HDR_SEL1_MDEUA |
2245 DESC_HDR_MODE1_MDEU_INIT |
2246 DESC_HDR_MODE1_MDEU_PAD |
2247 DESC_HDR_MODE1_MDEU_SHA256_HMAC,
2248 },
Lee Nipperd5e4aae2010-05-19 19:18:38 +10002249 { .type = CRYPTO_ALG_TYPE_AEAD,
Herbert Xuaeb4c132015-07-30 17:53:22 +08002250 .alg.aead = {
2251 .base = {
2252 .cra_name = "authenc(hmac(sha384),cbc(aes))",
2253 .cra_driver_name = "authenc-hmac-sha384-"
2254 "cbc-aes-talitos",
2255 .cra_blocksize = AES_BLOCK_SIZE,
2256 .cra_flags = CRYPTO_ALG_ASYNC,
2257 },
2258 .ivsize = AES_BLOCK_SIZE,
2259 .maxauthsize = SHA384_DIGEST_SIZE,
Horia Geanta357fb602012-07-03 19:16:53 +03002260 },
2261 .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
2262 DESC_HDR_SEL0_AESU |
2263 DESC_HDR_MODE0_AESU_CBC |
2264 DESC_HDR_SEL1_MDEUB |
2265 DESC_HDR_MODE1_MDEU_INIT |
2266 DESC_HDR_MODE1_MDEU_PAD |
2267 DESC_HDR_MODE1_MDEUB_SHA384_HMAC,
2268 },
2269 { .type = CRYPTO_ALG_TYPE_AEAD,
Herbert Xuaeb4c132015-07-30 17:53:22 +08002270 .alg.aead = {
2271 .base = {
2272 .cra_name = "authenc(hmac(sha384),"
2273 "cbc(des3_ede))",
2274 .cra_driver_name = "authenc-hmac-sha384-"
2275 "cbc-3des-talitos",
2276 .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2277 .cra_flags = CRYPTO_ALG_ASYNC,
2278 },
2279 .ivsize = DES3_EDE_BLOCK_SIZE,
2280 .maxauthsize = SHA384_DIGEST_SIZE,
Horia Geanta357fb602012-07-03 19:16:53 +03002281 },
2282 .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
2283 DESC_HDR_SEL0_DEU |
2284 DESC_HDR_MODE0_DEU_CBC |
2285 DESC_HDR_MODE0_DEU_3DES |
2286 DESC_HDR_SEL1_MDEUB |
2287 DESC_HDR_MODE1_MDEU_INIT |
2288 DESC_HDR_MODE1_MDEU_PAD |
2289 DESC_HDR_MODE1_MDEUB_SHA384_HMAC,
2290 },
2291 { .type = CRYPTO_ALG_TYPE_AEAD,
Herbert Xuaeb4c132015-07-30 17:53:22 +08002292 .alg.aead = {
2293 .base = {
2294 .cra_name = "authenc(hmac(sha512),cbc(aes))",
2295 .cra_driver_name = "authenc-hmac-sha512-"
2296 "cbc-aes-talitos",
2297 .cra_blocksize = AES_BLOCK_SIZE,
2298 .cra_flags = CRYPTO_ALG_ASYNC,
2299 },
2300 .ivsize = AES_BLOCK_SIZE,
2301 .maxauthsize = SHA512_DIGEST_SIZE,
Horia Geanta357fb602012-07-03 19:16:53 +03002302 },
2303 .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
2304 DESC_HDR_SEL0_AESU |
2305 DESC_HDR_MODE0_AESU_CBC |
2306 DESC_HDR_SEL1_MDEUB |
2307 DESC_HDR_MODE1_MDEU_INIT |
2308 DESC_HDR_MODE1_MDEU_PAD |
2309 DESC_HDR_MODE1_MDEUB_SHA512_HMAC,
2310 },
2311 { .type = CRYPTO_ALG_TYPE_AEAD,
Herbert Xuaeb4c132015-07-30 17:53:22 +08002312 .alg.aead = {
2313 .base = {
2314 .cra_name = "authenc(hmac(sha512),"
2315 "cbc(des3_ede))",
2316 .cra_driver_name = "authenc-hmac-sha512-"
2317 "cbc-3des-talitos",
2318 .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2319 .cra_flags = CRYPTO_ALG_ASYNC,
2320 },
2321 .ivsize = DES3_EDE_BLOCK_SIZE,
2322 .maxauthsize = SHA512_DIGEST_SIZE,
Horia Geanta357fb602012-07-03 19:16:53 +03002323 },
2324 .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
2325 DESC_HDR_SEL0_DEU |
2326 DESC_HDR_MODE0_DEU_CBC |
2327 DESC_HDR_MODE0_DEU_3DES |
2328 DESC_HDR_SEL1_MDEUB |
2329 DESC_HDR_MODE1_MDEU_INIT |
2330 DESC_HDR_MODE1_MDEU_PAD |
2331 DESC_HDR_MODE1_MDEUB_SHA512_HMAC,
2332 },
2333 { .type = CRYPTO_ALG_TYPE_AEAD,
Herbert Xuaeb4c132015-07-30 17:53:22 +08002334 .alg.aead = {
2335 .base = {
2336 .cra_name = "authenc(hmac(md5),cbc(aes))",
2337 .cra_driver_name = "authenc-hmac-md5-"
2338 "cbc-aes-talitos",
2339 .cra_blocksize = AES_BLOCK_SIZE,
2340 .cra_flags = CRYPTO_ALG_ASYNC,
2341 },
2342 .ivsize = AES_BLOCK_SIZE,
2343 .maxauthsize = MD5_DIGEST_SIZE,
Lee Nipper56af8cd2009-03-29 15:50:50 +08002344 },
Lee Nipper3952f172008-07-10 18:29:18 +08002345 .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
2346 DESC_HDR_SEL0_AESU |
2347 DESC_HDR_MODE0_AESU_CBC |
2348 DESC_HDR_SEL1_MDEUA |
2349 DESC_HDR_MODE1_MDEU_INIT |
2350 DESC_HDR_MODE1_MDEU_PAD |
2351 DESC_HDR_MODE1_MDEU_MD5_HMAC,
2352 },
Lee Nipperd5e4aae2010-05-19 19:18:38 +10002353 { .type = CRYPTO_ALG_TYPE_AEAD,
Herbert Xuaeb4c132015-07-30 17:53:22 +08002354 .alg.aead = {
2355 .base = {
2356 .cra_name = "authenc(hmac(md5),cbc(des3_ede))",
2357 .cra_driver_name = "authenc-hmac-md5-"
2358 "cbc-3des-talitos",
2359 .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2360 .cra_flags = CRYPTO_ALG_ASYNC,
2361 },
2362 .ivsize = DES3_EDE_BLOCK_SIZE,
2363 .maxauthsize = MD5_DIGEST_SIZE,
Lee Nipper56af8cd2009-03-29 15:50:50 +08002364 },
Lee Nipper3952f172008-07-10 18:29:18 +08002365 .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
2366 DESC_HDR_SEL0_DEU |
2367 DESC_HDR_MODE0_DEU_CBC |
2368 DESC_HDR_MODE0_DEU_3DES |
2369 DESC_HDR_SEL1_MDEUA |
2370 DESC_HDR_MODE1_MDEU_INIT |
2371 DESC_HDR_MODE1_MDEU_PAD |
2372 DESC_HDR_MODE1_MDEU_MD5_HMAC,
Lee Nipper4de9d0b2009-03-29 15:52:32 +08002373 },
2374 /* ABLKCIPHER algorithms. */
Lee Nipperd5e4aae2010-05-19 19:18:38 +10002375 { .type = CRYPTO_ALG_TYPE_ABLKCIPHER,
2376 .alg.crypto = {
LEROY Christophe5e75ae12015-12-01 12:44:15 +01002377 .cra_name = "ecb(aes)",
2378 .cra_driver_name = "ecb-aes-talitos",
2379 .cra_blocksize = AES_BLOCK_SIZE,
2380 .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER |
2381 CRYPTO_ALG_ASYNC,
2382 .cra_ablkcipher = {
2383 .min_keysize = AES_MIN_KEY_SIZE,
2384 .max_keysize = AES_MAX_KEY_SIZE,
2385 .ivsize = AES_BLOCK_SIZE,
2386 }
2387 },
2388 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2389 DESC_HDR_SEL0_AESU,
2390 },
2391 { .type = CRYPTO_ALG_TYPE_ABLKCIPHER,
2392 .alg.crypto = {
Lee Nipper4de9d0b2009-03-29 15:52:32 +08002393 .cra_name = "cbc(aes)",
2394 .cra_driver_name = "cbc-aes-talitos",
2395 .cra_blocksize = AES_BLOCK_SIZE,
2396 .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER |
2397 CRYPTO_ALG_ASYNC,
Lee Nipper4de9d0b2009-03-29 15:52:32 +08002398 .cra_ablkcipher = {
Lee Nipper4de9d0b2009-03-29 15:52:32 +08002399 .min_keysize = AES_MIN_KEY_SIZE,
2400 .max_keysize = AES_MAX_KEY_SIZE,
2401 .ivsize = AES_BLOCK_SIZE,
2402 }
2403 },
2404 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2405 DESC_HDR_SEL0_AESU |
2406 DESC_HDR_MODE0_AESU_CBC,
2407 },
Lee Nipperd5e4aae2010-05-19 19:18:38 +10002408 { .type = CRYPTO_ALG_TYPE_ABLKCIPHER,
2409 .alg.crypto = {
LEROY Christophe5e75ae12015-12-01 12:44:15 +01002410 .cra_name = "ctr(aes)",
2411 .cra_driver_name = "ctr-aes-talitos",
2412 .cra_blocksize = AES_BLOCK_SIZE,
2413 .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER |
2414 CRYPTO_ALG_ASYNC,
2415 .cra_ablkcipher = {
2416 .min_keysize = AES_MIN_KEY_SIZE,
2417 .max_keysize = AES_MAX_KEY_SIZE,
2418 .ivsize = AES_BLOCK_SIZE,
2419 }
2420 },
2421 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2422 DESC_HDR_SEL0_AESU |
2423 DESC_HDR_MODE0_AESU_CTR,
2424 },
2425 { .type = CRYPTO_ALG_TYPE_ABLKCIPHER,
2426 .alg.crypto = {
2427 .cra_name = "ecb(des)",
2428 .cra_driver_name = "ecb-des-talitos",
2429 .cra_blocksize = DES_BLOCK_SIZE,
2430 .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER |
2431 CRYPTO_ALG_ASYNC,
2432 .cra_ablkcipher = {
2433 .min_keysize = DES_KEY_SIZE,
2434 .max_keysize = DES_KEY_SIZE,
2435 .ivsize = DES_BLOCK_SIZE,
2436 }
2437 },
2438 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2439 DESC_HDR_SEL0_DEU,
2440 },
2441 { .type = CRYPTO_ALG_TYPE_ABLKCIPHER,
2442 .alg.crypto = {
2443 .cra_name = "cbc(des)",
2444 .cra_driver_name = "cbc-des-talitos",
2445 .cra_blocksize = DES_BLOCK_SIZE,
2446 .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER |
2447 CRYPTO_ALG_ASYNC,
2448 .cra_ablkcipher = {
2449 .min_keysize = DES_KEY_SIZE,
2450 .max_keysize = DES_KEY_SIZE,
2451 .ivsize = DES_BLOCK_SIZE,
2452 }
2453 },
2454 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2455 DESC_HDR_SEL0_DEU |
2456 DESC_HDR_MODE0_DEU_CBC,
2457 },
2458 { .type = CRYPTO_ALG_TYPE_ABLKCIPHER,
2459 .alg.crypto = {
2460 .cra_name = "ecb(des3_ede)",
2461 .cra_driver_name = "ecb-3des-talitos",
2462 .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2463 .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER |
2464 CRYPTO_ALG_ASYNC,
2465 .cra_ablkcipher = {
2466 .min_keysize = DES3_EDE_KEY_SIZE,
2467 .max_keysize = DES3_EDE_KEY_SIZE,
2468 .ivsize = DES3_EDE_BLOCK_SIZE,
2469 }
2470 },
2471 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2472 DESC_HDR_SEL0_DEU |
2473 DESC_HDR_MODE0_DEU_3DES,
2474 },
2475 { .type = CRYPTO_ALG_TYPE_ABLKCIPHER,
2476 .alg.crypto = {
Lee Nipper4de9d0b2009-03-29 15:52:32 +08002477 .cra_name = "cbc(des3_ede)",
2478 .cra_driver_name = "cbc-3des-talitos",
2479 .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2480 .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER |
2481 CRYPTO_ALG_ASYNC,
Lee Nipper4de9d0b2009-03-29 15:52:32 +08002482 .cra_ablkcipher = {
Lee Nipper4de9d0b2009-03-29 15:52:32 +08002483 .min_keysize = DES3_EDE_KEY_SIZE,
2484 .max_keysize = DES3_EDE_KEY_SIZE,
2485 .ivsize = DES3_EDE_BLOCK_SIZE,
2486 }
2487 },
2488 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2489 DESC_HDR_SEL0_DEU |
2490 DESC_HDR_MODE0_DEU_CBC |
2491 DESC_HDR_MODE0_DEU_3DES,
Lee Nipper497f2e62010-05-19 19:20:36 +10002492 },
2493 /* AHASH algorithms. */
2494 { .type = CRYPTO_ALG_TYPE_AHASH,
2495 .alg.hash = {
Lee Nipper497f2e62010-05-19 19:20:36 +10002496 .halg.digestsize = MD5_DIGEST_SIZE,
Horia Geant?3639ca82016-04-21 19:24:55 +03002497 .halg.statesize = sizeof(struct talitos_export_state),
Lee Nipper497f2e62010-05-19 19:20:36 +10002498 .halg.base = {
2499 .cra_name = "md5",
2500 .cra_driver_name = "md5-talitos",
Martin Hicksb3988612015-03-03 08:21:34 -05002501 .cra_blocksize = MD5_HMAC_BLOCK_SIZE,
Lee Nipper497f2e62010-05-19 19:20:36 +10002502 .cra_flags = CRYPTO_ALG_TYPE_AHASH |
2503 CRYPTO_ALG_ASYNC,
Lee Nipper497f2e62010-05-19 19:20:36 +10002504 }
2505 },
2506 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2507 DESC_HDR_SEL0_MDEUA |
2508 DESC_HDR_MODE0_MDEU_MD5,
2509 },
2510 { .type = CRYPTO_ALG_TYPE_AHASH,
2511 .alg.hash = {
Lee Nipper497f2e62010-05-19 19:20:36 +10002512 .halg.digestsize = SHA1_DIGEST_SIZE,
Horia Geant?3639ca82016-04-21 19:24:55 +03002513 .halg.statesize = sizeof(struct talitos_export_state),
Lee Nipper497f2e62010-05-19 19:20:36 +10002514 .halg.base = {
2515 .cra_name = "sha1",
2516 .cra_driver_name = "sha1-talitos",
2517 .cra_blocksize = SHA1_BLOCK_SIZE,
2518 .cra_flags = CRYPTO_ALG_TYPE_AHASH |
2519 CRYPTO_ALG_ASYNC,
Lee Nipper497f2e62010-05-19 19:20:36 +10002520 }
2521 },
2522 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2523 DESC_HDR_SEL0_MDEUA |
2524 DESC_HDR_MODE0_MDEU_SHA1,
2525 },
2526 { .type = CRYPTO_ALG_TYPE_AHASH,
2527 .alg.hash = {
Kim Phillips60f208d2010-05-19 19:21:53 +10002528 .halg.digestsize = SHA224_DIGEST_SIZE,
Horia Geant?3639ca82016-04-21 19:24:55 +03002529 .halg.statesize = sizeof(struct talitos_export_state),
Kim Phillips60f208d2010-05-19 19:21:53 +10002530 .halg.base = {
2531 .cra_name = "sha224",
2532 .cra_driver_name = "sha224-talitos",
2533 .cra_blocksize = SHA224_BLOCK_SIZE,
2534 .cra_flags = CRYPTO_ALG_TYPE_AHASH |
2535 CRYPTO_ALG_ASYNC,
Kim Phillips60f208d2010-05-19 19:21:53 +10002536 }
2537 },
2538 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2539 DESC_HDR_SEL0_MDEUA |
2540 DESC_HDR_MODE0_MDEU_SHA224,
2541 },
2542 { .type = CRYPTO_ALG_TYPE_AHASH,
2543 .alg.hash = {
Lee Nipper497f2e62010-05-19 19:20:36 +10002544 .halg.digestsize = SHA256_DIGEST_SIZE,
Horia Geant?3639ca82016-04-21 19:24:55 +03002545 .halg.statesize = sizeof(struct talitos_export_state),
Lee Nipper497f2e62010-05-19 19:20:36 +10002546 .halg.base = {
2547 .cra_name = "sha256",
2548 .cra_driver_name = "sha256-talitos",
2549 .cra_blocksize = SHA256_BLOCK_SIZE,
2550 .cra_flags = CRYPTO_ALG_TYPE_AHASH |
2551 CRYPTO_ALG_ASYNC,
Lee Nipper497f2e62010-05-19 19:20:36 +10002552 }
2553 },
2554 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2555 DESC_HDR_SEL0_MDEUA |
2556 DESC_HDR_MODE0_MDEU_SHA256,
2557 },
2558 { .type = CRYPTO_ALG_TYPE_AHASH,
2559 .alg.hash = {
Lee Nipper497f2e62010-05-19 19:20:36 +10002560 .halg.digestsize = SHA384_DIGEST_SIZE,
Horia Geant?3639ca82016-04-21 19:24:55 +03002561 .halg.statesize = sizeof(struct talitos_export_state),
Lee Nipper497f2e62010-05-19 19:20:36 +10002562 .halg.base = {
2563 .cra_name = "sha384",
2564 .cra_driver_name = "sha384-talitos",
2565 .cra_blocksize = SHA384_BLOCK_SIZE,
2566 .cra_flags = CRYPTO_ALG_TYPE_AHASH |
2567 CRYPTO_ALG_ASYNC,
Lee Nipper497f2e62010-05-19 19:20:36 +10002568 }
2569 },
2570 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2571 DESC_HDR_SEL0_MDEUB |
2572 DESC_HDR_MODE0_MDEUB_SHA384,
2573 },
2574 { .type = CRYPTO_ALG_TYPE_AHASH,
2575 .alg.hash = {
Lee Nipper497f2e62010-05-19 19:20:36 +10002576 .halg.digestsize = SHA512_DIGEST_SIZE,
Horia Geant?3639ca82016-04-21 19:24:55 +03002577 .halg.statesize = sizeof(struct talitos_export_state),
Lee Nipper497f2e62010-05-19 19:20:36 +10002578 .halg.base = {
2579 .cra_name = "sha512",
2580 .cra_driver_name = "sha512-talitos",
2581 .cra_blocksize = SHA512_BLOCK_SIZE,
2582 .cra_flags = CRYPTO_ALG_TYPE_AHASH |
2583 CRYPTO_ALG_ASYNC,
Lee Nipper497f2e62010-05-19 19:20:36 +10002584 }
2585 },
2586 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2587 DESC_HDR_SEL0_MDEUB |
2588 DESC_HDR_MODE0_MDEUB_SHA512,
2589 },
Lee Nipper79b3a412011-11-21 16:13:25 +08002590 { .type = CRYPTO_ALG_TYPE_AHASH,
2591 .alg.hash = {
Lee Nipper79b3a412011-11-21 16:13:25 +08002592 .halg.digestsize = MD5_DIGEST_SIZE,
Horia Geant?3639ca82016-04-21 19:24:55 +03002593 .halg.statesize = sizeof(struct talitos_export_state),
Lee Nipper79b3a412011-11-21 16:13:25 +08002594 .halg.base = {
2595 .cra_name = "hmac(md5)",
2596 .cra_driver_name = "hmac-md5-talitos",
Martin Hicksb3988612015-03-03 08:21:34 -05002597 .cra_blocksize = MD5_HMAC_BLOCK_SIZE,
Lee Nipper79b3a412011-11-21 16:13:25 +08002598 .cra_flags = CRYPTO_ALG_TYPE_AHASH |
2599 CRYPTO_ALG_ASYNC,
Lee Nipper79b3a412011-11-21 16:13:25 +08002600 }
2601 },
2602 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2603 DESC_HDR_SEL0_MDEUA |
2604 DESC_HDR_MODE0_MDEU_MD5,
2605 },
2606 { .type = CRYPTO_ALG_TYPE_AHASH,
2607 .alg.hash = {
Lee Nipper79b3a412011-11-21 16:13:25 +08002608 .halg.digestsize = SHA1_DIGEST_SIZE,
Horia Geant?3639ca82016-04-21 19:24:55 +03002609 .halg.statesize = sizeof(struct talitos_export_state),
Lee Nipper79b3a412011-11-21 16:13:25 +08002610 .halg.base = {
2611 .cra_name = "hmac(sha1)",
2612 .cra_driver_name = "hmac-sha1-talitos",
2613 .cra_blocksize = SHA1_BLOCK_SIZE,
2614 .cra_flags = CRYPTO_ALG_TYPE_AHASH |
2615 CRYPTO_ALG_ASYNC,
Lee Nipper79b3a412011-11-21 16:13:25 +08002616 }
2617 },
2618 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2619 DESC_HDR_SEL0_MDEUA |
2620 DESC_HDR_MODE0_MDEU_SHA1,
2621 },
2622 { .type = CRYPTO_ALG_TYPE_AHASH,
2623 .alg.hash = {
Lee Nipper79b3a412011-11-21 16:13:25 +08002624 .halg.digestsize = SHA224_DIGEST_SIZE,
Horia Geant?3639ca82016-04-21 19:24:55 +03002625 .halg.statesize = sizeof(struct talitos_export_state),
Lee Nipper79b3a412011-11-21 16:13:25 +08002626 .halg.base = {
2627 .cra_name = "hmac(sha224)",
2628 .cra_driver_name = "hmac-sha224-talitos",
2629 .cra_blocksize = SHA224_BLOCK_SIZE,
2630 .cra_flags = CRYPTO_ALG_TYPE_AHASH |
2631 CRYPTO_ALG_ASYNC,
Lee Nipper79b3a412011-11-21 16:13:25 +08002632 }
2633 },
2634 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2635 DESC_HDR_SEL0_MDEUA |
2636 DESC_HDR_MODE0_MDEU_SHA224,
2637 },
2638 { .type = CRYPTO_ALG_TYPE_AHASH,
2639 .alg.hash = {
Lee Nipper79b3a412011-11-21 16:13:25 +08002640 .halg.digestsize = SHA256_DIGEST_SIZE,
Horia Geant?3639ca82016-04-21 19:24:55 +03002641 .halg.statesize = sizeof(struct talitos_export_state),
Lee Nipper79b3a412011-11-21 16:13:25 +08002642 .halg.base = {
2643 .cra_name = "hmac(sha256)",
2644 .cra_driver_name = "hmac-sha256-talitos",
2645 .cra_blocksize = SHA256_BLOCK_SIZE,
2646 .cra_flags = CRYPTO_ALG_TYPE_AHASH |
2647 CRYPTO_ALG_ASYNC,
Lee Nipper79b3a412011-11-21 16:13:25 +08002648 }
2649 },
2650 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2651 DESC_HDR_SEL0_MDEUA |
2652 DESC_HDR_MODE0_MDEU_SHA256,
2653 },
2654 { .type = CRYPTO_ALG_TYPE_AHASH,
2655 .alg.hash = {
Lee Nipper79b3a412011-11-21 16:13:25 +08002656 .halg.digestsize = SHA384_DIGEST_SIZE,
Horia Geant?3639ca82016-04-21 19:24:55 +03002657 .halg.statesize = sizeof(struct talitos_export_state),
Lee Nipper79b3a412011-11-21 16:13:25 +08002658 .halg.base = {
2659 .cra_name = "hmac(sha384)",
2660 .cra_driver_name = "hmac-sha384-talitos",
2661 .cra_blocksize = SHA384_BLOCK_SIZE,
2662 .cra_flags = CRYPTO_ALG_TYPE_AHASH |
2663 CRYPTO_ALG_ASYNC,
Lee Nipper79b3a412011-11-21 16:13:25 +08002664 }
2665 },
2666 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2667 DESC_HDR_SEL0_MDEUB |
2668 DESC_HDR_MODE0_MDEUB_SHA384,
2669 },
2670 { .type = CRYPTO_ALG_TYPE_AHASH,
2671 .alg.hash = {
Lee Nipper79b3a412011-11-21 16:13:25 +08002672 .halg.digestsize = SHA512_DIGEST_SIZE,
Horia Geant?3639ca82016-04-21 19:24:55 +03002673 .halg.statesize = sizeof(struct talitos_export_state),
Lee Nipper79b3a412011-11-21 16:13:25 +08002674 .halg.base = {
2675 .cra_name = "hmac(sha512)",
2676 .cra_driver_name = "hmac-sha512-talitos",
2677 .cra_blocksize = SHA512_BLOCK_SIZE,
2678 .cra_flags = CRYPTO_ALG_TYPE_AHASH |
2679 CRYPTO_ALG_ASYNC,
Lee Nipper79b3a412011-11-21 16:13:25 +08002680 }
2681 },
2682 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2683 DESC_HDR_SEL0_MDEUB |
2684 DESC_HDR_MODE0_MDEUB_SHA512,
2685 }
Kim Phillips9c4a7962008-06-23 19:50:15 +08002686};
2687
2688struct talitos_crypto_alg {
2689 struct list_head entry;
2690 struct device *dev;
Lee Nipperacbf7c622010-05-19 19:19:33 +10002691 struct talitos_alg_template algt;
Kim Phillips9c4a7962008-06-23 19:50:15 +08002692};
2693
2694static int talitos_cra_init(struct crypto_tfm *tfm)
2695{
2696 struct crypto_alg *alg = tfm->__crt_alg;
Kim Phillips19bbbc62009-03-29 15:53:59 +08002697 struct talitos_crypto_alg *talitos_alg;
Kim Phillips9c4a7962008-06-23 19:50:15 +08002698 struct talitos_ctx *ctx = crypto_tfm_ctx(tfm);
Kim Phillips5228f0f2011-07-15 11:21:38 +08002699 struct talitos_private *priv;
Kim Phillips9c4a7962008-06-23 19:50:15 +08002700
Lee Nipper497f2e62010-05-19 19:20:36 +10002701 if ((alg->cra_flags & CRYPTO_ALG_TYPE_MASK) == CRYPTO_ALG_TYPE_AHASH)
2702 talitos_alg = container_of(__crypto_ahash_alg(alg),
2703 struct talitos_crypto_alg,
2704 algt.alg.hash);
2705 else
2706 talitos_alg = container_of(alg, struct talitos_crypto_alg,
2707 algt.alg.crypto);
Kim Phillips19bbbc62009-03-29 15:53:59 +08002708
Kim Phillips9c4a7962008-06-23 19:50:15 +08002709 /* update context with ptr to dev */
2710 ctx->dev = talitos_alg->dev;
Kim Phillips19bbbc62009-03-29 15:53:59 +08002711
Kim Phillips5228f0f2011-07-15 11:21:38 +08002712 /* assign SEC channel to tfm in round-robin fashion */
2713 priv = dev_get_drvdata(ctx->dev);
2714 ctx->ch = atomic_inc_return(&priv->last_chan) &
2715 (priv->num_channels - 1);
2716
Kim Phillips9c4a7962008-06-23 19:50:15 +08002717 /* copy descriptor header template value */
Lee Nipperacbf7c622010-05-19 19:19:33 +10002718 ctx->desc_hdr_template = talitos_alg->algt.desc_hdr_template;
Kim Phillips9c4a7962008-06-23 19:50:15 +08002719
Kim Phillips602dba52011-07-15 11:21:39 +08002720 /* select done notification */
2721 ctx->desc_hdr_template |= DESC_HDR_DONE_NOTIFY;
2722
Lee Nipper497f2e62010-05-19 19:20:36 +10002723 return 0;
2724}
2725
Herbert Xuaeb4c132015-07-30 17:53:22 +08002726static int talitos_cra_init_aead(struct crypto_aead *tfm)
Lee Nipper497f2e62010-05-19 19:20:36 +10002727{
Herbert Xuaeb4c132015-07-30 17:53:22 +08002728 talitos_cra_init(crypto_aead_tfm(tfm));
Kim Phillips9c4a7962008-06-23 19:50:15 +08002729 return 0;
2730}
2731
Lee Nipper497f2e62010-05-19 19:20:36 +10002732static int talitos_cra_init_ahash(struct crypto_tfm *tfm)
2733{
2734 struct talitos_ctx *ctx = crypto_tfm_ctx(tfm);
2735
2736 talitos_cra_init(tfm);
2737
2738 ctx->keylen = 0;
2739 crypto_ahash_set_reqsize(__crypto_ahash_cast(tfm),
2740 sizeof(struct talitos_ahash_req_ctx));
2741
2742 return 0;
2743}
2744
Kim Phillips9c4a7962008-06-23 19:50:15 +08002745/*
2746 * given the alg's descriptor header template, determine whether descriptor
2747 * type and primary/secondary execution units required match the hw
2748 * capabilities description provided in the device tree node.
2749 */
2750static int hw_supports(struct device *dev, __be32 desc_hdr_template)
2751{
2752 struct talitos_private *priv = dev_get_drvdata(dev);
2753 int ret;
2754
2755 ret = (1 << DESC_TYPE(desc_hdr_template) & priv->desc_types) &&
2756 (1 << PRIMARY_EU(desc_hdr_template) & priv->exec_units);
2757
2758 if (SECONDARY_EU(desc_hdr_template))
2759 ret = ret && (1 << SECONDARY_EU(desc_hdr_template)
2760 & priv->exec_units);
2761
2762 return ret;
2763}
2764
Grant Likely2dc11582010-08-06 09:25:50 -06002765static int talitos_remove(struct platform_device *ofdev)
Kim Phillips9c4a7962008-06-23 19:50:15 +08002766{
2767 struct device *dev = &ofdev->dev;
2768 struct talitos_private *priv = dev_get_drvdata(dev);
2769 struct talitos_crypto_alg *t_alg, *n;
2770 int i;
2771
2772 list_for_each_entry_safe(t_alg, n, &priv->alg_list, entry) {
Lee Nipperacbf7c622010-05-19 19:19:33 +10002773 switch (t_alg->algt.type) {
2774 case CRYPTO_ALG_TYPE_ABLKCIPHER:
Lee Nipperacbf7c622010-05-19 19:19:33 +10002775 break;
Herbert Xuaeb4c132015-07-30 17:53:22 +08002776 case CRYPTO_ALG_TYPE_AEAD:
2777 crypto_unregister_aead(&t_alg->algt.alg.aead);
Lee Nipperacbf7c622010-05-19 19:19:33 +10002778 case CRYPTO_ALG_TYPE_AHASH:
2779 crypto_unregister_ahash(&t_alg->algt.alg.hash);
2780 break;
2781 }
Kim Phillips9c4a7962008-06-23 19:50:15 +08002782 list_del(&t_alg->entry);
2783 kfree(t_alg);
2784 }
2785
2786 if (hw_supports(dev, DESC_HDR_SEL0_RNG))
2787 talitos_unregister_rng(dev);
2788
Aaron Sierra35a3bb32015-08-05 16:52:08 -05002789 for (i = 0; priv->chan && i < priv->num_channels; i++)
Kim Phillips0b798242010-09-23 15:56:08 +08002790 kfree(priv->chan[i].fifo);
Kim Phillips9c4a7962008-06-23 19:50:15 +08002791
Kim Phillips4b9926282009-08-13 11:50:38 +10002792 kfree(priv->chan);
Kim Phillips9c4a7962008-06-23 19:50:15 +08002793
Kim Phillipsc3e337f2011-11-21 16:13:27 +08002794 for (i = 0; i < 2; i++)
Kim Phillips2cdba3c2011-12-12 14:59:11 -06002795 if (priv->irq[i]) {
Kim Phillipsc3e337f2011-11-21 16:13:27 +08002796 free_irq(priv->irq[i], dev);
2797 irq_dispose_mapping(priv->irq[i]);
2798 }
Kim Phillips9c4a7962008-06-23 19:50:15 +08002799
Kim Phillipsc3e337f2011-11-21 16:13:27 +08002800 tasklet_kill(&priv->done_task[0]);
Kim Phillips2cdba3c2011-12-12 14:59:11 -06002801 if (priv->irq[1])
Kim Phillipsc3e337f2011-11-21 16:13:27 +08002802 tasklet_kill(&priv->done_task[1]);
Kim Phillips9c4a7962008-06-23 19:50:15 +08002803
2804 iounmap(priv->reg);
2805
Kim Phillips9c4a7962008-06-23 19:50:15 +08002806 kfree(priv);
2807
2808 return 0;
2809}
2810
2811static struct talitos_crypto_alg *talitos_alg_alloc(struct device *dev,
2812 struct talitos_alg_template
2813 *template)
2814{
Kim Phillips60f208d2010-05-19 19:21:53 +10002815 struct talitos_private *priv = dev_get_drvdata(dev);
Kim Phillips9c4a7962008-06-23 19:50:15 +08002816 struct talitos_crypto_alg *t_alg;
2817 struct crypto_alg *alg;
2818
2819 t_alg = kzalloc(sizeof(struct talitos_crypto_alg), GFP_KERNEL);
2820 if (!t_alg)
2821 return ERR_PTR(-ENOMEM);
2822
Lee Nipperacbf7c622010-05-19 19:19:33 +10002823 t_alg->algt = *template;
2824
2825 switch (t_alg->algt.type) {
2826 case CRYPTO_ALG_TYPE_ABLKCIPHER:
Lee Nipper497f2e62010-05-19 19:20:36 +10002827 alg = &t_alg->algt.alg.crypto;
2828 alg->cra_init = talitos_cra_init;
Kim Phillipsd4cd3282012-08-08 20:32:00 -05002829 alg->cra_type = &crypto_ablkcipher_type;
Kim Phillipsb286e002012-08-08 20:33:34 -05002830 alg->cra_ablkcipher.setkey = ablkcipher_setkey;
2831 alg->cra_ablkcipher.encrypt = ablkcipher_encrypt;
2832 alg->cra_ablkcipher.decrypt = ablkcipher_decrypt;
2833 alg->cra_ablkcipher.geniv = "eseqiv";
Lee Nipper497f2e62010-05-19 19:20:36 +10002834 break;
Lee Nipperacbf7c622010-05-19 19:19:33 +10002835 case CRYPTO_ALG_TYPE_AEAD:
Herbert Xuaeb4c132015-07-30 17:53:22 +08002836 alg = &t_alg->algt.alg.aead.base;
Herbert Xuaeb4c132015-07-30 17:53:22 +08002837 t_alg->algt.alg.aead.init = talitos_cra_init_aead;
2838 t_alg->algt.alg.aead.setkey = aead_setkey;
2839 t_alg->algt.alg.aead.encrypt = aead_encrypt;
2840 t_alg->algt.alg.aead.decrypt = aead_decrypt;
Lee Nipperacbf7c622010-05-19 19:19:33 +10002841 break;
2842 case CRYPTO_ALG_TYPE_AHASH:
2843 alg = &t_alg->algt.alg.hash.halg.base;
Lee Nipper497f2e62010-05-19 19:20:36 +10002844 alg->cra_init = talitos_cra_init_ahash;
Kim Phillipsd4cd3282012-08-08 20:32:00 -05002845 alg->cra_type = &crypto_ahash_type;
Kim Phillipsb286e002012-08-08 20:33:34 -05002846 t_alg->algt.alg.hash.init = ahash_init;
2847 t_alg->algt.alg.hash.update = ahash_update;
2848 t_alg->algt.alg.hash.final = ahash_final;
2849 t_alg->algt.alg.hash.finup = ahash_finup;
2850 t_alg->algt.alg.hash.digest = ahash_digest;
2851 t_alg->algt.alg.hash.setkey = ahash_setkey;
Horia Geant?3639ca82016-04-21 19:24:55 +03002852 t_alg->algt.alg.hash.import = ahash_import;
2853 t_alg->algt.alg.hash.export = ahash_export;
Kim Phillipsb286e002012-08-08 20:33:34 -05002854
Lee Nipper79b3a412011-11-21 16:13:25 +08002855 if (!(priv->features & TALITOS_FTR_HMAC_OK) &&
Kim Phillips0b2730d2011-12-12 14:59:10 -06002856 !strncmp(alg->cra_name, "hmac", 4)) {
2857 kfree(t_alg);
Lee Nipper79b3a412011-11-21 16:13:25 +08002858 return ERR_PTR(-ENOTSUPP);
Kim Phillips0b2730d2011-12-12 14:59:10 -06002859 }
Kim Phillips60f208d2010-05-19 19:21:53 +10002860 if (!(priv->features & TALITOS_FTR_SHA224_HWINIT) &&
Lee Nipper79b3a412011-11-21 16:13:25 +08002861 (!strcmp(alg->cra_name, "sha224") ||
2862 !strcmp(alg->cra_name, "hmac(sha224)"))) {
Kim Phillips60f208d2010-05-19 19:21:53 +10002863 t_alg->algt.alg.hash.init = ahash_init_sha224_swinit;
2864 t_alg->algt.desc_hdr_template =
2865 DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2866 DESC_HDR_SEL0_MDEUA |
2867 DESC_HDR_MODE0_MDEU_SHA256;
2868 }
Lee Nipper497f2e62010-05-19 19:20:36 +10002869 break;
Kim Phillips1d119112010-09-23 15:55:27 +08002870 default:
2871 dev_err(dev, "unknown algorithm type %d\n", t_alg->algt.type);
Horia Geant?5fa7dad2015-05-11 20:03:24 +03002872 kfree(t_alg);
Kim Phillips1d119112010-09-23 15:55:27 +08002873 return ERR_PTR(-EINVAL);
Lee Nipperacbf7c622010-05-19 19:19:33 +10002874 }
Kim Phillips9c4a7962008-06-23 19:50:15 +08002875
Kim Phillips9c4a7962008-06-23 19:50:15 +08002876 alg->cra_module = THIS_MODULE;
Kim Phillips9c4a7962008-06-23 19:50:15 +08002877 alg->cra_priority = TALITOS_CRA_PRIORITY;
Kim Phillips9c4a7962008-06-23 19:50:15 +08002878 alg->cra_alignmask = 0;
Kim Phillips9c4a7962008-06-23 19:50:15 +08002879 alg->cra_ctxsize = sizeof(struct talitos_ctx);
Nikos Mavrogiannopoulosd912bb72011-11-01 13:39:56 +01002880 alg->cra_flags |= CRYPTO_ALG_KERN_DRIVER_ONLY;
Kim Phillips9c4a7962008-06-23 19:50:15 +08002881
Kim Phillips9c4a7962008-06-23 19:50:15 +08002882 t_alg->dev = dev;
2883
2884 return t_alg;
2885}
2886
Kim Phillipsc3e337f2011-11-21 16:13:27 +08002887static int talitos_probe_irq(struct platform_device *ofdev)
2888{
2889 struct device *dev = &ofdev->dev;
2890 struct device_node *np = ofdev->dev.of_node;
2891 struct talitos_private *priv = dev_get_drvdata(dev);
2892 int err;
LEROY Christophedd3c0982015-04-17 16:32:13 +02002893 bool is_sec1 = has_ftr_sec1(priv);
Kim Phillipsc3e337f2011-11-21 16:13:27 +08002894
2895 priv->irq[0] = irq_of_parse_and_map(np, 0);
Kim Phillips2cdba3c2011-12-12 14:59:11 -06002896 if (!priv->irq[0]) {
Kim Phillipsc3e337f2011-11-21 16:13:27 +08002897 dev_err(dev, "failed to map irq\n");
2898 return -EINVAL;
2899 }
LEROY Christophedd3c0982015-04-17 16:32:13 +02002900 if (is_sec1) {
2901 err = request_irq(priv->irq[0], talitos1_interrupt_4ch, 0,
2902 dev_driver_string(dev), dev);
2903 goto primary_out;
2904 }
Kim Phillipsc3e337f2011-11-21 16:13:27 +08002905
2906 priv->irq[1] = irq_of_parse_and_map(np, 1);
2907
2908 /* get the primary irq line */
Kim Phillips2cdba3c2011-12-12 14:59:11 -06002909 if (!priv->irq[1]) {
LEROY Christophedd3c0982015-04-17 16:32:13 +02002910 err = request_irq(priv->irq[0], talitos2_interrupt_4ch, 0,
Kim Phillipsc3e337f2011-11-21 16:13:27 +08002911 dev_driver_string(dev), dev);
2912 goto primary_out;
2913 }
2914
LEROY Christophedd3c0982015-04-17 16:32:13 +02002915 err = request_irq(priv->irq[0], talitos2_interrupt_ch0_2, 0,
Kim Phillipsc3e337f2011-11-21 16:13:27 +08002916 dev_driver_string(dev), dev);
2917 if (err)
2918 goto primary_out;
2919
2920 /* get the secondary irq line */
LEROY Christophedd3c0982015-04-17 16:32:13 +02002921 err = request_irq(priv->irq[1], talitos2_interrupt_ch1_3, 0,
Kim Phillipsc3e337f2011-11-21 16:13:27 +08002922 dev_driver_string(dev), dev);
2923 if (err) {
2924 dev_err(dev, "failed to request secondary irq\n");
2925 irq_dispose_mapping(priv->irq[1]);
Kim Phillips2cdba3c2011-12-12 14:59:11 -06002926 priv->irq[1] = 0;
Kim Phillipsc3e337f2011-11-21 16:13:27 +08002927 }
2928
2929 return err;
2930
2931primary_out:
2932 if (err) {
2933 dev_err(dev, "failed to request primary irq\n");
2934 irq_dispose_mapping(priv->irq[0]);
Kim Phillips2cdba3c2011-12-12 14:59:11 -06002935 priv->irq[0] = 0;
Kim Phillipsc3e337f2011-11-21 16:13:27 +08002936 }
2937
2938 return err;
2939}
2940
Grant Likely1c48a5c2011-02-17 02:43:24 -07002941static int talitos_probe(struct platform_device *ofdev)
Kim Phillips9c4a7962008-06-23 19:50:15 +08002942{
2943 struct device *dev = &ofdev->dev;
Grant Likely61c7a082010-04-13 16:12:29 -07002944 struct device_node *np = ofdev->dev.of_node;
Kim Phillips9c4a7962008-06-23 19:50:15 +08002945 struct talitos_private *priv;
2946 const unsigned int *prop;
2947 int i, err;
LEROY Christophe5fa7fa12015-04-17 16:32:11 +02002948 int stride;
Kim Phillips9c4a7962008-06-23 19:50:15 +08002949
2950 priv = kzalloc(sizeof(struct talitos_private), GFP_KERNEL);
2951 if (!priv)
2952 return -ENOMEM;
2953
Kevin Haof3de9cb2014-01-28 20:17:23 +08002954 INIT_LIST_HEAD(&priv->alg_list);
2955
Kim Phillips9c4a7962008-06-23 19:50:15 +08002956 dev_set_drvdata(dev, priv);
2957
2958 priv->ofdev = ofdev;
2959
Horia Geanta511d63c2012-03-30 17:49:53 +03002960 spin_lock_init(&priv->reg_lock);
2961
Kim Phillips9c4a7962008-06-23 19:50:15 +08002962 priv->reg = of_iomap(np, 0);
2963 if (!priv->reg) {
2964 dev_err(dev, "failed to of_iomap\n");
2965 err = -ENOMEM;
2966 goto err_out;
2967 }
2968
2969 /* get SEC version capabilities from device tree */
2970 prop = of_get_property(np, "fsl,num-channels", NULL);
2971 if (prop)
2972 priv->num_channels = *prop;
2973
2974 prop = of_get_property(np, "fsl,channel-fifo-len", NULL);
2975 if (prop)
2976 priv->chfifo_len = *prop;
2977
2978 prop = of_get_property(np, "fsl,exec-units-mask", NULL);
2979 if (prop)
2980 priv->exec_units = *prop;
2981
2982 prop = of_get_property(np, "fsl,descriptor-types-mask", NULL);
2983 if (prop)
2984 priv->desc_types = *prop;
2985
2986 if (!is_power_of_2(priv->num_channels) || !priv->chfifo_len ||
2987 !priv->exec_units || !priv->desc_types) {
2988 dev_err(dev, "invalid property data in device tree node\n");
2989 err = -EINVAL;
2990 goto err_out;
2991 }
2992
Lee Nipperf3c85bc2008-07-30 16:26:57 +08002993 if (of_device_is_compatible(np, "fsl,sec3.0"))
2994 priv->features |= TALITOS_FTR_SRC_LINK_TBL_LEN_INCLUDES_EXTENT;
2995
Kim Phillipsfe5720e2008-10-12 20:33:14 +08002996 if (of_device_is_compatible(np, "fsl,sec2.1"))
Kim Phillips60f208d2010-05-19 19:21:53 +10002997 priv->features |= TALITOS_FTR_HW_AUTH_CHECK |
Lee Nipper79b3a412011-11-21 16:13:25 +08002998 TALITOS_FTR_SHA224_HWINIT |
2999 TALITOS_FTR_HMAC_OK;
Kim Phillipsfe5720e2008-10-12 20:33:14 +08003000
LEROY Christophe21590882015-04-17 16:32:05 +02003001 if (of_device_is_compatible(np, "fsl,sec1.0"))
3002 priv->features |= TALITOS_FTR_SEC1;
3003
LEROY Christophe5fa7fa12015-04-17 16:32:11 +02003004 if (of_device_is_compatible(np, "fsl,sec1.2")) {
3005 priv->reg_deu = priv->reg + TALITOS12_DEU;
3006 priv->reg_aesu = priv->reg + TALITOS12_AESU;
3007 priv->reg_mdeu = priv->reg + TALITOS12_MDEU;
3008 stride = TALITOS1_CH_STRIDE;
3009 } else if (of_device_is_compatible(np, "fsl,sec1.0")) {
3010 priv->reg_deu = priv->reg + TALITOS10_DEU;
3011 priv->reg_aesu = priv->reg + TALITOS10_AESU;
3012 priv->reg_mdeu = priv->reg + TALITOS10_MDEU;
3013 priv->reg_afeu = priv->reg + TALITOS10_AFEU;
3014 priv->reg_rngu = priv->reg + TALITOS10_RNGU;
3015 priv->reg_pkeu = priv->reg + TALITOS10_PKEU;
3016 stride = TALITOS1_CH_STRIDE;
3017 } else {
3018 priv->reg_deu = priv->reg + TALITOS2_DEU;
3019 priv->reg_aesu = priv->reg + TALITOS2_AESU;
3020 priv->reg_mdeu = priv->reg + TALITOS2_MDEU;
3021 priv->reg_afeu = priv->reg + TALITOS2_AFEU;
3022 priv->reg_rngu = priv->reg + TALITOS2_RNGU;
3023 priv->reg_pkeu = priv->reg + TALITOS2_PKEU;
3024 priv->reg_keu = priv->reg + TALITOS2_KEU;
3025 priv->reg_crcu = priv->reg + TALITOS2_CRCU;
3026 stride = TALITOS2_CH_STRIDE;
3027 }
3028
LEROY Christophedd3c0982015-04-17 16:32:13 +02003029 err = talitos_probe_irq(ofdev);
3030 if (err)
3031 goto err_out;
3032
3033 if (of_device_is_compatible(np, "fsl,sec1.0")) {
3034 tasklet_init(&priv->done_task[0], talitos1_done_4ch,
3035 (unsigned long)dev);
3036 } else {
3037 if (!priv->irq[1]) {
3038 tasklet_init(&priv->done_task[0], talitos2_done_4ch,
3039 (unsigned long)dev);
3040 } else {
3041 tasklet_init(&priv->done_task[0], talitos2_done_ch0_2,
3042 (unsigned long)dev);
3043 tasklet_init(&priv->done_task[1], talitos2_done_ch1_3,
3044 (unsigned long)dev);
3045 }
3046 }
3047
Kim Phillips4b9926282009-08-13 11:50:38 +10003048 priv->chan = kzalloc(sizeof(struct talitos_channel) *
3049 priv->num_channels, GFP_KERNEL);
3050 if (!priv->chan) {
3051 dev_err(dev, "failed to allocate channel management space\n");
Kim Phillips9c4a7962008-06-23 19:50:15 +08003052 err = -ENOMEM;
3053 goto err_out;
3054 }
3055
Martin Hicksf641ddd2015-03-03 08:21:33 -05003056 priv->fifo_len = roundup_pow_of_two(priv->chfifo_len);
3057
Kim Phillipsc3e337f2011-11-21 16:13:27 +08003058 for (i = 0; i < priv->num_channels; i++) {
LEROY Christophe5fa7fa12015-04-17 16:32:11 +02003059 priv->chan[i].reg = priv->reg + stride * (i + 1);
Kim Phillips2cdba3c2011-12-12 14:59:11 -06003060 if (!priv->irq[1] || !(i & 1))
Kim Phillipsc3e337f2011-11-21 16:13:27 +08003061 priv->chan[i].reg += TALITOS_CH_BASE_OFFSET;
Kim Phillipsad42d5f2011-11-21 16:13:27 +08003062
Kim Phillips4b9926282009-08-13 11:50:38 +10003063 spin_lock_init(&priv->chan[i].head_lock);
3064 spin_lock_init(&priv->chan[i].tail_lock);
Kim Phillips9c4a7962008-06-23 19:50:15 +08003065
Kim Phillips4b9926282009-08-13 11:50:38 +10003066 priv->chan[i].fifo = kzalloc(sizeof(struct talitos_request) *
3067 priv->fifo_len, GFP_KERNEL);
3068 if (!priv->chan[i].fifo) {
Kim Phillips9c4a7962008-06-23 19:50:15 +08003069 dev_err(dev, "failed to allocate request fifo %d\n", i);
3070 err = -ENOMEM;
3071 goto err_out;
3072 }
Kim Phillips9c4a7962008-06-23 19:50:15 +08003073
Kim Phillips4b9926282009-08-13 11:50:38 +10003074 atomic_set(&priv->chan[i].submit_count,
3075 -(priv->chfifo_len - 1));
Martin Hicksf641ddd2015-03-03 08:21:33 -05003076 }
Kim Phillips9c4a7962008-06-23 19:50:15 +08003077
Kim Phillips81eb0242009-08-13 11:51:51 +10003078 dma_set_mask(dev, DMA_BIT_MASK(36));
3079
Kim Phillips9c4a7962008-06-23 19:50:15 +08003080 /* reset and initialize the h/w */
3081 err = init_device(dev);
3082 if (err) {
3083 dev_err(dev, "failed to initialize device\n");
3084 goto err_out;
3085 }
3086
3087 /* register the RNG, if available */
3088 if (hw_supports(dev, DESC_HDR_SEL0_RNG)) {
3089 err = talitos_register_rng(dev);
3090 if (err) {
3091 dev_err(dev, "failed to register hwrng: %d\n", err);
3092 goto err_out;
3093 } else
3094 dev_info(dev, "hwrng\n");
3095 }
3096
3097 /* register crypto algorithms the device supports */
Kim Phillips9c4a7962008-06-23 19:50:15 +08003098 for (i = 0; i < ARRAY_SIZE(driver_algs); i++) {
3099 if (hw_supports(dev, driver_algs[i].desc_hdr_template)) {
3100 struct talitos_crypto_alg *t_alg;
Herbert Xuaeb4c132015-07-30 17:53:22 +08003101 struct crypto_alg *alg = NULL;
Kim Phillips9c4a7962008-06-23 19:50:15 +08003102
3103 t_alg = talitos_alg_alloc(dev, &driver_algs[i]);
3104 if (IS_ERR(t_alg)) {
3105 err = PTR_ERR(t_alg);
Kim Phillips0b2730d2011-12-12 14:59:10 -06003106 if (err == -ENOTSUPP)
Lee Nipper79b3a412011-11-21 16:13:25 +08003107 continue;
Kim Phillips9c4a7962008-06-23 19:50:15 +08003108 goto err_out;
3109 }
3110
Lee Nipperacbf7c622010-05-19 19:19:33 +10003111 switch (t_alg->algt.type) {
3112 case CRYPTO_ALG_TYPE_ABLKCIPHER:
Lee Nipperacbf7c622010-05-19 19:19:33 +10003113 err = crypto_register_alg(
3114 &t_alg->algt.alg.crypto);
Herbert Xuaeb4c132015-07-30 17:53:22 +08003115 alg = &t_alg->algt.alg.crypto;
Lee Nipperacbf7c622010-05-19 19:19:33 +10003116 break;
Herbert Xuaeb4c132015-07-30 17:53:22 +08003117
3118 case CRYPTO_ALG_TYPE_AEAD:
3119 err = crypto_register_aead(
3120 &t_alg->algt.alg.aead);
3121 alg = &t_alg->algt.alg.aead.base;
3122 break;
3123
Lee Nipperacbf7c622010-05-19 19:19:33 +10003124 case CRYPTO_ALG_TYPE_AHASH:
3125 err = crypto_register_ahash(
3126 &t_alg->algt.alg.hash);
Herbert Xuaeb4c132015-07-30 17:53:22 +08003127 alg = &t_alg->algt.alg.hash.halg.base;
Lee Nipperacbf7c622010-05-19 19:19:33 +10003128 break;
3129 }
Kim Phillips9c4a7962008-06-23 19:50:15 +08003130 if (err) {
3131 dev_err(dev, "%s alg registration failed\n",
Herbert Xuaeb4c132015-07-30 17:53:22 +08003132 alg->cra_driver_name);
Kim Phillips9c4a7962008-06-23 19:50:15 +08003133 kfree(t_alg);
Horia Geanta991155b2013-03-20 16:31:38 +02003134 } else
Kim Phillips9c4a7962008-06-23 19:50:15 +08003135 list_add_tail(&t_alg->entry, &priv->alg_list);
Kim Phillips9c4a7962008-06-23 19:50:15 +08003136 }
3137 }
Kim Phillips5b859b6e2011-11-21 16:13:26 +08003138 if (!list_empty(&priv->alg_list))
3139 dev_info(dev, "%s algorithms registered in /proc/crypto\n",
3140 (char *)of_get_property(np, "compatible", NULL));
Kim Phillips9c4a7962008-06-23 19:50:15 +08003141
3142 return 0;
3143
3144err_out:
3145 talitos_remove(ofdev);
Kim Phillips9c4a7962008-06-23 19:50:15 +08003146
3147 return err;
3148}
3149
Márton Németh6c3f9752010-01-17 21:54:01 +11003150static const struct of_device_id talitos_match[] = {
LEROY Christophe0635b7d2015-04-17 16:32:20 +02003151#ifdef CONFIG_CRYPTO_DEV_TALITOS1
3152 {
3153 .compatible = "fsl,sec1.0",
3154 },
3155#endif
3156#ifdef CONFIG_CRYPTO_DEV_TALITOS2
Kim Phillips9c4a7962008-06-23 19:50:15 +08003157 {
3158 .compatible = "fsl,sec2.0",
3159 },
LEROY Christophe0635b7d2015-04-17 16:32:20 +02003160#endif
Kim Phillips9c4a7962008-06-23 19:50:15 +08003161 {},
3162};
3163MODULE_DEVICE_TABLE(of, talitos_match);
3164
Grant Likely1c48a5c2011-02-17 02:43:24 -07003165static struct platform_driver talitos_driver = {
Grant Likely40182942010-04-13 16:13:02 -07003166 .driver = {
3167 .name = "talitos",
Grant Likely40182942010-04-13 16:13:02 -07003168 .of_match_table = talitos_match,
3169 },
Kim Phillips9c4a7962008-06-23 19:50:15 +08003170 .probe = talitos_probe,
Al Viro596f1032008-11-22 17:34:24 +00003171 .remove = talitos_remove,
Kim Phillips9c4a7962008-06-23 19:50:15 +08003172};
3173
Axel Lin741e8c22011-11-26 21:26:19 +08003174module_platform_driver(talitos_driver);
Kim Phillips9c4a7962008-06-23 19:50:15 +08003175
3176MODULE_LICENSE("GPL");
3177MODULE_AUTHOR("Kim Phillips <kim.phillips@freescale.com>");
3178MODULE_DESCRIPTION("Freescale integrated security engine (SEC) driver");