11a59d1b8SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
29c4a7965SKim Phillips /*
39c4a7965SKim Phillips * talitos - Freescale Integrated Security Engine (SEC) device driver
49c4a7965SKim Phillips *
55228f0f7SKim Phillips * Copyright (c) 2008-2011 Freescale Semiconductor, Inc.
69c4a7965SKim Phillips *
79c4a7965SKim Phillips * Scatterlist Crypto API glue code copied from files with the following:
89c4a7965SKim Phillips * Copyright (c) 2006-2007 Herbert Xu <herbert@gondor.apana.org.au>
99c4a7965SKim Phillips *
109c4a7965SKim Phillips * Crypto algorithm registration code copied from hifn driver:
119c4a7965SKim Phillips * 2007+ Copyright (c) Evgeniy Polyakov <johnpol@2ka.mipt.ru>
129c4a7965SKim Phillips * All rights reserved.
139c4a7965SKim Phillips */
149c4a7965SKim Phillips
159c4a7965SKim Phillips #include <linux/kernel.h>
169c4a7965SKim Phillips #include <linux/module.h>
179c4a7965SKim Phillips #include <linux/mod_devicetable.h>
189c4a7965SKim Phillips #include <linux/device.h>
199c4a7965SKim Phillips #include <linux/interrupt.h>
209c4a7965SKim Phillips #include <linux/crypto.h>
219c4a7965SKim Phillips #include <linux/hw_random.h>
22b0cc7491SRob Herring #include <linux/of.h>
235af50730SRob Herring #include <linux/of_irq.h>
24b0cc7491SRob Herring #include <linux/platform_device.h>
259c4a7965SKim Phillips #include <linux/dma-mapping.h>
269c4a7965SKim Phillips #include <linux/io.h>
279c4a7965SKim Phillips #include <linux/spinlock.h>
289c4a7965SKim Phillips #include <linux/rtnetlink.h>
295a0e3ad6STejun Heo #include <linux/slab.h>
309c4a7965SKim Phillips
319c4a7965SKim Phillips #include <crypto/algapi.h>
329c4a7965SKim Phillips #include <crypto/aes.h>
339d574ae8SArd Biesheuvel #include <crypto/internal/des.h>
34a24d22b2SEric Biggers #include <crypto/sha1.h>
35a24d22b2SEric Biggers #include <crypto/sha2.h>
36497f2e6bSLee Nipper #include <crypto/md5.h>
37e98014abSHerbert Xu #include <crypto/internal/aead.h>
389c4a7965SKim Phillips #include <crypto/authenc.h>
39373960d7SArd Biesheuvel #include <crypto/internal/skcipher.h>
40acbf7c62SLee Nipper #include <crypto/hash.h>
41acbf7c62SLee Nipper #include <crypto/internal/hash.h>
424de9d0b5SLee Nipper #include <crypto/scatterwalk.h>
439c4a7965SKim Phillips
449c4a7965SKim Phillips #include "talitos.h"
459c4a7965SKim Phillips
to_talitos_ptr(struct talitos_ptr * ptr,dma_addr_t dma_addr,unsigned int len,bool is_sec1)46922f9dc8SLEROY Christophe static void to_talitos_ptr(struct talitos_ptr *ptr, dma_addr_t dma_addr,
47da9de146SLEROY Christophe unsigned int len, bool is_sec1)
4881eb024cSKim Phillips {
49edc6bd69SLEROY Christophe ptr->ptr = cpu_to_be32(lower_32_bits(dma_addr));
50da9de146SLEROY Christophe if (is_sec1) {
51da9de146SLEROY Christophe ptr->len1 = cpu_to_be16(len);
52da9de146SLEROY Christophe } else {
53da9de146SLEROY Christophe ptr->len = cpu_to_be16(len);
54edc6bd69SLEROY Christophe ptr->eptr = upper_32_bits(dma_addr);
5581eb024cSKim Phillips }
56da9de146SLEROY Christophe }
5781eb024cSKim Phillips
copy_talitos_ptr(struct talitos_ptr * dst_ptr,struct talitos_ptr * src_ptr,bool is_sec1)58340ff60aSHoria Geant? static void copy_talitos_ptr(struct talitos_ptr *dst_ptr,
59340ff60aSHoria Geant? struct talitos_ptr *src_ptr, bool is_sec1)
60340ff60aSHoria Geant? {
61340ff60aSHoria Geant? dst_ptr->ptr = src_ptr->ptr;
62922f9dc8SLEROY Christophe if (is_sec1) {
63da9de146SLEROY Christophe dst_ptr->len1 = src_ptr->len1;
64922f9dc8SLEROY Christophe } else {
65da9de146SLEROY Christophe dst_ptr->len = src_ptr->len;
66da9de146SLEROY Christophe dst_ptr->eptr = src_ptr->eptr;
67538caf83SLEROY Christophe }
68922f9dc8SLEROY Christophe }
69538caf83SLEROY Christophe
from_talitos_ptr_len(struct talitos_ptr * ptr,bool is_sec1)70922f9dc8SLEROY Christophe static unsigned short from_talitos_ptr_len(struct talitos_ptr *ptr,
71922f9dc8SLEROY Christophe bool is_sec1)
72538caf83SLEROY Christophe {
73922f9dc8SLEROY Christophe if (is_sec1)
74922f9dc8SLEROY Christophe return be16_to_cpu(ptr->len1);
75922f9dc8SLEROY Christophe else
76538caf83SLEROY Christophe return be16_to_cpu(ptr->len);
77538caf83SLEROY Christophe }
78538caf83SLEROY Christophe
to_talitos_ptr_ext_set(struct talitos_ptr * ptr,u8 val,bool is_sec1)79b096b544SLEROY Christophe static void to_talitos_ptr_ext_set(struct talitos_ptr *ptr, u8 val,
80b096b544SLEROY Christophe bool is_sec1)
81185eb79fSLEROY Christophe {
82922f9dc8SLEROY Christophe if (!is_sec1)
83b096b544SLEROY Christophe ptr->j_extent = val;
84b096b544SLEROY Christophe }
85b096b544SLEROY Christophe
to_talitos_ptr_ext_or(struct talitos_ptr * ptr,u8 val,bool is_sec1)86b096b544SLEROY Christophe static void to_talitos_ptr_ext_or(struct talitos_ptr *ptr, u8 val, bool is_sec1)
87b096b544SLEROY Christophe {
88b096b544SLEROY Christophe if (!is_sec1)
89b096b544SLEROY Christophe ptr->j_extent |= val;
90185eb79fSLEROY Christophe }
91185eb79fSLEROY Christophe
929c4a7965SKim Phillips /*
939c4a7965SKim Phillips * map virtual single (contiguous) pointer to h/w descriptor pointer
949c4a7965SKim Phillips */
__map_single_talitos_ptr(struct device * dev,struct talitos_ptr * ptr,unsigned int len,void * data,enum dma_data_direction dir,unsigned long attrs)956a4967c3SLEROY Christophe static void __map_single_talitos_ptr(struct device *dev,
966a4967c3SLEROY Christophe struct talitos_ptr *ptr,
976a4967c3SLEROY Christophe unsigned int len, void *data,
986a4967c3SLEROY Christophe enum dma_data_direction dir,
996a4967c3SLEROY Christophe unsigned long attrs)
1006a4967c3SLEROY Christophe {
1016a4967c3SLEROY Christophe dma_addr_t dma_addr = dma_map_single_attrs(dev, data, len, dir, attrs);
1026a4967c3SLEROY Christophe struct talitos_private *priv = dev_get_drvdata(dev);
1036a4967c3SLEROY Christophe bool is_sec1 = has_ftr_sec1(priv);
1046a4967c3SLEROY Christophe
1056a4967c3SLEROY Christophe to_talitos_ptr(ptr, dma_addr, len, is_sec1);
1066a4967c3SLEROY Christophe }
1076a4967c3SLEROY Christophe
map_single_talitos_ptr(struct device * dev,struct talitos_ptr * ptr,unsigned int len,void * data,enum dma_data_direction dir)1089c4a7965SKim Phillips static void map_single_talitos_ptr(struct device *dev,
109edc6bd69SLEROY Christophe struct talitos_ptr *ptr,
11042e8b0d7SHoria Geant? unsigned int len, void *data,
1119c4a7965SKim Phillips enum dma_data_direction dir)
1129c4a7965SKim Phillips {
1136a4967c3SLEROY Christophe __map_single_talitos_ptr(dev, ptr, len, data, dir, 0);
1146a4967c3SLEROY Christophe }
11581eb024cSKim Phillips
map_single_talitos_ptr_nosync(struct device * dev,struct talitos_ptr * ptr,unsigned int len,void * data,enum dma_data_direction dir)1166a4967c3SLEROY Christophe static void map_single_talitos_ptr_nosync(struct device *dev,
1176a4967c3SLEROY Christophe struct talitos_ptr *ptr,
1186a4967c3SLEROY Christophe unsigned int len, void *data,
1196a4967c3SLEROY Christophe enum dma_data_direction dir)
1206a4967c3SLEROY Christophe {
1216a4967c3SLEROY Christophe __map_single_talitos_ptr(dev, ptr, len, data, dir,
1226a4967c3SLEROY Christophe DMA_ATTR_SKIP_CPU_SYNC);
1239c4a7965SKim Phillips }
1249c4a7965SKim Phillips
1259c4a7965SKim Phillips /*
1269c4a7965SKim Phillips * unmap bus single (contiguous) h/w descriptor pointer
1279c4a7965SKim Phillips */
unmap_single_talitos_ptr(struct device * dev,struct talitos_ptr * ptr,enum dma_data_direction dir)1289c4a7965SKim Phillips static void unmap_single_talitos_ptr(struct device *dev,
129edc6bd69SLEROY Christophe struct talitos_ptr *ptr,
1309c4a7965SKim Phillips enum dma_data_direction dir)
1319c4a7965SKim Phillips {
132922f9dc8SLEROY Christophe struct talitos_private *priv = dev_get_drvdata(dev);
133922f9dc8SLEROY Christophe bool is_sec1 = has_ftr_sec1(priv);
134922f9dc8SLEROY Christophe
135edc6bd69SLEROY Christophe dma_unmap_single(dev, be32_to_cpu(ptr->ptr),
136922f9dc8SLEROY Christophe from_talitos_ptr_len(ptr, is_sec1), dir);
1379c4a7965SKim Phillips }
1389c4a7965SKim Phillips
reset_channel(struct device * dev,int ch)1399c4a7965SKim Phillips static int reset_channel(struct device *dev, int ch)
1409c4a7965SKim Phillips {
1419c4a7965SKim Phillips struct talitos_private *priv = dev_get_drvdata(dev);
1429c4a7965SKim Phillips unsigned int timeout = TALITOS_TIMEOUT;
143dd3c0987SLEROY Christophe bool is_sec1 = has_ftr_sec1(priv);
1449c4a7965SKim Phillips
145dd3c0987SLEROY Christophe if (is_sec1) {
146dd3c0987SLEROY Christophe setbits32(priv->chan[ch].reg + TALITOS_CCCR_LO,
147dd3c0987SLEROY Christophe TALITOS1_CCCR_LO_RESET);
1489c4a7965SKim Phillips
149dd3c0987SLEROY Christophe while ((in_be32(priv->chan[ch].reg + TALITOS_CCCR_LO) &
150dd3c0987SLEROY Christophe TALITOS1_CCCR_LO_RESET) && --timeout)
1519c4a7965SKim Phillips cpu_relax();
152dd3c0987SLEROY Christophe } else {
153dd3c0987SLEROY Christophe setbits32(priv->chan[ch].reg + TALITOS_CCCR,
154dd3c0987SLEROY Christophe TALITOS2_CCCR_RESET);
155dd3c0987SLEROY Christophe
156dd3c0987SLEROY Christophe while ((in_be32(priv->chan[ch].reg + TALITOS_CCCR) &
157dd3c0987SLEROY Christophe TALITOS2_CCCR_RESET) && --timeout)
158dd3c0987SLEROY Christophe cpu_relax();
159dd3c0987SLEROY Christophe }
1609c4a7965SKim Phillips
1619c4a7965SKim Phillips if (timeout == 0) {
1629c4a7965SKim Phillips dev_err(dev, "failed to reset channel %d\n", ch);
1639c4a7965SKim Phillips return -EIO;
1649c4a7965SKim Phillips }
1659c4a7965SKim Phillips
16681eb024cSKim Phillips /* set 36-bit addressing, done writeback enable and done IRQ enable */
167ad42d5fcSKim Phillips setbits32(priv->chan[ch].reg + TALITOS_CCCR_LO, TALITOS_CCCR_LO_EAE |
16881eb024cSKim Phillips TALITOS_CCCR_LO_CDWE | TALITOS_CCCR_LO_CDIE);
16937b5e889SLEROY Christophe /* enable chaining descriptors */
17037b5e889SLEROY Christophe if (is_sec1)
17137b5e889SLEROY Christophe setbits32(priv->chan[ch].reg + TALITOS_CCCR_LO,
17237b5e889SLEROY Christophe TALITOS_CCCR_LO_NE);
1739c4a7965SKim Phillips
174fe5720e2SKim Phillips /* and ICCR writeback, if available */
175fe5720e2SKim Phillips if (priv->features & TALITOS_FTR_HW_AUTH_CHECK)
176ad42d5fcSKim Phillips setbits32(priv->chan[ch].reg + TALITOS_CCCR_LO,
177fe5720e2SKim Phillips TALITOS_CCCR_LO_IWSE);
178fe5720e2SKim Phillips
1799c4a7965SKim Phillips return 0;
1809c4a7965SKim Phillips }
1819c4a7965SKim Phillips
reset_device(struct device * dev)1829c4a7965SKim Phillips static int reset_device(struct device *dev)
1839c4a7965SKim Phillips {
1849c4a7965SKim Phillips struct talitos_private *priv = dev_get_drvdata(dev);
1859c4a7965SKim Phillips unsigned int timeout = TALITOS_TIMEOUT;
186dd3c0987SLEROY Christophe bool is_sec1 = has_ftr_sec1(priv);
187dd3c0987SLEROY Christophe u32 mcr = is_sec1 ? TALITOS1_MCR_SWR : TALITOS2_MCR_SWR;
1889c4a7965SKim Phillips
189c3e337f8SKim Phillips setbits32(priv->reg + TALITOS_MCR, mcr);
1909c4a7965SKim Phillips
191dd3c0987SLEROY Christophe while ((in_be32(priv->reg + TALITOS_MCR) & mcr)
1929c4a7965SKim Phillips && --timeout)
1939c4a7965SKim Phillips cpu_relax();
1949c4a7965SKim Phillips
1952cdba3cfSKim Phillips if (priv->irq[1]) {
196c3e337f8SKim Phillips mcr = TALITOS_MCR_RCA1 | TALITOS_MCR_RCA3;
197c3e337f8SKim Phillips setbits32(priv->reg + TALITOS_MCR, mcr);
198c3e337f8SKim Phillips }
199c3e337f8SKim Phillips
2009c4a7965SKim Phillips if (timeout == 0) {
2019c4a7965SKim Phillips dev_err(dev, "failed to reset device\n");
2029c4a7965SKim Phillips return -EIO;
2039c4a7965SKim Phillips }
2049c4a7965SKim Phillips
2059c4a7965SKim Phillips return 0;
2069c4a7965SKim Phillips }
2079c4a7965SKim Phillips
2089c4a7965SKim Phillips /*
2099c4a7965SKim Phillips * Reset and initialize the device
2109c4a7965SKim Phillips */
init_device(struct device * dev)2119c4a7965SKim Phillips static int init_device(struct device *dev)
2129c4a7965SKim Phillips {
2139c4a7965SKim Phillips struct talitos_private *priv = dev_get_drvdata(dev);
2149c4a7965SKim Phillips int ch, err;
215dd3c0987SLEROY Christophe bool is_sec1 = has_ftr_sec1(priv);
2169c4a7965SKim Phillips
2179c4a7965SKim Phillips /*
2189c4a7965SKim Phillips * Master reset
2199c4a7965SKim Phillips * errata documentation: warning: certain SEC interrupts
2209c4a7965SKim Phillips * are not fully cleared by writing the MCR:SWR bit,
2219c4a7965SKim Phillips * set bit twice to completely reset
2229c4a7965SKim Phillips */
2239c4a7965SKim Phillips err = reset_device(dev);
2249c4a7965SKim Phillips if (err)
2259c4a7965SKim Phillips return err;
2269c4a7965SKim Phillips
2279c4a7965SKim Phillips err = reset_device(dev);
2289c4a7965SKim Phillips if (err)
2299c4a7965SKim Phillips return err;
2309c4a7965SKim Phillips
2319c4a7965SKim Phillips /* reset channels */
2329c4a7965SKim Phillips for (ch = 0; ch < priv->num_channels; ch++) {
2339c4a7965SKim Phillips err = reset_channel(dev, ch);
2349c4a7965SKim Phillips if (err)
2359c4a7965SKim Phillips return err;
2369c4a7965SKim Phillips }
2379c4a7965SKim Phillips
2389c4a7965SKim Phillips /* enable channel done and error interrupts */
239dd3c0987SLEROY Christophe if (is_sec1) {
240dd3c0987SLEROY Christophe clrbits32(priv->reg + TALITOS_IMR, TALITOS1_IMR_INIT);
241dd3c0987SLEROY Christophe clrbits32(priv->reg + TALITOS_IMR_LO, TALITOS1_IMR_LO_INIT);
242dd3c0987SLEROY Christophe /* disable parity error check in DEU (erroneous? test vect.) */
243dd3c0987SLEROY Christophe setbits32(priv->reg_deu + TALITOS_EUICR, TALITOS1_DEUICR_KPE);
244dd3c0987SLEROY Christophe } else {
245dd3c0987SLEROY Christophe setbits32(priv->reg + TALITOS_IMR, TALITOS2_IMR_INIT);
246dd3c0987SLEROY Christophe setbits32(priv->reg + TALITOS_IMR_LO, TALITOS2_IMR_LO_INIT);
247dd3c0987SLEROY Christophe }
2489c4a7965SKim Phillips
249fe5720e2SKim Phillips /* disable integrity check error interrupts (use writeback instead) */
250fe5720e2SKim Phillips if (priv->features & TALITOS_FTR_HW_AUTH_CHECK)
2515fa7fa14SLEROY Christophe setbits32(priv->reg_mdeu + TALITOS_EUICR_LO,
252fe5720e2SKim Phillips TALITOS_MDEUICR_LO_ICE);
253fe5720e2SKim Phillips
2549c4a7965SKim Phillips return 0;
2559c4a7965SKim Phillips }
2569c4a7965SKim Phillips
2579c4a7965SKim Phillips /**
2589c4a7965SKim Phillips * talitos_submit - submits a descriptor to the device for processing
2599c4a7965SKim Phillips * @dev: the SEC device to be used
2605228f0f7SKim Phillips * @ch: the SEC device channel to be used
2619c4a7965SKim Phillips * @desc: the descriptor to be processed by the device
2629c4a7965SKim Phillips * @callback: whom to call when processing is complete
2639c4a7965SKim Phillips * @context: a handle for use by caller (optional)
2649c4a7965SKim Phillips *
2659c4a7965SKim Phillips * desc must contain valid dma-mapped (bus physical) address pointers.
2669c4a7965SKim Phillips * callback must check err and feedback in descriptor header
2679c4a7965SKim Phillips * for device processing status.
2689c4a7965SKim Phillips */
talitos_submit(struct device * dev,int ch,struct talitos_desc * desc,void (* callback)(struct device * dev,struct talitos_desc * desc,void * context,int error),void * context)269fbb8d46eSChristophe Leroy static int talitos_submit(struct device *dev, int ch, struct talitos_desc *desc,
2709c4a7965SKim Phillips void (*callback)(struct device *dev,
2719c4a7965SKim Phillips struct talitos_desc *desc,
2729c4a7965SKim Phillips void *context, int error),
2739c4a7965SKim Phillips void *context)
2749c4a7965SKim Phillips {
2759c4a7965SKim Phillips struct talitos_private *priv = dev_get_drvdata(dev);
2769c4a7965SKim Phillips struct talitos_request *request;
2775228f0f7SKim Phillips unsigned long flags;
2789c4a7965SKim Phillips int head;
2797d607c6aSLEROY Christophe bool is_sec1 = has_ftr_sec1(priv);
2809c4a7965SKim Phillips
2814b992628SKim Phillips spin_lock_irqsave(&priv->chan[ch].head_lock, flags);
2829c4a7965SKim Phillips
2834b992628SKim Phillips if (!atomic_inc_not_zero(&priv->chan[ch].submit_count)) {
284ec6644d6SKim Phillips /* h/w fifo is full */
2854b992628SKim Phillips spin_unlock_irqrestore(&priv->chan[ch].head_lock, flags);
2869c4a7965SKim Phillips return -EAGAIN;
2879c4a7965SKim Phillips }
2889c4a7965SKim Phillips
2894b992628SKim Phillips head = priv->chan[ch].head;
2904b992628SKim Phillips request = &priv->chan[ch].fifo[head];
291ec6644d6SKim Phillips
2929c4a7965SKim Phillips /* map descriptor and save caller data */
2937d607c6aSLEROY Christophe if (is_sec1) {
2947d607c6aSLEROY Christophe desc->hdr1 = desc->hdr;
2957d607c6aSLEROY Christophe request->dma_desc = dma_map_single(dev, &desc->hdr1,
2967d607c6aSLEROY Christophe TALITOS_DESC_SIZE,
2979c4a7965SKim Phillips DMA_BIDIRECTIONAL);
2987d607c6aSLEROY Christophe } else {
2997d607c6aSLEROY Christophe request->dma_desc = dma_map_single(dev, desc,
3007d607c6aSLEROY Christophe TALITOS_DESC_SIZE,
3017d607c6aSLEROY Christophe DMA_BIDIRECTIONAL);
3027d607c6aSLEROY Christophe }
3039c4a7965SKim Phillips request->callback = callback;
3049c4a7965SKim Phillips request->context = context;
3059c4a7965SKim Phillips
3069c4a7965SKim Phillips /* increment fifo head */
3074b992628SKim Phillips priv->chan[ch].head = (priv->chan[ch].head + 1) & (priv->fifo_len - 1);
3089c4a7965SKim Phillips
3099c4a7965SKim Phillips smp_wmb();
3109c4a7965SKim Phillips request->desc = desc;
3119c4a7965SKim Phillips
3129c4a7965SKim Phillips /* GO! */
3139c4a7965SKim Phillips wmb();
314ad42d5fcSKim Phillips out_be32(priv->chan[ch].reg + TALITOS_FF,
315ad42d5fcSKim Phillips upper_32_bits(request->dma_desc));
316ad42d5fcSKim Phillips out_be32(priv->chan[ch].reg + TALITOS_FF_LO,
317a752447aSKim Phillips lower_32_bits(request->dma_desc));
3189c4a7965SKim Phillips
3194b992628SKim Phillips spin_unlock_irqrestore(&priv->chan[ch].head_lock, flags);
3209c4a7965SKim Phillips
3219c4a7965SKim Phillips return -EINPROGRESS;
3229c4a7965SKim Phillips }
3239c4a7965SKim Phillips
get_request_hdr(struct talitos_request * request,bool is_sec1)32458cdbc6dSChristophe Leroy static __be32 get_request_hdr(struct talitos_request *request, bool is_sec1)
32558cdbc6dSChristophe Leroy {
32658cdbc6dSChristophe Leroy struct talitos_edesc *edesc;
32758cdbc6dSChristophe Leroy
32858cdbc6dSChristophe Leroy if (!is_sec1)
32958cdbc6dSChristophe Leroy return request->desc->hdr;
33058cdbc6dSChristophe Leroy
33158cdbc6dSChristophe Leroy if (!request->desc->next_desc)
33258cdbc6dSChristophe Leroy return request->desc->hdr1;
33358cdbc6dSChristophe Leroy
33458cdbc6dSChristophe Leroy edesc = container_of(request->desc, struct talitos_edesc, desc);
33558cdbc6dSChristophe Leroy
33658cdbc6dSChristophe Leroy return ((struct talitos_desc *)(edesc->buf + edesc->dma_len))->hdr1;
33758cdbc6dSChristophe Leroy }
3389c4a7965SKim Phillips
3399c4a7965SKim Phillips /*
3409c4a7965SKim Phillips * process what was done, notify callback of error if not
3419c4a7965SKim Phillips */
flush_channel(struct device * dev,int ch,int error,int reset_ch)3429c4a7965SKim Phillips static void flush_channel(struct device *dev, int ch, int error, int reset_ch)
3439c4a7965SKim Phillips {
3449c4a7965SKim Phillips struct talitos_private *priv = dev_get_drvdata(dev);
3459c4a7965SKim Phillips struct talitos_request *request, saved_req;
3469c4a7965SKim Phillips unsigned long flags;
3479c4a7965SKim Phillips int tail, status;
3487d607c6aSLEROY Christophe bool is_sec1 = has_ftr_sec1(priv);
3499c4a7965SKim Phillips
3504b992628SKim Phillips spin_lock_irqsave(&priv->chan[ch].tail_lock, flags);
3519c4a7965SKim Phillips
3524b992628SKim Phillips tail = priv->chan[ch].tail;
3534b992628SKim Phillips while (priv->chan[ch].fifo[tail].desc) {
3547d607c6aSLEROY Christophe __be32 hdr;
3557d607c6aSLEROY Christophe
3564b992628SKim Phillips request = &priv->chan[ch].fifo[tail];
3579c4a7965SKim Phillips
3589c4a7965SKim Phillips /* descriptors with their done bits set don't get the error */
3599c4a7965SKim Phillips rmb();
36058cdbc6dSChristophe Leroy hdr = get_request_hdr(request, is_sec1);
3617d607c6aSLEROY Christophe
3627d607c6aSLEROY Christophe if ((hdr & DESC_HDR_DONE) == DESC_HDR_DONE)
3639c4a7965SKim Phillips status = 0;
364ca38a814SLee Nipper else
3659c4a7965SKim Phillips if (!error)
3669c4a7965SKim Phillips break;
3679c4a7965SKim Phillips else
3689c4a7965SKim Phillips status = error;
3699c4a7965SKim Phillips
3709c4a7965SKim Phillips dma_unmap_single(dev, request->dma_desc,
3717d607c6aSLEROY Christophe TALITOS_DESC_SIZE,
372e938e465SKim Phillips DMA_BIDIRECTIONAL);
3739c4a7965SKim Phillips
3749c4a7965SKim Phillips /* copy entries so we can call callback outside lock */
3759c4a7965SKim Phillips saved_req.desc = request->desc;
3769c4a7965SKim Phillips saved_req.callback = request->callback;
3779c4a7965SKim Phillips saved_req.context = request->context;
3789c4a7965SKim Phillips
3799c4a7965SKim Phillips /* release request entry in fifo */
3809c4a7965SKim Phillips smp_wmb();
3819c4a7965SKim Phillips request->desc = NULL;
3829c4a7965SKim Phillips
3839c4a7965SKim Phillips /* increment fifo tail */
3844b992628SKim Phillips priv->chan[ch].tail = (tail + 1) & (priv->fifo_len - 1);
3859c4a7965SKim Phillips
3864b992628SKim Phillips spin_unlock_irqrestore(&priv->chan[ch].tail_lock, flags);
387ec6644d6SKim Phillips
3884b992628SKim Phillips atomic_dec(&priv->chan[ch].submit_count);
389ec6644d6SKim Phillips
3909c4a7965SKim Phillips saved_req.callback(dev, saved_req.desc, saved_req.context,
3919c4a7965SKim Phillips status);
3929c4a7965SKim Phillips /* channel may resume processing in single desc error case */
3939c4a7965SKim Phillips if (error && !reset_ch && status == error)
3949c4a7965SKim Phillips return;
3954b992628SKim Phillips spin_lock_irqsave(&priv->chan[ch].tail_lock, flags);
3964b992628SKim Phillips tail = priv->chan[ch].tail;
3979c4a7965SKim Phillips }
3989c4a7965SKim Phillips
3994b992628SKim Phillips spin_unlock_irqrestore(&priv->chan[ch].tail_lock, flags);
4009c4a7965SKim Phillips }
4019c4a7965SKim Phillips
4029c4a7965SKim Phillips /*
4039c4a7965SKim Phillips * process completed requests for channels that have done status
4049c4a7965SKim Phillips */
405dd3c0987SLEROY Christophe #define DEF_TALITOS1_DONE(name, ch_done_mask) \
406dd3c0987SLEROY Christophe static void talitos1_done_##name(unsigned long data) \
407dd3c0987SLEROY Christophe { \
408dd3c0987SLEROY Christophe struct device *dev = (struct device *)data; \
409dd3c0987SLEROY Christophe struct talitos_private *priv = dev_get_drvdata(dev); \
410dd3c0987SLEROY Christophe unsigned long flags; \
411dd3c0987SLEROY Christophe \
412dd3c0987SLEROY Christophe if (ch_done_mask & 0x10000000) \
413dd3c0987SLEROY Christophe flush_channel(dev, 0, 0, 0); \
414dd3c0987SLEROY Christophe if (ch_done_mask & 0x40000000) \
415dd3c0987SLEROY Christophe flush_channel(dev, 1, 0, 0); \
416dd3c0987SLEROY Christophe if (ch_done_mask & 0x00010000) \
417dd3c0987SLEROY Christophe flush_channel(dev, 2, 0, 0); \
418dd3c0987SLEROY Christophe if (ch_done_mask & 0x00040000) \
419dd3c0987SLEROY Christophe flush_channel(dev, 3, 0, 0); \
420dd3c0987SLEROY Christophe \
421dd3c0987SLEROY Christophe /* At this point, all completed channels have been processed */ \
422dd3c0987SLEROY Christophe /* Unmask done interrupts for channels completed later on. */ \
423dd3c0987SLEROY Christophe spin_lock_irqsave(&priv->reg_lock, flags); \
424dd3c0987SLEROY Christophe clrbits32(priv->reg + TALITOS_IMR, ch_done_mask); \
425dd3c0987SLEROY Christophe clrbits32(priv->reg + TALITOS_IMR_LO, TALITOS1_IMR_LO_INIT); \
426dd3c0987SLEROY Christophe spin_unlock_irqrestore(&priv->reg_lock, flags); \
427dd3c0987SLEROY Christophe }
428dd3c0987SLEROY Christophe
429dd3c0987SLEROY Christophe DEF_TALITOS1_DONE(4ch, TALITOS1_ISR_4CHDONE)
DEF_TALITOS1_DONE(ch0,TALITOS1_ISR_CH_0_DONE)4309c02e285SLEROY Christophe DEF_TALITOS1_DONE(ch0, TALITOS1_ISR_CH_0_DONE)
431dd3c0987SLEROY Christophe
432dd3c0987SLEROY Christophe #define DEF_TALITOS2_DONE(name, ch_done_mask) \
433dd3c0987SLEROY Christophe static void talitos2_done_##name(unsigned long data) \
434c3e337f8SKim Phillips { \
435c3e337f8SKim Phillips struct device *dev = (struct device *)data; \
436c3e337f8SKim Phillips struct talitos_private *priv = dev_get_drvdata(dev); \
437511d63cbSHoria Geanta unsigned long flags; \
438c3e337f8SKim Phillips \
439c3e337f8SKim Phillips if (ch_done_mask & 1) \
440c3e337f8SKim Phillips flush_channel(dev, 0, 0, 0); \
441c3e337f8SKim Phillips if (ch_done_mask & (1 << 2)) \
442c3e337f8SKim Phillips flush_channel(dev, 1, 0, 0); \
443c3e337f8SKim Phillips if (ch_done_mask & (1 << 4)) \
444c3e337f8SKim Phillips flush_channel(dev, 2, 0, 0); \
445c3e337f8SKim Phillips if (ch_done_mask & (1 << 6)) \
446c3e337f8SKim Phillips flush_channel(dev, 3, 0, 0); \
447c3e337f8SKim Phillips \
448c3e337f8SKim Phillips /* At this point, all completed channels have been processed */ \
449c3e337f8SKim Phillips /* Unmask done interrupts for channels completed later on. */ \
450511d63cbSHoria Geanta spin_lock_irqsave(&priv->reg_lock, flags); \
451c3e337f8SKim Phillips setbits32(priv->reg + TALITOS_IMR, ch_done_mask); \
452dd3c0987SLEROY Christophe setbits32(priv->reg + TALITOS_IMR_LO, TALITOS2_IMR_LO_INIT); \
453511d63cbSHoria Geanta spin_unlock_irqrestore(&priv->reg_lock, flags); \
4549c4a7965SKim Phillips }
455dd3c0987SLEROY Christophe
456dd3c0987SLEROY Christophe DEF_TALITOS2_DONE(4ch, TALITOS2_ISR_4CHDONE)
4579c02e285SLEROY Christophe DEF_TALITOS2_DONE(ch0, TALITOS2_ISR_CH_0_DONE)
458dd3c0987SLEROY Christophe DEF_TALITOS2_DONE(ch0_2, TALITOS2_ISR_CH_0_2_DONE)
459dd3c0987SLEROY Christophe DEF_TALITOS2_DONE(ch1_3, TALITOS2_ISR_CH_1_3_DONE)
4609c4a7965SKim Phillips
4619c4a7965SKim Phillips /*
4629c4a7965SKim Phillips * locate current (offending) descriptor
4639c4a7965SKim Phillips */
46402376161SChristophe Leroy static __be32 current_desc_hdr(struct device *dev, int ch)
4659c4a7965SKim Phillips {
4669c4a7965SKim Phillips struct talitos_private *priv = dev_get_drvdata(dev);
467b62ffd8cSHoria Geanta int tail, iter;
4689c4a7965SKim Phillips dma_addr_t cur_desc;
4699c4a7965SKim Phillips
470b62ffd8cSHoria Geanta cur_desc = ((u64)in_be32(priv->chan[ch].reg + TALITOS_CDPR)) << 32;
471b62ffd8cSHoria Geanta cur_desc |= in_be32(priv->chan[ch].reg + TALITOS_CDPR_LO);
4729c4a7965SKim Phillips
473b62ffd8cSHoria Geanta if (!cur_desc) {
474b62ffd8cSHoria Geanta dev_err(dev, "CDPR is NULL, giving up search for offending descriptor\n");
475b62ffd8cSHoria Geanta return 0;
476b62ffd8cSHoria Geanta }
477b62ffd8cSHoria Geanta
478b62ffd8cSHoria Geanta tail = priv->chan[ch].tail;
479b62ffd8cSHoria Geanta
480b62ffd8cSHoria Geanta iter = tail;
48137b5e889SLEROY Christophe while (priv->chan[ch].fifo[iter].dma_desc != cur_desc &&
482195404dbSChristophe Leroy priv->chan[ch].fifo[iter].desc->next_desc != cpu_to_be32(cur_desc)) {
483b62ffd8cSHoria Geanta iter = (iter + 1) & (priv->fifo_len - 1);
484b62ffd8cSHoria Geanta if (iter == tail) {
4859c4a7965SKim Phillips dev_err(dev, "couldn't locate current descriptor\n");
4863e721aebSKim Phillips return 0;
4879c4a7965SKim Phillips }
4889c4a7965SKim Phillips }
4899c4a7965SKim Phillips
490195404dbSChristophe Leroy if (priv->chan[ch].fifo[iter].desc->next_desc == cpu_to_be32(cur_desc)) {
49158cdbc6dSChristophe Leroy struct talitos_edesc *edesc;
49258cdbc6dSChristophe Leroy
49358cdbc6dSChristophe Leroy edesc = container_of(priv->chan[ch].fifo[iter].desc,
49458cdbc6dSChristophe Leroy struct talitos_edesc, desc);
49558cdbc6dSChristophe Leroy return ((struct talitos_desc *)
49658cdbc6dSChristophe Leroy (edesc->buf + edesc->dma_len))->hdr;
49758cdbc6dSChristophe Leroy }
49837b5e889SLEROY Christophe
499b62ffd8cSHoria Geanta return priv->chan[ch].fifo[iter].desc->hdr;
5009c4a7965SKim Phillips }
5019c4a7965SKim Phillips
5029c4a7965SKim Phillips /*
5039c4a7965SKim Phillips * user diagnostics; report root cause of error based on execution unit status
5049c4a7965SKim Phillips */
report_eu_error(struct device * dev,int ch,__be32 desc_hdr)50502376161SChristophe Leroy static void report_eu_error(struct device *dev, int ch, __be32 desc_hdr)
5069c4a7965SKim Phillips {
5079c4a7965SKim Phillips struct talitos_private *priv = dev_get_drvdata(dev);
5089c4a7965SKim Phillips int i;
5099c4a7965SKim Phillips
5103e721aebSKim Phillips if (!desc_hdr)
51102376161SChristophe Leroy desc_hdr = cpu_to_be32(in_be32(priv->chan[ch].reg + TALITOS_DESCBUF));
5123e721aebSKim Phillips
5133e721aebSKim Phillips switch (desc_hdr & DESC_HDR_SEL0_MASK) {
5149c4a7965SKim Phillips case DESC_HDR_SEL0_AFEU:
5159c4a7965SKim Phillips dev_err(dev, "AFEUISR 0x%08x_%08x\n",
5165fa7fa14SLEROY Christophe in_be32(priv->reg_afeu + TALITOS_EUISR),
5175fa7fa14SLEROY Christophe in_be32(priv->reg_afeu + TALITOS_EUISR_LO));
5189c4a7965SKim Phillips break;
5199c4a7965SKim Phillips case DESC_HDR_SEL0_DEU:
5209c4a7965SKim Phillips dev_err(dev, "DEUISR 0x%08x_%08x\n",
5215fa7fa14SLEROY Christophe in_be32(priv->reg_deu + TALITOS_EUISR),
5225fa7fa14SLEROY Christophe in_be32(priv->reg_deu + TALITOS_EUISR_LO));
5239c4a7965SKim Phillips break;
5249c4a7965SKim Phillips case DESC_HDR_SEL0_MDEUA:
5259c4a7965SKim Phillips case DESC_HDR_SEL0_MDEUB:
5269c4a7965SKim Phillips dev_err(dev, "MDEUISR 0x%08x_%08x\n",
5275fa7fa14SLEROY Christophe in_be32(priv->reg_mdeu + TALITOS_EUISR),
5285fa7fa14SLEROY Christophe in_be32(priv->reg_mdeu + TALITOS_EUISR_LO));
5299c4a7965SKim Phillips break;
5309c4a7965SKim Phillips case DESC_HDR_SEL0_RNG:
5319c4a7965SKim Phillips dev_err(dev, "RNGUISR 0x%08x_%08x\n",
5325fa7fa14SLEROY Christophe in_be32(priv->reg_rngu + TALITOS_ISR),
5335fa7fa14SLEROY Christophe in_be32(priv->reg_rngu + TALITOS_ISR_LO));
5349c4a7965SKim Phillips break;
5359c4a7965SKim Phillips case DESC_HDR_SEL0_PKEU:
5369c4a7965SKim Phillips dev_err(dev, "PKEUISR 0x%08x_%08x\n",
5375fa7fa14SLEROY Christophe in_be32(priv->reg_pkeu + TALITOS_EUISR),
5385fa7fa14SLEROY Christophe in_be32(priv->reg_pkeu + TALITOS_EUISR_LO));
5399c4a7965SKim Phillips break;
5409c4a7965SKim Phillips case DESC_HDR_SEL0_AESU:
5419c4a7965SKim Phillips dev_err(dev, "AESUISR 0x%08x_%08x\n",
5425fa7fa14SLEROY Christophe in_be32(priv->reg_aesu + TALITOS_EUISR),
5435fa7fa14SLEROY Christophe in_be32(priv->reg_aesu + TALITOS_EUISR_LO));
5449c4a7965SKim Phillips break;
5459c4a7965SKim Phillips case DESC_HDR_SEL0_CRCU:
5469c4a7965SKim Phillips dev_err(dev, "CRCUISR 0x%08x_%08x\n",
5475fa7fa14SLEROY Christophe in_be32(priv->reg_crcu + TALITOS_EUISR),
5485fa7fa14SLEROY Christophe in_be32(priv->reg_crcu + TALITOS_EUISR_LO));
5499c4a7965SKim Phillips break;
5509c4a7965SKim Phillips case DESC_HDR_SEL0_KEU:
5519c4a7965SKim Phillips dev_err(dev, "KEUISR 0x%08x_%08x\n",
5525fa7fa14SLEROY Christophe in_be32(priv->reg_pkeu + TALITOS_EUISR),
5535fa7fa14SLEROY Christophe in_be32(priv->reg_pkeu + TALITOS_EUISR_LO));
5549c4a7965SKim Phillips break;
5559c4a7965SKim Phillips }
5569c4a7965SKim Phillips
5573e721aebSKim Phillips switch (desc_hdr & DESC_HDR_SEL1_MASK) {
5589c4a7965SKim Phillips case DESC_HDR_SEL1_MDEUA:
5599c4a7965SKim Phillips case DESC_HDR_SEL1_MDEUB:
5609c4a7965SKim Phillips dev_err(dev, "MDEUISR 0x%08x_%08x\n",
5615fa7fa14SLEROY Christophe in_be32(priv->reg_mdeu + TALITOS_EUISR),
5625fa7fa14SLEROY Christophe in_be32(priv->reg_mdeu + TALITOS_EUISR_LO));
5639c4a7965SKim Phillips break;
5649c4a7965SKim Phillips case DESC_HDR_SEL1_CRCU:
5659c4a7965SKim Phillips dev_err(dev, "CRCUISR 0x%08x_%08x\n",
5665fa7fa14SLEROY Christophe in_be32(priv->reg_crcu + TALITOS_EUISR),
5675fa7fa14SLEROY Christophe in_be32(priv->reg_crcu + TALITOS_EUISR_LO));
5689c4a7965SKim Phillips break;
5699c4a7965SKim Phillips }
5709c4a7965SKim Phillips
5719c4a7965SKim Phillips for (i = 0; i < 8; i++)
5729c4a7965SKim Phillips dev_err(dev, "DESCBUF 0x%08x_%08x\n",
573ad42d5fcSKim Phillips in_be32(priv->chan[ch].reg + TALITOS_DESCBUF + 8*i),
574ad42d5fcSKim Phillips in_be32(priv->chan[ch].reg + TALITOS_DESCBUF_LO + 8*i));
5759c4a7965SKim Phillips }
5769c4a7965SKim Phillips
5779c4a7965SKim Phillips /*
5789c4a7965SKim Phillips * recover from error interrupts
5799c4a7965SKim Phillips */
talitos_error(struct device * dev,u32 isr,u32 isr_lo)5805e718a09SKim Phillips static void talitos_error(struct device *dev, u32 isr, u32 isr_lo)
5819c4a7965SKim Phillips {
5829c4a7965SKim Phillips struct talitos_private *priv = dev_get_drvdata(dev);
5839c4a7965SKim Phillips unsigned int timeout = TALITOS_TIMEOUT;
584dd3c0987SLEROY Christophe int ch, error, reset_dev = 0;
58542e8b0d7SHoria Geant? u32 v_lo;
586dd3c0987SLEROY Christophe bool is_sec1 = has_ftr_sec1(priv);
587dd3c0987SLEROY Christophe int reset_ch = is_sec1 ? 1 : 0; /* only SEC2 supports continuation */
5889c4a7965SKim Phillips
5899c4a7965SKim Phillips for (ch = 0; ch < priv->num_channels; ch++) {
5909c4a7965SKim Phillips /* skip channels without errors */
591dd3c0987SLEROY Christophe if (is_sec1) {
592dd3c0987SLEROY Christophe /* bits 29, 31, 17, 19 */
593dd3c0987SLEROY Christophe if (!(isr & (1 << (29 + (ch & 1) * 2 - (ch & 2) * 6))))
594dd3c0987SLEROY Christophe continue;
595dd3c0987SLEROY Christophe } else {
5969c4a7965SKim Phillips if (!(isr & (1 << (ch * 2 + 1))))
5979c4a7965SKim Phillips continue;
598dd3c0987SLEROY Christophe }
5999c4a7965SKim Phillips
6009c4a7965SKim Phillips error = -EINVAL;
6019c4a7965SKim Phillips
602ad42d5fcSKim Phillips v_lo = in_be32(priv->chan[ch].reg + TALITOS_CCPSR_LO);
6039c4a7965SKim Phillips
6049c4a7965SKim Phillips if (v_lo & TALITOS_CCPSR_LO_DOF) {
6059c4a7965SKim Phillips dev_err(dev, "double fetch fifo overflow error\n");
6069c4a7965SKim Phillips error = -EAGAIN;
6079c4a7965SKim Phillips reset_ch = 1;
6089c4a7965SKim Phillips }
6099c4a7965SKim Phillips if (v_lo & TALITOS_CCPSR_LO_SOF) {
6109c4a7965SKim Phillips /* h/w dropped descriptor */
6119c4a7965SKim Phillips dev_err(dev, "single fetch fifo overflow error\n");
6129c4a7965SKim Phillips error = -EAGAIN;
6139c4a7965SKim Phillips }
6149c4a7965SKim Phillips if (v_lo & TALITOS_CCPSR_LO_MDTE)
6159c4a7965SKim Phillips dev_err(dev, "master data transfer error\n");
6169c4a7965SKim Phillips if (v_lo & TALITOS_CCPSR_LO_SGDLZ)
6174d9b3a5bSColin Ian King dev_err(dev, is_sec1 ? "pointer not complete error\n"
618dd3c0987SLEROY Christophe : "s/g data length zero error\n");
6199c4a7965SKim Phillips if (v_lo & TALITOS_CCPSR_LO_FPZ)
620dd3c0987SLEROY Christophe dev_err(dev, is_sec1 ? "parity error\n"
621dd3c0987SLEROY Christophe : "fetch pointer zero error\n");
6229c4a7965SKim Phillips if (v_lo & TALITOS_CCPSR_LO_IDH)
6239c4a7965SKim Phillips dev_err(dev, "illegal descriptor header error\n");
6249c4a7965SKim Phillips if (v_lo & TALITOS_CCPSR_LO_IEU)
625dd3c0987SLEROY Christophe dev_err(dev, is_sec1 ? "static assignment error\n"
626dd3c0987SLEROY Christophe : "invalid exec unit error\n");
6279c4a7965SKim Phillips if (v_lo & TALITOS_CCPSR_LO_EU)
6283e721aebSKim Phillips report_eu_error(dev, ch, current_desc_hdr(dev, ch));
629dd3c0987SLEROY Christophe if (!is_sec1) {
6309c4a7965SKim Phillips if (v_lo & TALITOS_CCPSR_LO_GB)
6319c4a7965SKim Phillips dev_err(dev, "gather boundary error\n");
6329c4a7965SKim Phillips if (v_lo & TALITOS_CCPSR_LO_GRL)
6339c4a7965SKim Phillips dev_err(dev, "gather return/length error\n");
6349c4a7965SKim Phillips if (v_lo & TALITOS_CCPSR_LO_SB)
6359c4a7965SKim Phillips dev_err(dev, "scatter boundary error\n");
6369c4a7965SKim Phillips if (v_lo & TALITOS_CCPSR_LO_SRL)
6379c4a7965SKim Phillips dev_err(dev, "scatter return/length error\n");
638dd3c0987SLEROY Christophe }
6399c4a7965SKim Phillips
6409c4a7965SKim Phillips flush_channel(dev, ch, error, reset_ch);
6419c4a7965SKim Phillips
6429c4a7965SKim Phillips if (reset_ch) {
6439c4a7965SKim Phillips reset_channel(dev, ch);
6449c4a7965SKim Phillips } else {
645ad42d5fcSKim Phillips setbits32(priv->chan[ch].reg + TALITOS_CCCR,
646dd3c0987SLEROY Christophe TALITOS2_CCCR_CONT);
647ad42d5fcSKim Phillips setbits32(priv->chan[ch].reg + TALITOS_CCCR_LO, 0);
648ad42d5fcSKim Phillips while ((in_be32(priv->chan[ch].reg + TALITOS_CCCR) &
649dd3c0987SLEROY Christophe TALITOS2_CCCR_CONT) && --timeout)
6509c4a7965SKim Phillips cpu_relax();
6519c4a7965SKim Phillips if (timeout == 0) {
6529c4a7965SKim Phillips dev_err(dev, "failed to restart channel %d\n",
6539c4a7965SKim Phillips ch);
6549c4a7965SKim Phillips reset_dev = 1;
6559c4a7965SKim Phillips }
6569c4a7965SKim Phillips }
6579c4a7965SKim Phillips }
658dd3c0987SLEROY Christophe if (reset_dev || (is_sec1 && isr & ~TALITOS1_ISR_4CHERR) ||
659dd3c0987SLEROY Christophe (!is_sec1 && isr & ~TALITOS2_ISR_4CHERR) || isr_lo) {
660dd3c0987SLEROY Christophe if (is_sec1 && (isr_lo & TALITOS1_ISR_TEA_ERR))
661dd3c0987SLEROY Christophe dev_err(dev, "TEA error: ISR 0x%08x_%08x\n",
662dd3c0987SLEROY Christophe isr, isr_lo);
663dd3c0987SLEROY Christophe else
664dd3c0987SLEROY Christophe dev_err(dev, "done overflow, internal time out, or "
665dd3c0987SLEROY Christophe "rngu error: ISR 0x%08x_%08x\n", isr, isr_lo);
6669c4a7965SKim Phillips
6679c4a7965SKim Phillips /* purge request queues */
6689c4a7965SKim Phillips for (ch = 0; ch < priv->num_channels; ch++)
6699c4a7965SKim Phillips flush_channel(dev, ch, -EIO, 1);
6709c4a7965SKim Phillips
6719c4a7965SKim Phillips /* reset and reinitialize the device */
6729c4a7965SKim Phillips init_device(dev);
6739c4a7965SKim Phillips }
6749c4a7965SKim Phillips }
6759c4a7965SKim Phillips
676dd3c0987SLEROY Christophe #define DEF_TALITOS1_INTERRUPT(name, ch_done_mask, ch_err_mask, tlet) \
677dd3c0987SLEROY Christophe static irqreturn_t talitos1_interrupt_##name(int irq, void *data) \
678dd3c0987SLEROY Christophe { \
679dd3c0987SLEROY Christophe struct device *dev = data; \
680dd3c0987SLEROY Christophe struct talitos_private *priv = dev_get_drvdata(dev); \
681dd3c0987SLEROY Christophe u32 isr, isr_lo; \
682dd3c0987SLEROY Christophe unsigned long flags; \
683dd3c0987SLEROY Christophe \
684dd3c0987SLEROY Christophe spin_lock_irqsave(&priv->reg_lock, flags); \
685dd3c0987SLEROY Christophe isr = in_be32(priv->reg + TALITOS_ISR); \
686dd3c0987SLEROY Christophe isr_lo = in_be32(priv->reg + TALITOS_ISR_LO); \
687dd3c0987SLEROY Christophe /* Acknowledge interrupt */ \
688dd3c0987SLEROY Christophe out_be32(priv->reg + TALITOS_ICR, isr & (ch_done_mask | ch_err_mask)); \
689dd3c0987SLEROY Christophe out_be32(priv->reg + TALITOS_ICR_LO, isr_lo); \
690dd3c0987SLEROY Christophe \
691dd3c0987SLEROY Christophe if (unlikely(isr & ch_err_mask || isr_lo & TALITOS1_IMR_LO_INIT)) { \
692dd3c0987SLEROY Christophe spin_unlock_irqrestore(&priv->reg_lock, flags); \
693dd3c0987SLEROY Christophe talitos_error(dev, isr & ch_err_mask, isr_lo); \
694dd3c0987SLEROY Christophe } \
695dd3c0987SLEROY Christophe else { \
696dd3c0987SLEROY Christophe if (likely(isr & ch_done_mask)) { \
697dd3c0987SLEROY Christophe /* mask further done interrupts. */ \
698dd3c0987SLEROY Christophe setbits32(priv->reg + TALITOS_IMR, ch_done_mask); \
699dd3c0987SLEROY Christophe /* done_task will unmask done interrupts at exit */ \
700dd3c0987SLEROY Christophe tasklet_schedule(&priv->done_task[tlet]); \
701dd3c0987SLEROY Christophe } \
702dd3c0987SLEROY Christophe spin_unlock_irqrestore(&priv->reg_lock, flags); \
703dd3c0987SLEROY Christophe } \
704dd3c0987SLEROY Christophe \
705dd3c0987SLEROY Christophe return (isr & (ch_done_mask | ch_err_mask) || isr_lo) ? IRQ_HANDLED : \
706dd3c0987SLEROY Christophe IRQ_NONE; \
707dd3c0987SLEROY Christophe }
708dd3c0987SLEROY Christophe
709dd3c0987SLEROY Christophe DEF_TALITOS1_INTERRUPT(4ch, TALITOS1_ISR_4CHDONE, TALITOS1_ISR_4CHERR, 0)
710dd3c0987SLEROY Christophe
711dd3c0987SLEROY Christophe #define DEF_TALITOS2_INTERRUPT(name, ch_done_mask, ch_err_mask, tlet) \
712dd3c0987SLEROY Christophe static irqreturn_t talitos2_interrupt_##name(int irq, void *data) \
713c3e337f8SKim Phillips { \
714c3e337f8SKim Phillips struct device *dev = data; \
715c3e337f8SKim Phillips struct talitos_private *priv = dev_get_drvdata(dev); \
716c3e337f8SKim Phillips u32 isr, isr_lo; \
717511d63cbSHoria Geanta unsigned long flags; \
718c3e337f8SKim Phillips \
719511d63cbSHoria Geanta spin_lock_irqsave(&priv->reg_lock, flags); \
720c3e337f8SKim Phillips isr = in_be32(priv->reg + TALITOS_ISR); \
721c3e337f8SKim Phillips isr_lo = in_be32(priv->reg + TALITOS_ISR_LO); \
722c3e337f8SKim Phillips /* Acknowledge interrupt */ \
723c3e337f8SKim Phillips out_be32(priv->reg + TALITOS_ICR, isr & (ch_done_mask | ch_err_mask)); \
724c3e337f8SKim Phillips out_be32(priv->reg + TALITOS_ICR_LO, isr_lo); \
725c3e337f8SKim Phillips \
726511d63cbSHoria Geanta if (unlikely(isr & ch_err_mask || isr_lo)) { \
727511d63cbSHoria Geanta spin_unlock_irqrestore(&priv->reg_lock, flags); \
728511d63cbSHoria Geanta talitos_error(dev, isr & ch_err_mask, isr_lo); \
729511d63cbSHoria Geanta } \
730511d63cbSHoria Geanta else { \
731c3e337f8SKim Phillips if (likely(isr & ch_done_mask)) { \
732c3e337f8SKim Phillips /* mask further done interrupts. */ \
733c3e337f8SKim Phillips clrbits32(priv->reg + TALITOS_IMR, ch_done_mask); \
734c3e337f8SKim Phillips /* done_task will unmask done interrupts at exit */ \
735c3e337f8SKim Phillips tasklet_schedule(&priv->done_task[tlet]); \
736c3e337f8SKim Phillips } \
737511d63cbSHoria Geanta spin_unlock_irqrestore(&priv->reg_lock, flags); \
738511d63cbSHoria Geanta } \
739c3e337f8SKim Phillips \
740c3e337f8SKim Phillips return (isr & (ch_done_mask | ch_err_mask) || isr_lo) ? IRQ_HANDLED : \
741c3e337f8SKim Phillips IRQ_NONE; \
7421c2e8811SLee Nipper }
743dd3c0987SLEROY Christophe
744dd3c0987SLEROY Christophe DEF_TALITOS2_INTERRUPT(4ch, TALITOS2_ISR_4CHDONE, TALITOS2_ISR_4CHERR, 0)
745dd3c0987SLEROY Christophe DEF_TALITOS2_INTERRUPT(ch0_2, TALITOS2_ISR_CH_0_2_DONE, TALITOS2_ISR_CH_0_2_ERR,
746dd3c0987SLEROY Christophe 0)
747dd3c0987SLEROY Christophe DEF_TALITOS2_INTERRUPT(ch1_3, TALITOS2_ISR_CH_1_3_DONE, TALITOS2_ISR_CH_1_3_ERR,
748dd3c0987SLEROY Christophe 1)
7499c4a7965SKim Phillips
7509c4a7965SKim Phillips /*
7519c4a7965SKim Phillips * hwrng
7529c4a7965SKim Phillips */
talitos_rng_data_present(struct hwrng * rng,int wait)7539c4a7965SKim Phillips static int talitos_rng_data_present(struct hwrng *rng, int wait)
7549c4a7965SKim Phillips {
7559c4a7965SKim Phillips struct device *dev = (struct device *)rng->priv;
7569c4a7965SKim Phillips struct talitos_private *priv = dev_get_drvdata(dev);
7579c4a7965SKim Phillips u32 ofl;
7589c4a7965SKim Phillips int i;
7599c4a7965SKim Phillips
7609c4a7965SKim Phillips for (i = 0; i < 20; i++) {
7615fa7fa14SLEROY Christophe ofl = in_be32(priv->reg_rngu + TALITOS_EUSR_LO) &
7629c4a7965SKim Phillips TALITOS_RNGUSR_LO_OFL;
7639c4a7965SKim Phillips if (ofl || !wait)
7649c4a7965SKim Phillips break;
7659c4a7965SKim Phillips udelay(10);
7669c4a7965SKim Phillips }
7679c4a7965SKim Phillips
7689c4a7965SKim Phillips return !!ofl;
7699c4a7965SKim Phillips }
7709c4a7965SKim Phillips
talitos_rng_data_read(struct hwrng * rng,u32 * data)7719c4a7965SKim Phillips static int talitos_rng_data_read(struct hwrng *rng, u32 *data)
7729c4a7965SKim Phillips {
7739c4a7965SKim Phillips struct device *dev = (struct device *)rng->priv;
7749c4a7965SKim Phillips struct talitos_private *priv = dev_get_drvdata(dev);
7759c4a7965SKim Phillips
7769c4a7965SKim Phillips /* rng fifo requires 64-bit accesses */
7775fa7fa14SLEROY Christophe *data = in_be32(priv->reg_rngu + TALITOS_EU_FIFO);
7785fa7fa14SLEROY Christophe *data = in_be32(priv->reg_rngu + TALITOS_EU_FIFO_LO);
7799c4a7965SKim Phillips
7809c4a7965SKim Phillips return sizeof(u32);
7819c4a7965SKim Phillips }
7829c4a7965SKim Phillips
talitos_rng_init(struct hwrng * rng)7839c4a7965SKim Phillips static int talitos_rng_init(struct hwrng *rng)
7849c4a7965SKim Phillips {
7859c4a7965SKim Phillips struct device *dev = (struct device *)rng->priv;
7869c4a7965SKim Phillips struct talitos_private *priv = dev_get_drvdata(dev);
7879c4a7965SKim Phillips unsigned int timeout = TALITOS_TIMEOUT;
7889c4a7965SKim Phillips
7895fa7fa14SLEROY Christophe setbits32(priv->reg_rngu + TALITOS_EURCR_LO, TALITOS_RNGURCR_LO_SR);
7905fa7fa14SLEROY Christophe while (!(in_be32(priv->reg_rngu + TALITOS_EUSR_LO)
7915fa7fa14SLEROY Christophe & TALITOS_RNGUSR_LO_RD)
7929c4a7965SKim Phillips && --timeout)
7939c4a7965SKim Phillips cpu_relax();
7949c4a7965SKim Phillips if (timeout == 0) {
7959c4a7965SKim Phillips dev_err(dev, "failed to reset rng hw\n");
7969c4a7965SKim Phillips return -ENODEV;
7979c4a7965SKim Phillips }
7989c4a7965SKim Phillips
7999c4a7965SKim Phillips /* start generating */
8005fa7fa14SLEROY Christophe setbits32(priv->reg_rngu + TALITOS_EUDSR_LO, 0);
8019c4a7965SKim Phillips
8029c4a7965SKim Phillips return 0;
8039c4a7965SKim Phillips }
8049c4a7965SKim Phillips
talitos_register_rng(struct device * dev)8059c4a7965SKim Phillips static int talitos_register_rng(struct device *dev)
8069c4a7965SKim Phillips {
8079c4a7965SKim Phillips struct talitos_private *priv = dev_get_drvdata(dev);
80835a3bb3dSAaron Sierra int err;
8099c4a7965SKim Phillips
81077450fd7SJulia Lawall priv->rng.name = dev_driver_string(dev);
81177450fd7SJulia Lawall priv->rng.init = talitos_rng_init;
81277450fd7SJulia Lawall priv->rng.data_present = talitos_rng_data_present;
81377450fd7SJulia Lawall priv->rng.data_read = talitos_rng_data_read;
8149c4a7965SKim Phillips priv->rng.priv = (unsigned long)dev;
8159c4a7965SKim Phillips
81635a3bb3dSAaron Sierra err = hwrng_register(&priv->rng);
81735a3bb3dSAaron Sierra if (!err)
81835a3bb3dSAaron Sierra priv->rng_registered = true;
81935a3bb3dSAaron Sierra
82035a3bb3dSAaron Sierra return err;
8219c4a7965SKim Phillips }
8229c4a7965SKim Phillips
talitos_unregister_rng(struct device * dev)8239c4a7965SKim Phillips static void talitos_unregister_rng(struct device *dev)
8249c4a7965SKim Phillips {
8259c4a7965SKim Phillips struct talitos_private *priv = dev_get_drvdata(dev);
8269c4a7965SKim Phillips
82735a3bb3dSAaron Sierra if (!priv->rng_registered)
82835a3bb3dSAaron Sierra return;
82935a3bb3dSAaron Sierra
8309c4a7965SKim Phillips hwrng_unregister(&priv->rng);
83135a3bb3dSAaron Sierra priv->rng_registered = false;
8329c4a7965SKim Phillips }
8339c4a7965SKim Phillips
8349c4a7965SKim Phillips /*
8359c4a7965SKim Phillips * crypto alg
8369c4a7965SKim Phillips */
8379c4a7965SKim Phillips #define TALITOS_CRA_PRIORITY 3000
8387405c8d7SLEROY Christophe /*
8397405c8d7SLEROY Christophe * Defines a priority for doing AEAD with descriptors type
8407405c8d7SLEROY Christophe * HMAC_SNOOP_NO_AFEA (HSNA) instead of type IPSEC_ESP
8417405c8d7SLEROY Christophe */
8427405c8d7SLEROY Christophe #define TALITOS_CRA_PRIORITY_AEAD_HSNA (TALITOS_CRA_PRIORITY - 1)
843192125edSChristophe Leroy #ifdef CONFIG_CRYPTO_DEV_TALITOS2
84403d2c511SMartin Hicks #define TALITOS_MAX_KEY_SIZE (AES_MAX_KEY_SIZE + SHA512_BLOCK_SIZE)
845b8fbdc2bSChristophe Leroy #else
846b8fbdc2bSChristophe Leroy #define TALITOS_MAX_KEY_SIZE (AES_MAX_KEY_SIZE + SHA256_BLOCK_SIZE)
847b8fbdc2bSChristophe Leroy #endif
8483952f17eSLee Nipper #define TALITOS_MAX_IV_LENGTH 16 /* max of AES_BLOCK_SIZE, DES3_EDE_BLOCK_SIZE */
84970bcaca7SLee Nipper
8509c4a7965SKim Phillips struct talitos_ctx {
8519c4a7965SKim Phillips struct device *dev;
8525228f0f7SKim Phillips int ch;
8539c4a7965SKim Phillips __be32 desc_hdr_template;
8549c4a7965SKim Phillips u8 key[TALITOS_MAX_KEY_SIZE];
85570bcaca7SLee Nipper u8 iv[TALITOS_MAX_IV_LENGTH];
8562e13ce08SLEROY Christophe dma_addr_t dma_key;
8579c4a7965SKim Phillips unsigned int keylen;
8589c4a7965SKim Phillips unsigned int enckeylen;
8599c4a7965SKim Phillips unsigned int authkeylen;
8609c4a7965SKim Phillips };
8619c4a7965SKim Phillips
862497f2e6bSLee Nipper #define HASH_MAX_BLOCK_SIZE SHA512_BLOCK_SIZE
863497f2e6bSLee Nipper #define TALITOS_MDEU_MAX_CONTEXT_SIZE TALITOS_MDEU_CONTEXT_SIZE_SHA384_SHA512
864497f2e6bSLee Nipper
865497f2e6bSLee Nipper struct talitos_ahash_req_ctx {
86660f208d7SKim Phillips u32 hw_context[TALITOS_MDEU_MAX_CONTEXT_SIZE / sizeof(u32)];
867497f2e6bSLee Nipper unsigned int hw_context_size;
8683c0dd190SLEROY Christophe u8 buf[2][HASH_MAX_BLOCK_SIZE];
8693c0dd190SLEROY Christophe int buf_idx;
87060f208d7SKim Phillips unsigned int swinit;
871497f2e6bSLee Nipper unsigned int first;
872497f2e6bSLee Nipper unsigned int last;
873497f2e6bSLee Nipper unsigned int to_hash_later;
87442e8b0d7SHoria Geant? unsigned int nbuf;
875497f2e6bSLee Nipper struct scatterlist bufsl[2];
876497f2e6bSLee Nipper struct scatterlist *psrc;
877497f2e6bSLee Nipper };
878497f2e6bSLee Nipper
8793639ca84SHoria Geant? struct talitos_export_state {
8803639ca84SHoria Geant? u32 hw_context[TALITOS_MDEU_MAX_CONTEXT_SIZE / sizeof(u32)];
8813639ca84SHoria Geant? u8 buf[HASH_MAX_BLOCK_SIZE];
8823639ca84SHoria Geant? unsigned int swinit;
8833639ca84SHoria Geant? unsigned int first;
8843639ca84SHoria Geant? unsigned int last;
8853639ca84SHoria Geant? unsigned int to_hash_later;
8863639ca84SHoria Geant? unsigned int nbuf;
8873639ca84SHoria Geant? };
8883639ca84SHoria Geant?
aead_setkey(struct crypto_aead * authenc,const u8 * key,unsigned int keylen)88956af8cd4SLee Nipper static int aead_setkey(struct crypto_aead *authenc,
8909c4a7965SKim Phillips const u8 *key, unsigned int keylen)
8919c4a7965SKim Phillips {
8929c4a7965SKim Phillips struct talitos_ctx *ctx = crypto_aead_ctx(authenc);
8932e13ce08SLEROY Christophe struct device *dev = ctx->dev;
894c306a98dSMathias Krause struct crypto_authenc_keys keys;
8959c4a7965SKim Phillips
896c306a98dSMathias Krause if (crypto_authenc_extractkeys(&keys, key, keylen) != 0)
8979c4a7965SKim Phillips goto badkey;
8989c4a7965SKim Phillips
899c306a98dSMathias Krause if (keys.authkeylen + keys.enckeylen > TALITOS_MAX_KEY_SIZE)
9009c4a7965SKim Phillips goto badkey;
9019c4a7965SKim Phillips
9022e13ce08SLEROY Christophe if (ctx->keylen)
9032e13ce08SLEROY Christophe dma_unmap_single(dev, ctx->dma_key, ctx->keylen, DMA_TO_DEVICE);
9042e13ce08SLEROY Christophe
905c306a98dSMathias Krause memcpy(ctx->key, keys.authkey, keys.authkeylen);
906c306a98dSMathias Krause memcpy(&ctx->key[keys.authkeylen], keys.enckey, keys.enckeylen);
9079c4a7965SKim Phillips
908c306a98dSMathias Krause ctx->keylen = keys.authkeylen + keys.enckeylen;
909c306a98dSMathias Krause ctx->enckeylen = keys.enckeylen;
910c306a98dSMathias Krause ctx->authkeylen = keys.authkeylen;
9112e13ce08SLEROY Christophe ctx->dma_key = dma_map_single(dev, ctx->key, ctx->keylen,
9122e13ce08SLEROY Christophe DMA_TO_DEVICE);
9139c4a7965SKim Phillips
9148f0691fcSTudor-Dan Ambarus memzero_explicit(&keys, sizeof(keys));
9159c4a7965SKim Phillips return 0;
9169c4a7965SKim Phillips
9179c4a7965SKim Phillips badkey:
9188f0691fcSTudor-Dan Ambarus memzero_explicit(&keys, sizeof(keys));
9199c4a7965SKim Phillips return -EINVAL;
9209c4a7965SKim Phillips }
9219c4a7965SKim Phillips
aead_des3_setkey(struct crypto_aead * authenc,const u8 * key,unsigned int keylen)922ef7c5c85SHerbert Xu static int aead_des3_setkey(struct crypto_aead *authenc,
923ef7c5c85SHerbert Xu const u8 *key, unsigned int keylen)
924ef7c5c85SHerbert Xu {
925ef7c5c85SHerbert Xu struct talitos_ctx *ctx = crypto_aead_ctx(authenc);
926ef7c5c85SHerbert Xu struct device *dev = ctx->dev;
927ef7c5c85SHerbert Xu struct crypto_authenc_keys keys;
928ef7c5c85SHerbert Xu int err;
929ef7c5c85SHerbert Xu
930ef7c5c85SHerbert Xu err = crypto_authenc_extractkeys(&keys, key, keylen);
931ef7c5c85SHerbert Xu if (unlikely(err))
932674f368aSEric Biggers goto out;
933ef7c5c85SHerbert Xu
934ef7c5c85SHerbert Xu err = -EINVAL;
935ef7c5c85SHerbert Xu if (keys.authkeylen + keys.enckeylen > TALITOS_MAX_KEY_SIZE)
936674f368aSEric Biggers goto out;
937ef7c5c85SHerbert Xu
9389d574ae8SArd Biesheuvel err = verify_aead_des3_key(authenc, keys.enckey, keys.enckeylen);
9399d574ae8SArd Biesheuvel if (err)
940ef7c5c85SHerbert Xu goto out;
941ef7c5c85SHerbert Xu
942ef7c5c85SHerbert Xu if (ctx->keylen)
943ef7c5c85SHerbert Xu dma_unmap_single(dev, ctx->dma_key, ctx->keylen, DMA_TO_DEVICE);
944ef7c5c85SHerbert Xu
945ef7c5c85SHerbert Xu memcpy(ctx->key, keys.authkey, keys.authkeylen);
946ef7c5c85SHerbert Xu memcpy(&ctx->key[keys.authkeylen], keys.enckey, keys.enckeylen);
947ef7c5c85SHerbert Xu
948ef7c5c85SHerbert Xu ctx->keylen = keys.authkeylen + keys.enckeylen;
949ef7c5c85SHerbert Xu ctx->enckeylen = keys.enckeylen;
950ef7c5c85SHerbert Xu ctx->authkeylen = keys.authkeylen;
951ef7c5c85SHerbert Xu ctx->dma_key = dma_map_single(dev, ctx->key, ctx->keylen,
952ef7c5c85SHerbert Xu DMA_TO_DEVICE);
953ef7c5c85SHerbert Xu
954ef7c5c85SHerbert Xu out:
955ef7c5c85SHerbert Xu memzero_explicit(&keys, sizeof(keys));
956ef7c5c85SHerbert Xu return err;
957ef7c5c85SHerbert Xu }
958ef7c5c85SHerbert Xu
talitos_sg_unmap(struct device * dev,struct talitos_edesc * edesc,struct scatterlist * src,struct scatterlist * dst,unsigned int len,unsigned int offset)9594de9d0b5SLee Nipper static void talitos_sg_unmap(struct device *dev,
9604de9d0b5SLee Nipper struct talitos_edesc *edesc,
9614de9d0b5SLee Nipper struct scatterlist *src,
9626a1e8d14SLEROY Christophe struct scatterlist *dst,
9636a1e8d14SLEROY Christophe unsigned int len, unsigned int offset)
964246a87cdSLEROY Christophe {
965246a87cdSLEROY Christophe struct talitos_private *priv = dev_get_drvdata(dev);
966246a87cdSLEROY Christophe bool is_sec1 = has_ftr_sec1(priv);
9676a1e8d14SLEROY Christophe unsigned int src_nents = edesc->src_nents ? : 1;
9686a1e8d14SLEROY Christophe unsigned int dst_nents = edesc->dst_nents ? : 1;
969246a87cdSLEROY Christophe
9706a1e8d14SLEROY Christophe if (is_sec1 && dst && dst_nents > 1) {
9716a1e8d14SLEROY Christophe dma_sync_single_for_device(dev, edesc->dma_link_tbl + offset,
972246a87cdSLEROY Christophe len, DMA_FROM_DEVICE);
9736a1e8d14SLEROY Christophe sg_pcopy_from_buffer(dst, dst_nents, edesc->buf + offset, len,
9746a1e8d14SLEROY Christophe offset);
975246a87cdSLEROY Christophe }
9766a1e8d14SLEROY Christophe if (src != dst) {
9776a1e8d14SLEROY Christophe if (src_nents == 1 || !is_sec1)
9786a1e8d14SLEROY Christophe dma_unmap_sg(dev, src, src_nents, DMA_TO_DEVICE);
9796a1e8d14SLEROY Christophe
9806a1e8d14SLEROY Christophe if (dst && (dst_nents == 1 || !is_sec1))
9816a1e8d14SLEROY Christophe dma_unmap_sg(dev, dst, dst_nents, DMA_FROM_DEVICE);
9826a1e8d14SLEROY Christophe } else if (src_nents == 1 || !is_sec1) {
9836a1e8d14SLEROY Christophe dma_unmap_sg(dev, src, src_nents, DMA_BIDIRECTIONAL);
984246a87cdSLEROY Christophe }
985246a87cdSLEROY Christophe }
986246a87cdSLEROY Christophe
ipsec_esp_unmap(struct device * dev,struct talitos_edesc * edesc,struct aead_request * areq,bool encrypt)9879c4a7965SKim Phillips static void ipsec_esp_unmap(struct device *dev,
98856af8cd4SLee Nipper struct talitos_edesc *edesc,
9897ede4c36SChristophe Leroy struct aead_request *areq, bool encrypt)
9909c4a7965SKim Phillips {
991549bd8bcSLEROY Christophe struct crypto_aead *aead = crypto_aead_reqtfm(areq);
992549bd8bcSLEROY Christophe struct talitos_ctx *ctx = crypto_aead_ctx(aead);
993549bd8bcSLEROY Christophe unsigned int ivsize = crypto_aead_ivsize(aead);
9947ede4c36SChristophe Leroy unsigned int authsize = crypto_aead_authsize(aead);
9957ede4c36SChristophe Leroy unsigned int cryptlen = areq->cryptlen - (encrypt ? 0 : authsize);
9969a655608SLEROY Christophe bool is_ipsec_esp = edesc->desc.hdr & DESC_HDR_TYPE_IPSEC_ESP;
9979a655608SLEROY Christophe struct talitos_ptr *civ_ptr = &edesc->desc.ptr[is_ipsec_esp ? 2 : 3];
998549bd8bcSLEROY Christophe
9999a655608SLEROY Christophe if (is_ipsec_esp)
1000549bd8bcSLEROY Christophe unmap_single_talitos_ptr(dev, &edesc->desc.ptr[6],
1001549bd8bcSLEROY Christophe DMA_FROM_DEVICE);
10029a655608SLEROY Christophe unmap_single_talitos_ptr(dev, civ_ptr, DMA_TO_DEVICE);
10039c4a7965SKim Phillips
1004e345177dSChristophe Leroy talitos_sg_unmap(dev, edesc, areq->src, areq->dst,
1005e345177dSChristophe Leroy cryptlen + authsize, areq->assoclen);
10069c4a7965SKim Phillips
10079c4a7965SKim Phillips if (edesc->dma_len)
10089c4a7965SKim Phillips dma_unmap_single(dev, edesc->dma_link_tbl, edesc->dma_len,
10099c4a7965SKim Phillips DMA_BIDIRECTIONAL);
1010549bd8bcSLEROY Christophe
10119a655608SLEROY Christophe if (!is_ipsec_esp) {
1012549bd8bcSLEROY Christophe unsigned int dst_nents = edesc->dst_nents ? : 1;
1013549bd8bcSLEROY Christophe
1014549bd8bcSLEROY Christophe sg_pcopy_to_buffer(areq->dst, dst_nents, ctx->iv, ivsize,
10157ede4c36SChristophe Leroy areq->assoclen + cryptlen - ivsize);
1016549bd8bcSLEROY Christophe }
10179c4a7965SKim Phillips }
10189c4a7965SKim Phillips
10199c4a7965SKim Phillips /*
10209c4a7965SKim Phillips * ipsec_esp descriptor callbacks
10219c4a7965SKim Phillips */
ipsec_esp_encrypt_done(struct device * dev,struct talitos_desc * desc,void * context,int err)10229c4a7965SKim Phillips static void ipsec_esp_encrypt_done(struct device *dev,
10239c4a7965SKim Phillips struct talitos_desc *desc, void *context,
10249c4a7965SKim Phillips int err)
10259c4a7965SKim Phillips {
10269c4a7965SKim Phillips struct aead_request *areq = context;
10279c4a7965SKim Phillips struct crypto_aead *authenc = crypto_aead_reqtfm(areq);
10282e13ce08SLEROY Christophe unsigned int ivsize = crypto_aead_ivsize(authenc);
102919bbbc63SKim Phillips struct talitos_edesc *edesc;
10309c4a7965SKim Phillips
103119bbbc63SKim Phillips edesc = container_of(desc, struct talitos_edesc, desc);
103219bbbc63SKim Phillips
10337ede4c36SChristophe Leroy ipsec_esp_unmap(dev, edesc, areq, true);
10349c4a7965SKim Phillips
10352e13ce08SLEROY Christophe dma_unmap_single(dev, edesc->iv_dma, ivsize, DMA_TO_DEVICE);
10362e13ce08SLEROY Christophe
10379c4a7965SKim Phillips kfree(edesc);
10389c4a7965SKim Phillips
10399c4a7965SKim Phillips aead_request_complete(areq, err);
10409c4a7965SKim Phillips }
10419c4a7965SKim Phillips
ipsec_esp_decrypt_swauth_done(struct device * dev,struct talitos_desc * desc,void * context,int err)1042fe5720e2SKim Phillips static void ipsec_esp_decrypt_swauth_done(struct device *dev,
1043e938e465SKim Phillips struct talitos_desc *desc,
1044e938e465SKim Phillips void *context, int err)
10459c4a7965SKim Phillips {
10469c4a7965SKim Phillips struct aead_request *req = context;
10479c4a7965SKim Phillips struct crypto_aead *authenc = crypto_aead_reqtfm(req);
1048aeb4c132SHerbert Xu unsigned int authsize = crypto_aead_authsize(authenc);
104919bbbc63SKim Phillips struct talitos_edesc *edesc;
1050aeb4c132SHerbert Xu char *oicv, *icv;
10519c4a7965SKim Phillips
105219bbbc63SKim Phillips edesc = container_of(desc, struct talitos_edesc, desc);
105319bbbc63SKim Phillips
10547ede4c36SChristophe Leroy ipsec_esp_unmap(dev, edesc, req, false);
10559c4a7965SKim Phillips
10569c4a7965SKim Phillips if (!err) {
10579c4a7965SKim Phillips /* auth check */
1058e345177dSChristophe Leroy oicv = edesc->buf + edesc->dma_len;
1059e345177dSChristophe Leroy icv = oicv - authsize;
1060aeb4c132SHerbert Xu
106179960943SDavid Gstir err = crypto_memneq(oicv, icv, authsize) ? -EBADMSG : 0;
10629c4a7965SKim Phillips }
10639c4a7965SKim Phillips
10649c4a7965SKim Phillips kfree(edesc);
10659c4a7965SKim Phillips
10669c4a7965SKim Phillips aead_request_complete(req, err);
10679c4a7965SKim Phillips }
10689c4a7965SKim Phillips
ipsec_esp_decrypt_hwauth_done(struct device * dev,struct talitos_desc * desc,void * context,int err)1069fe5720e2SKim Phillips static void ipsec_esp_decrypt_hwauth_done(struct device *dev,
1070e938e465SKim Phillips struct talitos_desc *desc,
1071e938e465SKim Phillips void *context, int err)
1072fe5720e2SKim Phillips {
1073fe5720e2SKim Phillips struct aead_request *req = context;
107419bbbc63SKim Phillips struct talitos_edesc *edesc;
107519bbbc63SKim Phillips
107619bbbc63SKim Phillips edesc = container_of(desc, struct talitos_edesc, desc);
1077fe5720e2SKim Phillips
10787ede4c36SChristophe Leroy ipsec_esp_unmap(dev, edesc, req, false);
1079fe5720e2SKim Phillips
1080fe5720e2SKim Phillips /* check ICV auth status */
1081e938e465SKim Phillips if (!err && ((desc->hdr_lo & DESC_HDR_LO_ICCR1_MASK) !=
1082e938e465SKim Phillips DESC_HDR_LO_ICCR1_PASS))
1083fe5720e2SKim Phillips err = -EBADMSG;
1084fe5720e2SKim Phillips
1085fe5720e2SKim Phillips kfree(edesc);
1086fe5720e2SKim Phillips
1087fe5720e2SKim Phillips aead_request_complete(req, err);
1088fe5720e2SKim Phillips }
1089fe5720e2SKim Phillips
10909c4a7965SKim Phillips /*
10919c4a7965SKim Phillips * convert scatterlist to SEC h/w link table format
10929c4a7965SKim Phillips * stop at cryptlen bytes
10939c4a7965SKim Phillips */
sg_to_link_tbl_offset(struct scatterlist * sg,int sg_count,unsigned int offset,int datalen,int elen,struct talitos_ptr * link_tbl_ptr,int align)1094aeb4c132SHerbert Xu static int sg_to_link_tbl_offset(struct scatterlist *sg, int sg_count,
1095e345177dSChristophe Leroy unsigned int offset, int datalen, int elen,
1096416b8467SChristophe Leroy struct talitos_ptr *link_tbl_ptr, int align)
10979c4a7965SKim Phillips {
1098e345177dSChristophe Leroy int n_sg = elen ? sg_count + 1 : sg_count;
1099aeb4c132SHerbert Xu int count = 0;
1100e345177dSChristophe Leroy int cryptlen = datalen + elen;
1101416b8467SChristophe Leroy int padding = ALIGN(cryptlen, align) - cryptlen;
110270bcaca7SLee Nipper
1103aeb4c132SHerbert Xu while (cryptlen && sg && n_sg--) {
1104aeb4c132SHerbert Xu unsigned int len = sg_dma_len(sg);
1105aeb4c132SHerbert Xu
1106aeb4c132SHerbert Xu if (offset >= len) {
1107aeb4c132SHerbert Xu offset -= len;
1108aeb4c132SHerbert Xu goto next;
1109aeb4c132SHerbert Xu }
1110aeb4c132SHerbert Xu
1111aeb4c132SHerbert Xu len -= offset;
1112aeb4c132SHerbert Xu
1113aeb4c132SHerbert Xu if (len > cryptlen)
1114aeb4c132SHerbert Xu len = cryptlen;
1115aeb4c132SHerbert Xu
1116e345177dSChristophe Leroy if (datalen > 0 && len > datalen) {
1117e345177dSChristophe Leroy to_talitos_ptr(link_tbl_ptr + count,
1118e345177dSChristophe Leroy sg_dma_address(sg) + offset, datalen, 0);
1119e345177dSChristophe Leroy to_talitos_ptr_ext_set(link_tbl_ptr + count, 0, 0);
1120e345177dSChristophe Leroy count++;
1121e345177dSChristophe Leroy len -= datalen;
1122e345177dSChristophe Leroy offset += datalen;
1123e345177dSChristophe Leroy }
1124aeb4c132SHerbert Xu to_talitos_ptr(link_tbl_ptr + count,
1125416b8467SChristophe Leroy sg_dma_address(sg) + offset, sg_next(sg) ? len : len + padding, 0);
1126b096b544SLEROY Christophe to_talitos_ptr_ext_set(link_tbl_ptr + count, 0, 0);
1127aeb4c132SHerbert Xu count++;
1128aeb4c132SHerbert Xu cryptlen -= len;
1129e345177dSChristophe Leroy datalen -= len;
1130aeb4c132SHerbert Xu offset = 0;
1131aeb4c132SHerbert Xu
1132aeb4c132SHerbert Xu next:
11335be4d4c9SCristian Stoica sg = sg_next(sg);
11349c4a7965SKim Phillips }
11359c4a7965SKim Phillips
11369c4a7965SKim Phillips /* tag end of link table */
1137aeb4c132SHerbert Xu if (count > 0)
1138b096b544SLEROY Christophe to_talitos_ptr_ext_set(link_tbl_ptr + count - 1,
1139e345177dSChristophe Leroy DESC_PTR_LNKTBL_RET, 0);
114070bcaca7SLee Nipper
1141aeb4c132SHerbert Xu return count;
1142aeb4c132SHerbert Xu }
1143aeb4c132SHerbert Xu
talitos_sg_map_ext(struct device * dev,struct scatterlist * src,unsigned int len,struct talitos_edesc * edesc,struct talitos_ptr * ptr,int sg_count,unsigned int offset,int tbl_off,int elen,bool force,int align)11442b122730SLEROY Christophe static int talitos_sg_map_ext(struct device *dev, struct scatterlist *src,
1145246a87cdSLEROY Christophe unsigned int len, struct talitos_edesc *edesc,
11462b122730SLEROY Christophe struct talitos_ptr *ptr, int sg_count,
1147e345177dSChristophe Leroy unsigned int offset, int tbl_off, int elen,
1148416b8467SChristophe Leroy bool force, int align)
1149246a87cdSLEROY Christophe {
1150246a87cdSLEROY Christophe struct talitos_private *priv = dev_get_drvdata(dev);
1151246a87cdSLEROY Christophe bool is_sec1 = has_ftr_sec1(priv);
1152416b8467SChristophe Leroy int aligned_len = ALIGN(len, align);
1153246a87cdSLEROY Christophe
115487a81dceSLEROY Christophe if (!src) {
115587a81dceSLEROY Christophe to_talitos_ptr(ptr, 0, 0, is_sec1);
115687a81dceSLEROY Christophe return 1;
115787a81dceSLEROY Christophe }
11582b122730SLEROY Christophe to_talitos_ptr_ext_set(ptr, elen, is_sec1);
1159e345177dSChristophe Leroy if (sg_count == 1 && !force) {
1160416b8467SChristophe Leroy to_talitos_ptr(ptr, sg_dma_address(src) + offset, aligned_len, is_sec1);
1161246a87cdSLEROY Christophe return sg_count;
1162246a87cdSLEROY Christophe }
1163246a87cdSLEROY Christophe if (is_sec1) {
1164416b8467SChristophe Leroy to_talitos_ptr(ptr, edesc->dma_link_tbl + offset, aligned_len, is_sec1);
11656a1e8d14SLEROY Christophe return sg_count;
1166246a87cdSLEROY Christophe }
1167e345177dSChristophe Leroy sg_count = sg_to_link_tbl_offset(src, sg_count, offset, len, elen,
1168416b8467SChristophe Leroy &edesc->link_tbl[tbl_off], align);
1169e345177dSChristophe Leroy if (sg_count == 1 && !force) {
11706a1e8d14SLEROY Christophe /* Only one segment now, so no link tbl needed*/
11716a1e8d14SLEROY Christophe copy_talitos_ptr(ptr, &edesc->link_tbl[tbl_off], is_sec1);
11726a1e8d14SLEROY Christophe return sg_count;
11736a1e8d14SLEROY Christophe }
1174246a87cdSLEROY Christophe to_talitos_ptr(ptr, edesc->dma_link_tbl +
1175416b8467SChristophe Leroy tbl_off * sizeof(struct talitos_ptr), aligned_len, is_sec1);
11766a1e8d14SLEROY Christophe to_talitos_ptr_ext_or(ptr, DESC_PTR_LNKTBL_JUMP, is_sec1);
11776a1e8d14SLEROY Christophe
11786a1e8d14SLEROY Christophe return sg_count;
1179246a87cdSLEROY Christophe }
1180246a87cdSLEROY Christophe
talitos_sg_map(struct device * dev,struct scatterlist * src,unsigned int len,struct talitos_edesc * edesc,struct talitos_ptr * ptr,int sg_count,unsigned int offset,int tbl_off)11812b122730SLEROY Christophe static int talitos_sg_map(struct device *dev, struct scatterlist *src,
11822b122730SLEROY Christophe unsigned int len, struct talitos_edesc *edesc,
11832b122730SLEROY Christophe struct talitos_ptr *ptr, int sg_count,
11842b122730SLEROY Christophe unsigned int offset, int tbl_off)
11852b122730SLEROY Christophe {
11862b122730SLEROY Christophe return talitos_sg_map_ext(dev, src, len, edesc, ptr, sg_count, offset,
1187416b8467SChristophe Leroy tbl_off, 0, false, 1);
11882b122730SLEROY Christophe }
11892b122730SLEROY Christophe
11909c4a7965SKim Phillips /*
11919c4a7965SKim Phillips * fill in and submit ipsec_esp descriptor
11929c4a7965SKim Phillips */
ipsec_esp(struct talitos_edesc * edesc,struct aead_request * areq,bool encrypt,void (* callback)(struct device * dev,struct talitos_desc * desc,void * context,int error))119356af8cd4SLee Nipper static int ipsec_esp(struct talitos_edesc *edesc, struct aead_request *areq,
11947ede4c36SChristophe Leroy bool encrypt,
1195aeb4c132SHerbert Xu void (*callback)(struct device *dev,
11969c4a7965SKim Phillips struct talitos_desc *desc,
11979c4a7965SKim Phillips void *context, int error))
11989c4a7965SKim Phillips {
11999c4a7965SKim Phillips struct crypto_aead *aead = crypto_aead_reqtfm(areq);
1200aeb4c132SHerbert Xu unsigned int authsize = crypto_aead_authsize(aead);
12019c4a7965SKim Phillips struct talitos_ctx *ctx = crypto_aead_ctx(aead);
12029c4a7965SKim Phillips struct device *dev = ctx->dev;
12039c4a7965SKim Phillips struct talitos_desc *desc = &edesc->desc;
12047ede4c36SChristophe Leroy unsigned int cryptlen = areq->cryptlen - (encrypt ? 0 : authsize);
1205e41256f1SKim Phillips unsigned int ivsize = crypto_aead_ivsize(aead);
1206aeb4c132SHerbert Xu int tbl_off = 0;
1207fa86a267SKim Phillips int sg_count, ret;
12082b122730SLEROY Christophe int elen = 0;
1209549bd8bcSLEROY Christophe bool sync_needed = false;
1210549bd8bcSLEROY Christophe struct talitos_private *priv = dev_get_drvdata(dev);
1211549bd8bcSLEROY Christophe bool is_sec1 = has_ftr_sec1(priv);
12129a655608SLEROY Christophe bool is_ipsec_esp = desc->hdr & DESC_HDR_TYPE_IPSEC_ESP;
12139a655608SLEROY Christophe struct talitos_ptr *civ_ptr = &desc->ptr[is_ipsec_esp ? 2 : 3];
12149a655608SLEROY Christophe struct talitos_ptr *ckey_ptr = &desc->ptr[is_ipsec_esp ? 3 : 2];
1215e345177dSChristophe Leroy dma_addr_t dma_icv = edesc->dma_link_tbl + edesc->dma_len - authsize;
12169c4a7965SKim Phillips
12179c4a7965SKim Phillips /* hmac key */
12182e13ce08SLEROY Christophe to_talitos_ptr(&desc->ptr[0], ctx->dma_key, ctx->authkeylen, is_sec1);
121979fd31d3SHoria Geanta
1220549bd8bcSLEROY Christophe sg_count = edesc->src_nents ?: 1;
1221549bd8bcSLEROY Christophe if (is_sec1 && sg_count > 1)
1222549bd8bcSLEROY Christophe sg_copy_to_buffer(areq->src, sg_count, edesc->buf,
1223549bd8bcSLEROY Christophe areq->assoclen + cryptlen);
1224549bd8bcSLEROY Christophe else
1225549bd8bcSLEROY Christophe sg_count = dma_map_sg(dev, areq->src, sg_count,
1226549bd8bcSLEROY Christophe (areq->src == areq->dst) ?
1227549bd8bcSLEROY Christophe DMA_BIDIRECTIONAL : DMA_TO_DEVICE);
1228549bd8bcSLEROY Christophe
12299c4a7965SKim Phillips /* hmac data */
1230549bd8bcSLEROY Christophe ret = talitos_sg_map(dev, areq->src, areq->assoclen, edesc,
1231549bd8bcSLEROY Christophe &desc->ptr[1], sg_count, 0, tbl_off);
123279fd31d3SHoria Geanta
1233549bd8bcSLEROY Christophe if (ret > 1) {
1234340ff60aSHoria Geant? tbl_off += ret;
1235549bd8bcSLEROY Christophe sync_needed = true;
123679fd31d3SHoria Geanta }
123779fd31d3SHoria Geanta
12389c4a7965SKim Phillips /* cipher iv */
12399a655608SLEROY Christophe to_talitos_ptr(civ_ptr, edesc->iv_dma, ivsize, is_sec1);
12409c4a7965SKim Phillips
12419c4a7965SKim Phillips /* cipher key */
12422e13ce08SLEROY Christophe to_talitos_ptr(ckey_ptr, ctx->dma_key + ctx->authkeylen,
12432e13ce08SLEROY Christophe ctx->enckeylen, is_sec1);
12449c4a7965SKim Phillips
12459c4a7965SKim Phillips /*
12469c4a7965SKim Phillips * cipher in
12479c4a7965SKim Phillips * map and adjust cipher len to aead request cryptlen.
12489c4a7965SKim Phillips * extent is bytes of HMAC postpended to ciphertext,
12499c4a7965SKim Phillips * typically 12 for ipsec
12509c4a7965SKim Phillips */
12512b122730SLEROY Christophe if (is_ipsec_esp && (desc->hdr & DESC_HDR_MODE1_MDEU_CICV))
12522b122730SLEROY Christophe elen = authsize;
1253549bd8bcSLEROY Christophe
12542b122730SLEROY Christophe ret = talitos_sg_map_ext(dev, areq->src, cryptlen, edesc, &desc->ptr[4],
1255e345177dSChristophe Leroy sg_count, areq->assoclen, tbl_off, elen,
1256416b8467SChristophe Leroy false, 1);
1257549bd8bcSLEROY Christophe
1258ec8c7d14SLEROY Christophe if (ret > 1) {
1259ec8c7d14SLEROY Christophe tbl_off += ret;
1260549bd8bcSLEROY Christophe sync_needed = true;
1261340ff60aSHoria Geant? }
12629c4a7965SKim Phillips
12639c4a7965SKim Phillips /* cipher out */
1264549bd8bcSLEROY Christophe if (areq->src != areq->dst) {
1265549bd8bcSLEROY Christophe sg_count = edesc->dst_nents ? : 1;
1266549bd8bcSLEROY Christophe if (!is_sec1 || sg_count == 1)
1267549bd8bcSLEROY Christophe dma_map_sg(dev, areq->dst, sg_count, DMA_FROM_DEVICE);
1268549bd8bcSLEROY Christophe }
12699c4a7965SKim Phillips
1270e345177dSChristophe Leroy if (is_ipsec_esp && encrypt)
1271e345177dSChristophe Leroy elen = authsize;
1272e345177dSChristophe Leroy else
1273e345177dSChristophe Leroy elen = 0;
1274e345177dSChristophe Leroy ret = talitos_sg_map_ext(dev, areq->dst, cryptlen, edesc, &desc->ptr[5],
1275e345177dSChristophe Leroy sg_count, areq->assoclen, tbl_off, elen,
1276416b8467SChristophe Leroy is_ipsec_esp && !encrypt, 1);
1277e04a61beSLEROY Christophe tbl_off += ret;
1278549bd8bcSLEROY Christophe
1279e345177dSChristophe Leroy if (!encrypt && is_ipsec_esp) {
128079fd31d3SHoria Geanta struct talitos_ptr *tbl_ptr = &edesc->link_tbl[tbl_off];
1281fe5720e2SKim Phillips
1282f3c85bc1SLee Nipper /* Add an entry to the link table for ICV data */
1283e04a61beSLEROY Christophe to_talitos_ptr_ext_set(tbl_ptr - 1, 0, is_sec1);
1284e345177dSChristophe Leroy to_talitos_ptr_ext_set(tbl_ptr, DESC_PTR_LNKTBL_RET, is_sec1);
12859c4a7965SKim Phillips
12869c4a7965SKim Phillips /* icv data follows link tables */
1287e345177dSChristophe Leroy to_talitos_ptr(tbl_ptr, dma_icv, authsize, is_sec1);
1288e345177dSChristophe Leroy to_talitos_ptr_ext_or(&desc->ptr[5], authsize, is_sec1);
1289e04a61beSLEROY Christophe sync_needed = true;
1290e345177dSChristophe Leroy } else if (!encrypt) {
1291e345177dSChristophe Leroy to_talitos_ptr(&desc->ptr[6], dma_icv, authsize, is_sec1);
1292e345177dSChristophe Leroy sync_needed = true;
1293e345177dSChristophe Leroy } else if (!is_ipsec_esp) {
1294e345177dSChristophe Leroy talitos_sg_map(dev, areq->dst, authsize, edesc, &desc->ptr[6],
1295e345177dSChristophe Leroy sg_count, areq->assoclen + cryptlen, tbl_off);
1296340ff60aSHoria Geant? }
12979c4a7965SKim Phillips
12989c4a7965SKim Phillips /* iv out */
12999a655608SLEROY Christophe if (is_ipsec_esp)
1300a2b35aa8SLEROY Christophe map_single_talitos_ptr(dev, &desc->ptr[6], ivsize, ctx->iv,
13019c4a7965SKim Phillips DMA_FROM_DEVICE);
13029c4a7965SKim Phillips
1303549bd8bcSLEROY Christophe if (sync_needed)
1304549bd8bcSLEROY Christophe dma_sync_single_for_device(dev, edesc->dma_link_tbl,
1305549bd8bcSLEROY Christophe edesc->dma_len,
1306549bd8bcSLEROY Christophe DMA_BIDIRECTIONAL);
1307549bd8bcSLEROY Christophe
13085228f0f7SKim Phillips ret = talitos_submit(dev, ctx->ch, desc, callback, areq);
1309fa86a267SKim Phillips if (ret != -EINPROGRESS) {
13107ede4c36SChristophe Leroy ipsec_esp_unmap(dev, edesc, areq, encrypt);
1311fa86a267SKim Phillips kfree(edesc);
1312fa86a267SKim Phillips }
1313fa86a267SKim Phillips return ret;
13149c4a7965SKim Phillips }
13159c4a7965SKim Phillips
13169c4a7965SKim Phillips /*
131756af8cd4SLee Nipper * allocate and map the extended descriptor
13189c4a7965SKim Phillips */
talitos_edesc_alloc(struct device * dev,struct scatterlist * src,struct scatterlist * dst,u8 * iv,unsigned int assoclen,unsigned int cryptlen,unsigned int authsize,unsigned int ivsize,int icv_stashing,u32 cryptoflags,bool encrypt)13194de9d0b5SLee Nipper static struct talitos_edesc *talitos_edesc_alloc(struct device *dev,
13204de9d0b5SLee Nipper struct scatterlist *src,
13214de9d0b5SLee Nipper struct scatterlist *dst,
132279fd31d3SHoria Geanta u8 *iv,
132379fd31d3SHoria Geanta unsigned int assoclen,
13244de9d0b5SLee Nipper unsigned int cryptlen,
13254de9d0b5SLee Nipper unsigned int authsize,
132679fd31d3SHoria Geanta unsigned int ivsize,
13274de9d0b5SLee Nipper int icv_stashing,
132862293a37SHoria Geanta u32 cryptoflags,
132962293a37SHoria Geanta bool encrypt)
13309c4a7965SKim Phillips {
133156af8cd4SLee Nipper struct talitos_edesc *edesc;
13326a1e8d14SLEROY Christophe int src_nents, dst_nents, alloc_len, dma_len, src_len, dst_len;
133379fd31d3SHoria Geanta dma_addr_t iv_dma = 0;
13344de9d0b5SLee Nipper gfp_t flags = cryptoflags & CRYPTO_TFM_REQ_MAY_SLEEP ? GFP_KERNEL :
1335586725f8SKim Phillips GFP_ATOMIC;
13366f65f6acSLEROY Christophe struct talitos_private *priv = dev_get_drvdata(dev);
13376f65f6acSLEROY Christophe bool is_sec1 = has_ftr_sec1(priv);
13386f65f6acSLEROY Christophe int max_len = is_sec1 ? TALITOS1_MAX_DATA_LEN : TALITOS2_MAX_DATA_LEN;
13399c4a7965SKim Phillips
13406f65f6acSLEROY Christophe if (cryptlen + authsize > max_len) {
13414de9d0b5SLee Nipper dev_err(dev, "length exceeds h/w max limit\n");
13429c4a7965SKim Phillips return ERR_PTR(-EINVAL);
13439c4a7965SKim Phillips }
13449c4a7965SKim Phillips
134562293a37SHoria Geanta if (!dst || dst == src) {
13466a1e8d14SLEROY Christophe src_len = assoclen + cryptlen + authsize;
13476a1e8d14SLEROY Christophe src_nents = sg_nents_for_len(src, src_len);
13488e409fe1SLABBE Corentin if (src_nents < 0) {
13498e409fe1SLABBE Corentin dev_err(dev, "Invalid number of src SG.\n");
1350c56c2e17SChristophe Leroy return ERR_PTR(-EINVAL);
13518e409fe1SLABBE Corentin }
13529c4a7965SKim Phillips src_nents = (src_nents == 1) ? 0 : src_nents;
135362293a37SHoria Geanta dst_nents = dst ? src_nents : 0;
13546a1e8d14SLEROY Christophe dst_len = 0;
135562293a37SHoria Geanta } else { /* dst && dst != src*/
13566a1e8d14SLEROY Christophe src_len = assoclen + cryptlen + (encrypt ? 0 : authsize);
13576a1e8d14SLEROY Christophe src_nents = sg_nents_for_len(src, src_len);
13588e409fe1SLABBE Corentin if (src_nents < 0) {
13598e409fe1SLABBE Corentin dev_err(dev, "Invalid number of src SG.\n");
1360c56c2e17SChristophe Leroy return ERR_PTR(-EINVAL);
13618e409fe1SLABBE Corentin }
136262293a37SHoria Geanta src_nents = (src_nents == 1) ? 0 : src_nents;
13636a1e8d14SLEROY Christophe dst_len = assoclen + cryptlen + (encrypt ? authsize : 0);
13646a1e8d14SLEROY Christophe dst_nents = sg_nents_for_len(dst, dst_len);
13658e409fe1SLABBE Corentin if (dst_nents < 0) {
13668e409fe1SLABBE Corentin dev_err(dev, "Invalid number of dst SG.\n");
1367c56c2e17SChristophe Leroy return ERR_PTR(-EINVAL);
13688e409fe1SLABBE Corentin }
1369695ad589SLee Nipper dst_nents = (dst_nents == 1) ? 0 : dst_nents;
13709c4a7965SKim Phillips }
13719c4a7965SKim Phillips
13729c4a7965SKim Phillips /*
13739c4a7965SKim Phillips * allocate space for base edesc plus the link tables,
1374aeb4c132SHerbert Xu * allowing for two separate entries for AD and generated ICV (+ 2),
1375aeb4c132SHerbert Xu * and space for two sets of ICVs (stashed and generated)
13769c4a7965SKim Phillips */
137756af8cd4SLee Nipper alloc_len = sizeof(struct talitos_edesc);
1378e345177dSChristophe Leroy if (src_nents || dst_nents || !encrypt) {
13796f65f6acSLEROY Christophe if (is_sec1)
13806a1e8d14SLEROY Christophe dma_len = (src_nents ? src_len : 0) +
1381e345177dSChristophe Leroy (dst_nents ? dst_len : 0) + authsize;
13826f65f6acSLEROY Christophe else
1383aeb4c132SHerbert Xu dma_len = (src_nents + dst_nents + 2) *
1384e345177dSChristophe Leroy sizeof(struct talitos_ptr) + authsize;
13859c4a7965SKim Phillips alloc_len += dma_len;
13869c4a7965SKim Phillips } else {
13879c4a7965SKim Phillips dma_len = 0;
13889c4a7965SKim Phillips }
1389e345177dSChristophe Leroy alloc_len += icv_stashing ? authsize : 0;
13909c4a7965SKim Phillips
139137b5e889SLEROY Christophe /* if its a ahash, add space for a second desc next to the first one */
139237b5e889SLEROY Christophe if (is_sec1 && !dst)
139337b5e889SLEROY Christophe alloc_len += sizeof(struct talitos_desc);
13941bea445bSChristophe Leroy alloc_len += ivsize;
139537b5e889SLEROY Christophe
13968e613cecSHerbert Xu edesc = kmalloc(ALIGN(alloc_len, dma_get_cache_alignment()), flags);
1397c56c2e17SChristophe Leroy if (!edesc)
1398c56c2e17SChristophe Leroy return ERR_PTR(-ENOMEM);
13991bea445bSChristophe Leroy if (ivsize) {
14001bea445bSChristophe Leroy iv = memcpy(((u8 *)edesc) + alloc_len - ivsize, iv, ivsize);
1401c56c2e17SChristophe Leroy iv_dma = dma_map_single(dev, iv, ivsize, DMA_TO_DEVICE);
14021bea445bSChristophe Leroy }
1403e4a647c4SLEROY Christophe memset(&edesc->desc, 0, sizeof(edesc->desc));
14049c4a7965SKim Phillips
14059c4a7965SKim Phillips edesc->src_nents = src_nents;
14069c4a7965SKim Phillips edesc->dst_nents = dst_nents;
140779fd31d3SHoria Geanta edesc->iv_dma = iv_dma;
14089c4a7965SKim Phillips edesc->dma_len = dma_len;
140958cdbc6dSChristophe Leroy if (dma_len)
141058cdbc6dSChristophe Leroy edesc->dma_link_tbl = dma_map_single(dev, &edesc->link_tbl[0],
1411497f2e6bSLee Nipper edesc->dma_len,
1412497f2e6bSLee Nipper DMA_BIDIRECTIONAL);
141358cdbc6dSChristophe Leroy
14149c4a7965SKim Phillips return edesc;
14159c4a7965SKim Phillips }
14169c4a7965SKim Phillips
aead_edesc_alloc(struct aead_request * areq,u8 * iv,int icv_stashing,bool encrypt)141779fd31d3SHoria Geanta static struct talitos_edesc *aead_edesc_alloc(struct aead_request *areq, u8 *iv,
141862293a37SHoria Geanta int icv_stashing, bool encrypt)
14194de9d0b5SLee Nipper {
14204de9d0b5SLee Nipper struct crypto_aead *authenc = crypto_aead_reqtfm(areq);
1421aeb4c132SHerbert Xu unsigned int authsize = crypto_aead_authsize(authenc);
14224de9d0b5SLee Nipper struct talitos_ctx *ctx = crypto_aead_ctx(authenc);
142379fd31d3SHoria Geanta unsigned int ivsize = crypto_aead_ivsize(authenc);
14247ede4c36SChristophe Leroy unsigned int cryptlen = areq->cryptlen - (encrypt ? 0 : authsize);
14254de9d0b5SLee Nipper
1426aeb4c132SHerbert Xu return talitos_edesc_alloc(ctx->dev, areq->src, areq->dst,
14277ede4c36SChristophe Leroy iv, areq->assoclen, cryptlen,
1428aeb4c132SHerbert Xu authsize, ivsize, icv_stashing,
142962293a37SHoria Geanta areq->base.flags, encrypt);
14304de9d0b5SLee Nipper }
14314de9d0b5SLee Nipper
aead_encrypt(struct aead_request * req)143256af8cd4SLee Nipper static int aead_encrypt(struct aead_request *req)
14339c4a7965SKim Phillips {
14349c4a7965SKim Phillips struct crypto_aead *authenc = crypto_aead_reqtfm(req);
14359c4a7965SKim Phillips struct talitos_ctx *ctx = crypto_aead_ctx(authenc);
143656af8cd4SLee Nipper struct talitos_edesc *edesc;
14379c4a7965SKim Phillips
14389c4a7965SKim Phillips /* allocate extended descriptor */
143962293a37SHoria Geanta edesc = aead_edesc_alloc(req, req->iv, 0, true);
14409c4a7965SKim Phillips if (IS_ERR(edesc))
14419c4a7965SKim Phillips return PTR_ERR(edesc);
14429c4a7965SKim Phillips
14439c4a7965SKim Phillips /* set encrypt */
144470bcaca7SLee Nipper edesc->desc.hdr = ctx->desc_hdr_template | DESC_HDR_MODE0_ENCRYPT;
14459c4a7965SKim Phillips
14467ede4c36SChristophe Leroy return ipsec_esp(edesc, req, true, ipsec_esp_encrypt_done);
14479c4a7965SKim Phillips }
14489c4a7965SKim Phillips
aead_decrypt(struct aead_request * req)144956af8cd4SLee Nipper static int aead_decrypt(struct aead_request *req)
14509c4a7965SKim Phillips {
14519c4a7965SKim Phillips struct crypto_aead *authenc = crypto_aead_reqtfm(req);
1452aeb4c132SHerbert Xu unsigned int authsize = crypto_aead_authsize(authenc);
14539c4a7965SKim Phillips struct talitos_ctx *ctx = crypto_aead_ctx(authenc);
1454fe5720e2SKim Phillips struct talitos_private *priv = dev_get_drvdata(ctx->dev);
145556af8cd4SLee Nipper struct talitos_edesc *edesc;
14569c4a7965SKim Phillips void *icvdata;
14579c4a7965SKim Phillips
14589c4a7965SKim Phillips /* allocate extended descriptor */
145962293a37SHoria Geanta edesc = aead_edesc_alloc(req, req->iv, 1, false);
14609c4a7965SKim Phillips if (IS_ERR(edesc))
14619c4a7965SKim Phillips return PTR_ERR(edesc);
14629c4a7965SKim Phillips
14634bbfb839SChristophe Leroy if ((edesc->desc.hdr & DESC_HDR_TYPE_IPSEC_ESP) &&
14644bbfb839SChristophe Leroy (priv->features & TALITOS_FTR_HW_AUTH_CHECK) &&
1465e938e465SKim Phillips ((!edesc->src_nents && !edesc->dst_nents) ||
1466e938e465SKim Phillips priv->features & TALITOS_FTR_SRC_LINK_TBL_LEN_INCLUDES_EXTENT)) {
1467fe5720e2SKim Phillips
1468fe5720e2SKim Phillips /* decrypt and check the ICV */
1469e938e465SKim Phillips edesc->desc.hdr = ctx->desc_hdr_template |
1470e938e465SKim Phillips DESC_HDR_DIR_INBOUND |
1471fe5720e2SKim Phillips DESC_HDR_MODE1_MDEU_CICV;
1472fe5720e2SKim Phillips
1473fe5720e2SKim Phillips /* reset integrity check result bits */
1474fe5720e2SKim Phillips
14757ede4c36SChristophe Leroy return ipsec_esp(edesc, req, false,
14767ede4c36SChristophe Leroy ipsec_esp_decrypt_hwauth_done);
1477e938e465SKim Phillips }
1478fe5720e2SKim Phillips
1479fe5720e2SKim Phillips /* Have to check the ICV with software */
1480fe5720e2SKim Phillips edesc->desc.hdr = ctx->desc_hdr_template | DESC_HDR_DIR_INBOUND;
1481fe5720e2SKim Phillips
14829c4a7965SKim Phillips /* stash incoming ICV for later cmp with ICV generated by the h/w */
1483e345177dSChristophe Leroy icvdata = edesc->buf + edesc->dma_len;
14849c4a7965SKim Phillips
1485eae55a58SChristophe Leroy sg_pcopy_to_buffer(req->src, edesc->src_nents ? : 1, icvdata, authsize,
1486eae55a58SChristophe Leroy req->assoclen + req->cryptlen - authsize);
14879c4a7965SKim Phillips
14887ede4c36SChristophe Leroy return ipsec_esp(edesc, req, false, ipsec_esp_decrypt_swauth_done);
14899c4a7965SKim Phillips }
14909c4a7965SKim Phillips
skcipher_setkey(struct crypto_skcipher * cipher,const u8 * key,unsigned int keylen)1491373960d7SArd Biesheuvel static int skcipher_setkey(struct crypto_skcipher *cipher,
14924de9d0b5SLee Nipper const u8 *key, unsigned int keylen)
14934de9d0b5SLee Nipper {
1494373960d7SArd Biesheuvel struct talitos_ctx *ctx = crypto_skcipher_ctx(cipher);
14952e13ce08SLEROY Christophe struct device *dev = ctx->dev;
1496f384cdc4SLEROY Christophe
14972e13ce08SLEROY Christophe if (ctx->keylen)
14982e13ce08SLEROY Christophe dma_unmap_single(dev, ctx->dma_key, ctx->keylen, DMA_TO_DEVICE);
14992e13ce08SLEROY Christophe
15004de9d0b5SLee Nipper memcpy(&ctx->key, key, keylen);
15014de9d0b5SLee Nipper ctx->keylen = keylen;
15024de9d0b5SLee Nipper
15032e13ce08SLEROY Christophe ctx->dma_key = dma_map_single(dev, ctx->key, keylen, DMA_TO_DEVICE);
15042e13ce08SLEROY Christophe
15054de9d0b5SLee Nipper return 0;
15064de9d0b5SLee Nipper }
15074de9d0b5SLee Nipper
skcipher_des_setkey(struct crypto_skcipher * cipher,const u8 * key,unsigned int keylen)1508373960d7SArd Biesheuvel static int skcipher_des_setkey(struct crypto_skcipher *cipher,
1509ef7c5c85SHerbert Xu const u8 *key, unsigned int keylen)
1510ef7c5c85SHerbert Xu {
1511373960d7SArd Biesheuvel return verify_skcipher_des_key(cipher, key) ?:
1512373960d7SArd Biesheuvel skcipher_setkey(cipher, key, keylen);
1513ef7c5c85SHerbert Xu }
1514ef7c5c85SHerbert Xu
skcipher_des3_setkey(struct crypto_skcipher * cipher,const u8 * key,unsigned int keylen)1515373960d7SArd Biesheuvel static int skcipher_des3_setkey(struct crypto_skcipher *cipher,
1516ef7c5c85SHerbert Xu const u8 *key, unsigned int keylen)
1517ef7c5c85SHerbert Xu {
1518373960d7SArd Biesheuvel return verify_skcipher_des3_key(cipher, key) ?:
1519373960d7SArd Biesheuvel skcipher_setkey(cipher, key, keylen);
1520ef7c5c85SHerbert Xu }
1521ef7c5c85SHerbert Xu
skcipher_aes_setkey(struct crypto_skcipher * cipher,const u8 * key,unsigned int keylen)1522373960d7SArd Biesheuvel static int skcipher_aes_setkey(struct crypto_skcipher *cipher,
15231ba34e71SChristophe Leroy const u8 *key, unsigned int keylen)
15241ba34e71SChristophe Leroy {
15251ba34e71SChristophe Leroy if (keylen == AES_KEYSIZE_128 || keylen == AES_KEYSIZE_192 ||
15261ba34e71SChristophe Leroy keylen == AES_KEYSIZE_256)
1527373960d7SArd Biesheuvel return skcipher_setkey(cipher, key, keylen);
15281ba34e71SChristophe Leroy
15291ba34e71SChristophe Leroy return -EINVAL;
15301ba34e71SChristophe Leroy }
15311ba34e71SChristophe Leroy
common_nonsnoop_unmap(struct device * dev,struct talitos_edesc * edesc,struct skcipher_request * areq)15324de9d0b5SLee Nipper static void common_nonsnoop_unmap(struct device *dev,
15334de9d0b5SLee Nipper struct talitos_edesc *edesc,
1534373960d7SArd Biesheuvel struct skcipher_request *areq)
15354de9d0b5SLee Nipper {
15364de9d0b5SLee Nipper unmap_single_talitos_ptr(dev, &edesc->desc.ptr[5], DMA_FROM_DEVICE);
1537032d197eSLEROY Christophe
1538373960d7SArd Biesheuvel talitos_sg_unmap(dev, edesc, areq->src, areq->dst, areq->cryptlen, 0);
15394de9d0b5SLee Nipper unmap_single_talitos_ptr(dev, &edesc->desc.ptr[1], DMA_TO_DEVICE);
15404de9d0b5SLee Nipper
15414de9d0b5SLee Nipper if (edesc->dma_len)
15424de9d0b5SLee Nipper dma_unmap_single(dev, edesc->dma_link_tbl, edesc->dma_len,
15434de9d0b5SLee Nipper DMA_BIDIRECTIONAL);
15444de9d0b5SLee Nipper }
15454de9d0b5SLee Nipper
skcipher_done(struct device * dev,struct talitos_desc * desc,void * context,int err)1546373960d7SArd Biesheuvel static void skcipher_done(struct device *dev,
15474de9d0b5SLee Nipper struct talitos_desc *desc, void *context,
15484de9d0b5SLee Nipper int err)
15494de9d0b5SLee Nipper {
1550373960d7SArd Biesheuvel struct skcipher_request *areq = context;
1551373960d7SArd Biesheuvel struct crypto_skcipher *cipher = crypto_skcipher_reqtfm(areq);
1552373960d7SArd Biesheuvel struct talitos_ctx *ctx = crypto_skcipher_ctx(cipher);
1553373960d7SArd Biesheuvel unsigned int ivsize = crypto_skcipher_ivsize(cipher);
155419bbbc63SKim Phillips struct talitos_edesc *edesc;
155519bbbc63SKim Phillips
155619bbbc63SKim Phillips edesc = container_of(desc, struct talitos_edesc, desc);
15574de9d0b5SLee Nipper
15584de9d0b5SLee Nipper common_nonsnoop_unmap(dev, edesc, areq);
1559373960d7SArd Biesheuvel memcpy(areq->iv, ctx->iv, ivsize);
15604de9d0b5SLee Nipper
15614de9d0b5SLee Nipper kfree(edesc);
15624de9d0b5SLee Nipper
1563234650bdSHerbert Xu skcipher_request_complete(areq, err);
15644de9d0b5SLee Nipper }
15654de9d0b5SLee Nipper
common_nonsnoop(struct talitos_edesc * edesc,struct skcipher_request * areq,void (* callback)(struct device * dev,struct talitos_desc * desc,void * context,int error))15664de9d0b5SLee Nipper static int common_nonsnoop(struct talitos_edesc *edesc,
1567373960d7SArd Biesheuvel struct skcipher_request *areq,
15684de9d0b5SLee Nipper void (*callback) (struct device *dev,
15694de9d0b5SLee Nipper struct talitos_desc *desc,
15704de9d0b5SLee Nipper void *context, int error))
15714de9d0b5SLee Nipper {
1572373960d7SArd Biesheuvel struct crypto_skcipher *cipher = crypto_skcipher_reqtfm(areq);
1573373960d7SArd Biesheuvel struct talitos_ctx *ctx = crypto_skcipher_ctx(cipher);
15744de9d0b5SLee Nipper struct device *dev = ctx->dev;
15754de9d0b5SLee Nipper struct talitos_desc *desc = &edesc->desc;
1576373960d7SArd Biesheuvel unsigned int cryptlen = areq->cryptlen;
1577373960d7SArd Biesheuvel unsigned int ivsize = crypto_skcipher_ivsize(cipher);
15784de9d0b5SLee Nipper int sg_count, ret;
15796a1e8d14SLEROY Christophe bool sync_needed = false;
1580922f9dc8SLEROY Christophe struct talitos_private *priv = dev_get_drvdata(dev);
1581922f9dc8SLEROY Christophe bool is_sec1 = has_ftr_sec1(priv);
1582416b8467SChristophe Leroy bool is_ctr = (desc->hdr & DESC_HDR_SEL0_MASK) == DESC_HDR_SEL0_AESU &&
1583416b8467SChristophe Leroy (desc->hdr & DESC_HDR_MODE0_AESU_MASK) == DESC_HDR_MODE0_AESU_CTR;
15844de9d0b5SLee Nipper
15854de9d0b5SLee Nipper /* first DWORD empty */
15864de9d0b5SLee Nipper
15874de9d0b5SLee Nipper /* cipher iv */
1588da9de146SLEROY Christophe to_talitos_ptr(&desc->ptr[1], edesc->iv_dma, ivsize, is_sec1);
15894de9d0b5SLee Nipper
15904de9d0b5SLee Nipper /* cipher key */
15912e13ce08SLEROY Christophe to_talitos_ptr(&desc->ptr[2], ctx->dma_key, ctx->keylen, is_sec1);
15924de9d0b5SLee Nipper
15936a1e8d14SLEROY Christophe sg_count = edesc->src_nents ?: 1;
15946a1e8d14SLEROY Christophe if (is_sec1 && sg_count > 1)
15956a1e8d14SLEROY Christophe sg_copy_to_buffer(areq->src, sg_count, edesc->buf,
15966a1e8d14SLEROY Christophe cryptlen);
15976a1e8d14SLEROY Christophe else
15986a1e8d14SLEROY Christophe sg_count = dma_map_sg(dev, areq->src, sg_count,
15996a1e8d14SLEROY Christophe (areq->src == areq->dst) ?
16006a1e8d14SLEROY Christophe DMA_BIDIRECTIONAL : DMA_TO_DEVICE);
16014de9d0b5SLee Nipper /*
16024de9d0b5SLee Nipper * cipher in
16034de9d0b5SLee Nipper */
1604416b8467SChristophe Leroy sg_count = talitos_sg_map_ext(dev, areq->src, cryptlen, edesc, &desc->ptr[3],
1605416b8467SChristophe Leroy sg_count, 0, 0, 0, false, is_ctr ? 16 : 1);
16066a1e8d14SLEROY Christophe if (sg_count > 1)
16076a1e8d14SLEROY Christophe sync_needed = true;
16084de9d0b5SLee Nipper
16094de9d0b5SLee Nipper /* cipher out */
16106a1e8d14SLEROY Christophe if (areq->src != areq->dst) {
16116a1e8d14SLEROY Christophe sg_count = edesc->dst_nents ? : 1;
16126a1e8d14SLEROY Christophe if (!is_sec1 || sg_count == 1)
16136a1e8d14SLEROY Christophe dma_map_sg(dev, areq->dst, sg_count, DMA_FROM_DEVICE);
16146a1e8d14SLEROY Christophe }
16156a1e8d14SLEROY Christophe
16166a1e8d14SLEROY Christophe ret = talitos_sg_map(dev, areq->dst, cryptlen, edesc, &desc->ptr[4],
16176a1e8d14SLEROY Christophe sg_count, 0, (edesc->src_nents + 1));
16186a1e8d14SLEROY Christophe if (ret > 1)
16196a1e8d14SLEROY Christophe sync_needed = true;
16204de9d0b5SLee Nipper
16214de9d0b5SLee Nipper /* iv out */
1622a2b35aa8SLEROY Christophe map_single_talitos_ptr(dev, &desc->ptr[5], ivsize, ctx->iv,
16234de9d0b5SLee Nipper DMA_FROM_DEVICE);
16244de9d0b5SLee Nipper
16254de9d0b5SLee Nipper /* last DWORD empty */
16264de9d0b5SLee Nipper
16276a1e8d14SLEROY Christophe if (sync_needed)
16286a1e8d14SLEROY Christophe dma_sync_single_for_device(dev, edesc->dma_link_tbl,
16296a1e8d14SLEROY Christophe edesc->dma_len, DMA_BIDIRECTIONAL);
16306a1e8d14SLEROY Christophe
16315228f0f7SKim Phillips ret = talitos_submit(dev, ctx->ch, desc, callback, areq);
16324de9d0b5SLee Nipper if (ret != -EINPROGRESS) {
16334de9d0b5SLee Nipper common_nonsnoop_unmap(dev, edesc, areq);
16344de9d0b5SLee Nipper kfree(edesc);
16354de9d0b5SLee Nipper }
16364de9d0b5SLee Nipper return ret;
16374de9d0b5SLee Nipper }
16384de9d0b5SLee Nipper
skcipher_edesc_alloc(struct skcipher_request * areq,bool encrypt)1639373960d7SArd Biesheuvel static struct talitos_edesc *skcipher_edesc_alloc(struct skcipher_request *
164062293a37SHoria Geanta areq, bool encrypt)
16414de9d0b5SLee Nipper {
1642373960d7SArd Biesheuvel struct crypto_skcipher *cipher = crypto_skcipher_reqtfm(areq);
1643373960d7SArd Biesheuvel struct talitos_ctx *ctx = crypto_skcipher_ctx(cipher);
1644373960d7SArd Biesheuvel unsigned int ivsize = crypto_skcipher_ivsize(cipher);
16454de9d0b5SLee Nipper
1646aeb4c132SHerbert Xu return talitos_edesc_alloc(ctx->dev, areq->src, areq->dst,
1647373960d7SArd Biesheuvel areq->iv, 0, areq->cryptlen, 0, ivsize, 0,
164862293a37SHoria Geanta areq->base.flags, encrypt);
16494de9d0b5SLee Nipper }
16504de9d0b5SLee Nipper
skcipher_encrypt(struct skcipher_request * areq)1651373960d7SArd Biesheuvel static int skcipher_encrypt(struct skcipher_request *areq)
16524de9d0b5SLee Nipper {
1653373960d7SArd Biesheuvel struct crypto_skcipher *cipher = crypto_skcipher_reqtfm(areq);
1654373960d7SArd Biesheuvel struct talitos_ctx *ctx = crypto_skcipher_ctx(cipher);
16554de9d0b5SLee Nipper struct talitos_edesc *edesc;
1656ee483d32SChristophe Leroy unsigned int blocksize =
1657373960d7SArd Biesheuvel crypto_tfm_alg_blocksize(crypto_skcipher_tfm(cipher));
1658ee483d32SChristophe Leroy
1659373960d7SArd Biesheuvel if (!areq->cryptlen)
1660ee483d32SChristophe Leroy return 0;
1661ee483d32SChristophe Leroy
1662373960d7SArd Biesheuvel if (areq->cryptlen % blocksize)
1663ee483d32SChristophe Leroy return -EINVAL;
16644de9d0b5SLee Nipper
16654de9d0b5SLee Nipper /* allocate extended descriptor */
1666373960d7SArd Biesheuvel edesc = skcipher_edesc_alloc(areq, true);
16674de9d0b5SLee Nipper if (IS_ERR(edesc))
16684de9d0b5SLee Nipper return PTR_ERR(edesc);
16694de9d0b5SLee Nipper
16704de9d0b5SLee Nipper /* set encrypt */
16714de9d0b5SLee Nipper edesc->desc.hdr = ctx->desc_hdr_template | DESC_HDR_MODE0_ENCRYPT;
16724de9d0b5SLee Nipper
1673373960d7SArd Biesheuvel return common_nonsnoop(edesc, areq, skcipher_done);
16744de9d0b5SLee Nipper }
16754de9d0b5SLee Nipper
skcipher_decrypt(struct skcipher_request * areq)1676373960d7SArd Biesheuvel static int skcipher_decrypt(struct skcipher_request *areq)
16774de9d0b5SLee Nipper {
1678373960d7SArd Biesheuvel struct crypto_skcipher *cipher = crypto_skcipher_reqtfm(areq);
1679373960d7SArd Biesheuvel struct talitos_ctx *ctx = crypto_skcipher_ctx(cipher);
16804de9d0b5SLee Nipper struct talitos_edesc *edesc;
1681ee483d32SChristophe Leroy unsigned int blocksize =
1682373960d7SArd Biesheuvel crypto_tfm_alg_blocksize(crypto_skcipher_tfm(cipher));
1683ee483d32SChristophe Leroy
1684373960d7SArd Biesheuvel if (!areq->cryptlen)
1685ee483d32SChristophe Leroy return 0;
1686ee483d32SChristophe Leroy
1687373960d7SArd Biesheuvel if (areq->cryptlen % blocksize)
1688ee483d32SChristophe Leroy return -EINVAL;
16894de9d0b5SLee Nipper
16904de9d0b5SLee Nipper /* allocate extended descriptor */
1691373960d7SArd Biesheuvel edesc = skcipher_edesc_alloc(areq, false);
16924de9d0b5SLee Nipper if (IS_ERR(edesc))
16934de9d0b5SLee Nipper return PTR_ERR(edesc);
16944de9d0b5SLee Nipper
16954de9d0b5SLee Nipper edesc->desc.hdr = ctx->desc_hdr_template | DESC_HDR_DIR_INBOUND;
16964de9d0b5SLee Nipper
1697373960d7SArd Biesheuvel return common_nonsnoop(edesc, areq, skcipher_done);
16984de9d0b5SLee Nipper }
16994de9d0b5SLee Nipper
common_nonsnoop_hash_unmap(struct device * dev,struct talitos_edesc * edesc,struct ahash_request * areq)1700497f2e6bSLee Nipper static void common_nonsnoop_hash_unmap(struct device *dev,
1701497f2e6bSLee Nipper struct talitos_edesc *edesc,
1702497f2e6bSLee Nipper struct ahash_request *areq)
1703497f2e6bSLee Nipper {
1704497f2e6bSLee Nipper struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
17057a6eda5bSChristophe Leroy struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
1706ad4cd51fSLEROY Christophe struct talitos_private *priv = dev_get_drvdata(dev);
1707ad4cd51fSLEROY Christophe bool is_sec1 = has_ftr_sec1(priv);
1708ad4cd51fSLEROY Christophe struct talitos_desc *desc = &edesc->desc;
170958cdbc6dSChristophe Leroy struct talitos_desc *desc2 = (struct talitos_desc *)
171058cdbc6dSChristophe Leroy (edesc->buf + edesc->dma_len);
1711ad4cd51fSLEROY Christophe
17126ae7a8b1Sjianchunfu unmap_single_talitos_ptr(dev, &desc->ptr[5], DMA_FROM_DEVICE);
1713ad4cd51fSLEROY Christophe if (desc->next_desc &&
1714ad4cd51fSLEROY Christophe desc->ptr[5].ptr != desc2->ptr[5].ptr)
1715ad4cd51fSLEROY Christophe unmap_single_talitos_ptr(dev, &desc2->ptr[5], DMA_FROM_DEVICE);
17167a6eda5bSChristophe Leroy if (req_ctx->last)
17177a6eda5bSChristophe Leroy memcpy(areq->result, req_ctx->hw_context,
17187a6eda5bSChristophe Leroy crypto_ahash_digestsize(tfm));
1719497f2e6bSLee Nipper
172058cdbc6dSChristophe Leroy if (req_ctx->psrc)
17216a1e8d14SLEROY Christophe talitos_sg_unmap(dev, edesc, req_ctx->psrc, NULL, 0, 0);
1722032d197eSLEROY Christophe
1723ad4cd51fSLEROY Christophe /* When using hashctx-in, must unmap it. */
17246ae7a8b1Sjianchunfu if (from_talitos_ptr_len(&desc->ptr[1], is_sec1))
17256ae7a8b1Sjianchunfu unmap_single_talitos_ptr(dev, &desc->ptr[1],
1726ad4cd51fSLEROY Christophe DMA_TO_DEVICE);
1727ad4cd51fSLEROY Christophe else if (desc->next_desc)
1728ad4cd51fSLEROY Christophe unmap_single_talitos_ptr(dev, &desc2->ptr[1],
1729ad4cd51fSLEROY Christophe DMA_TO_DEVICE);
1730ad4cd51fSLEROY Christophe
1731ad4cd51fSLEROY Christophe if (is_sec1 && req_ctx->nbuf)
1732ad4cd51fSLEROY Christophe unmap_single_talitos_ptr(dev, &desc->ptr[3],
1733ad4cd51fSLEROY Christophe DMA_TO_DEVICE);
1734ad4cd51fSLEROY Christophe
1735497f2e6bSLee Nipper if (edesc->dma_len)
1736497f2e6bSLee Nipper dma_unmap_single(dev, edesc->dma_link_tbl, edesc->dma_len,
1737497f2e6bSLee Nipper DMA_BIDIRECTIONAL);
1738497f2e6bSLee Nipper
17396ae7a8b1Sjianchunfu if (desc->next_desc)
17406ae7a8b1Sjianchunfu dma_unmap_single(dev, be32_to_cpu(desc->next_desc),
174137b5e889SLEROY Christophe TALITOS_DESC_SIZE, DMA_BIDIRECTIONAL);
1742497f2e6bSLee Nipper }
1743497f2e6bSLee Nipper
ahash_done(struct device * dev,struct talitos_desc * desc,void * context,int err)1744497f2e6bSLee Nipper static void ahash_done(struct device *dev,
1745497f2e6bSLee Nipper struct talitos_desc *desc, void *context,
1746497f2e6bSLee Nipper int err)
1747497f2e6bSLee Nipper {
1748497f2e6bSLee Nipper struct ahash_request *areq = context;
1749497f2e6bSLee Nipper struct talitos_edesc *edesc =
1750497f2e6bSLee Nipper container_of(desc, struct talitos_edesc, desc);
1751497f2e6bSLee Nipper struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
1752497f2e6bSLee Nipper
1753497f2e6bSLee Nipper if (!req_ctx->last && req_ctx->to_hash_later) {
1754497f2e6bSLee Nipper /* Position any partial block for next update/final/finup */
17553c0dd190SLEROY Christophe req_ctx->buf_idx = (req_ctx->buf_idx + 1) & 1;
17565e833bc4SLee Nipper req_ctx->nbuf = req_ctx->to_hash_later;
1757497f2e6bSLee Nipper }
1758497f2e6bSLee Nipper common_nonsnoop_hash_unmap(dev, edesc, areq);
1759497f2e6bSLee Nipper
1760497f2e6bSLee Nipper kfree(edesc);
1761497f2e6bSLee Nipper
1762234650bdSHerbert Xu ahash_request_complete(areq, err);
1763497f2e6bSLee Nipper }
1764497f2e6bSLee Nipper
17652d02905eSLEROY Christophe /*
17662d02905eSLEROY Christophe * SEC1 doesn't like hashing of 0 sized message, so we do the padding
17672d02905eSLEROY Christophe * ourself and submit a padded block
17682d02905eSLEROY Christophe */
talitos_handle_buggy_hash(struct talitos_ctx * ctx,struct talitos_edesc * edesc,struct talitos_ptr * ptr)17695b2cf268SLEROY Christophe static void talitos_handle_buggy_hash(struct talitos_ctx *ctx,
17702d02905eSLEROY Christophe struct talitos_edesc *edesc,
17712d02905eSLEROY Christophe struct talitos_ptr *ptr)
17722d02905eSLEROY Christophe {
17732d02905eSLEROY Christophe static u8 padded_hash[64] = {
17742d02905eSLEROY Christophe 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
17752d02905eSLEROY Christophe 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
17762d02905eSLEROY Christophe 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
17772d02905eSLEROY Christophe 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
17782d02905eSLEROY Christophe };
17792d02905eSLEROY Christophe
17802d02905eSLEROY Christophe pr_err_once("Bug in SEC1, padding ourself\n");
17812d02905eSLEROY Christophe edesc->desc.hdr &= ~DESC_HDR_MODE0_MDEU_PAD;
17822d02905eSLEROY Christophe map_single_talitos_ptr(ctx->dev, ptr, sizeof(padded_hash),
17832d02905eSLEROY Christophe (char *)padded_hash, DMA_TO_DEVICE);
17842d02905eSLEROY Christophe }
17852d02905eSLEROY Christophe
common_nonsnoop_hash(struct talitos_edesc * edesc,struct ahash_request * areq,unsigned int length,void (* callback)(struct device * dev,struct talitos_desc * desc,void * context,int error))1786497f2e6bSLee Nipper static int common_nonsnoop_hash(struct talitos_edesc *edesc,
1787497f2e6bSLee Nipper struct ahash_request *areq, unsigned int length,
1788497f2e6bSLee Nipper void (*callback) (struct device *dev,
1789497f2e6bSLee Nipper struct talitos_desc *desc,
1790497f2e6bSLee Nipper void *context, int error))
1791497f2e6bSLee Nipper {
1792497f2e6bSLee Nipper struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
1793497f2e6bSLee Nipper struct talitos_ctx *ctx = crypto_ahash_ctx(tfm);
1794497f2e6bSLee Nipper struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
1795497f2e6bSLee Nipper struct device *dev = ctx->dev;
1796497f2e6bSLee Nipper struct talitos_desc *desc = &edesc->desc;
1797032d197eSLEROY Christophe int ret;
17986a1e8d14SLEROY Christophe bool sync_needed = false;
1799922f9dc8SLEROY Christophe struct talitos_private *priv = dev_get_drvdata(dev);
1800922f9dc8SLEROY Christophe bool is_sec1 = has_ftr_sec1(priv);
18016a1e8d14SLEROY Christophe int sg_count;
1802497f2e6bSLee Nipper
1803497f2e6bSLee Nipper /* first DWORD empty */
1804497f2e6bSLee Nipper
180560f208d7SKim Phillips /* hash context in */
180660f208d7SKim Phillips if (!req_ctx->first || req_ctx->swinit) {
18076a4967c3SLEROY Christophe map_single_talitos_ptr_nosync(dev, &desc->ptr[1],
1808ad4cd51fSLEROY Christophe req_ctx->hw_context_size,
18096a4967c3SLEROY Christophe req_ctx->hw_context,
1810ad4cd51fSLEROY Christophe DMA_TO_DEVICE);
181160f208d7SKim Phillips req_ctx->swinit = 0;
1812afd62fa2SLEROY Christophe }
1813497f2e6bSLee Nipper /* Indicate next op is not the first. */
1814497f2e6bSLee Nipper req_ctx->first = 0;
1815497f2e6bSLee Nipper
1816497f2e6bSLee Nipper /* HMAC key */
1817497f2e6bSLee Nipper if (ctx->keylen)
18182e13ce08SLEROY Christophe to_talitos_ptr(&desc->ptr[2], ctx->dma_key, ctx->keylen,
18192e13ce08SLEROY Christophe is_sec1);
1820497f2e6bSLee Nipper
182137b5e889SLEROY Christophe if (is_sec1 && req_ctx->nbuf)
182237b5e889SLEROY Christophe length -= req_ctx->nbuf;
182337b5e889SLEROY Christophe
18246a1e8d14SLEROY Christophe sg_count = edesc->src_nents ?: 1;
18256a1e8d14SLEROY Christophe if (is_sec1 && sg_count > 1)
182658cdbc6dSChristophe Leroy sg_copy_to_buffer(req_ctx->psrc, sg_count, edesc->buf, length);
182737b5e889SLEROY Christophe else if (length)
18286a1e8d14SLEROY Christophe sg_count = dma_map_sg(dev, req_ctx->psrc, sg_count,
18296a1e8d14SLEROY Christophe DMA_TO_DEVICE);
1830497f2e6bSLee Nipper /*
1831497f2e6bSLee Nipper * data in
1832497f2e6bSLee Nipper */
183337b5e889SLEROY Christophe if (is_sec1 && req_ctx->nbuf) {
1834ad4cd51fSLEROY Christophe map_single_talitos_ptr(dev, &desc->ptr[3], req_ctx->nbuf,
1835ad4cd51fSLEROY Christophe req_ctx->buf[req_ctx->buf_idx],
1836ad4cd51fSLEROY Christophe DMA_TO_DEVICE);
183737b5e889SLEROY Christophe } else {
18386a1e8d14SLEROY Christophe sg_count = talitos_sg_map(dev, req_ctx->psrc, length, edesc,
183958cdbc6dSChristophe Leroy &desc->ptr[3], sg_count, 0, 0);
18406a1e8d14SLEROY Christophe if (sg_count > 1)
18416a1e8d14SLEROY Christophe sync_needed = true;
184237b5e889SLEROY Christophe }
1843497f2e6bSLee Nipper
1844497f2e6bSLee Nipper /* fifth DWORD empty */
1845497f2e6bSLee Nipper
1846497f2e6bSLee Nipper /* hash/HMAC out -or- hash context out */
1847497f2e6bSLee Nipper if (req_ctx->last)
1848497f2e6bSLee Nipper map_single_talitos_ptr(dev, &desc->ptr[5],
1849497f2e6bSLee Nipper crypto_ahash_digestsize(tfm),
18507a6eda5bSChristophe Leroy req_ctx->hw_context, DMA_FROM_DEVICE);
1851497f2e6bSLee Nipper else
18526a4967c3SLEROY Christophe map_single_talitos_ptr_nosync(dev, &desc->ptr[5],
1853ad4cd51fSLEROY Christophe req_ctx->hw_context_size,
18546a4967c3SLEROY Christophe req_ctx->hw_context,
18556a4967c3SLEROY Christophe DMA_FROM_DEVICE);
1856497f2e6bSLee Nipper
1857497f2e6bSLee Nipper /* last DWORD empty */
1858497f2e6bSLee Nipper
18592d02905eSLEROY Christophe if (is_sec1 && from_talitos_ptr_len(&desc->ptr[3], true) == 0)
18602d02905eSLEROY Christophe talitos_handle_buggy_hash(ctx, edesc, &desc->ptr[3]);
18612d02905eSLEROY Christophe
186237b5e889SLEROY Christophe if (is_sec1 && req_ctx->nbuf && length) {
186358cdbc6dSChristophe Leroy struct talitos_desc *desc2 = (struct talitos_desc *)
186458cdbc6dSChristophe Leroy (edesc->buf + edesc->dma_len);
186537b5e889SLEROY Christophe dma_addr_t next_desc;
186637b5e889SLEROY Christophe
186737b5e889SLEROY Christophe memset(desc2, 0, sizeof(*desc2));
186837b5e889SLEROY Christophe desc2->hdr = desc->hdr;
186937b5e889SLEROY Christophe desc2->hdr &= ~DESC_HDR_MODE0_MDEU_INIT;
187037b5e889SLEROY Christophe desc2->hdr1 = desc2->hdr;
187137b5e889SLEROY Christophe desc->hdr &= ~DESC_HDR_MODE0_MDEU_PAD;
187237b5e889SLEROY Christophe desc->hdr |= DESC_HDR_MODE0_MDEU_CONT;
187337b5e889SLEROY Christophe desc->hdr &= ~DESC_HDR_DONE_NOTIFY;
187437b5e889SLEROY Christophe
1875ad4cd51fSLEROY Christophe if (desc->ptr[1].ptr)
1876ad4cd51fSLEROY Christophe copy_talitos_ptr(&desc2->ptr[1], &desc->ptr[1],
1877ad4cd51fSLEROY Christophe is_sec1);
1878ad4cd51fSLEROY Christophe else
18796a4967c3SLEROY Christophe map_single_talitos_ptr_nosync(dev, &desc2->ptr[1],
1880ad4cd51fSLEROY Christophe req_ctx->hw_context_size,
1881ad4cd51fSLEROY Christophe req_ctx->hw_context,
1882ad4cd51fSLEROY Christophe DMA_TO_DEVICE);
188337b5e889SLEROY Christophe copy_talitos_ptr(&desc2->ptr[2], &desc->ptr[2], is_sec1);
188437b5e889SLEROY Christophe sg_count = talitos_sg_map(dev, req_ctx->psrc, length, edesc,
188558cdbc6dSChristophe Leroy &desc2->ptr[3], sg_count, 0, 0);
188637b5e889SLEROY Christophe if (sg_count > 1)
188737b5e889SLEROY Christophe sync_needed = true;
188837b5e889SLEROY Christophe copy_talitos_ptr(&desc2->ptr[5], &desc->ptr[5], is_sec1);
188937b5e889SLEROY Christophe if (req_ctx->last)
18906a4967c3SLEROY Christophe map_single_talitos_ptr_nosync(dev, &desc->ptr[5],
1891ad4cd51fSLEROY Christophe req_ctx->hw_context_size,
1892ad4cd51fSLEROY Christophe req_ctx->hw_context,
1893ad4cd51fSLEROY Christophe DMA_FROM_DEVICE);
189437b5e889SLEROY Christophe
189537b5e889SLEROY Christophe next_desc = dma_map_single(dev, &desc2->hdr1, TALITOS_DESC_SIZE,
189637b5e889SLEROY Christophe DMA_BIDIRECTIONAL);
189737b5e889SLEROY Christophe desc->next_desc = cpu_to_be32(next_desc);
189837b5e889SLEROY Christophe }
189937b5e889SLEROY Christophe
19006a1e8d14SLEROY Christophe if (sync_needed)
19016a1e8d14SLEROY Christophe dma_sync_single_for_device(dev, edesc->dma_link_tbl,
19026a1e8d14SLEROY Christophe edesc->dma_len, DMA_BIDIRECTIONAL);
19036a1e8d14SLEROY Christophe
19045228f0f7SKim Phillips ret = talitos_submit(dev, ctx->ch, desc, callback, areq);
1905497f2e6bSLee Nipper if (ret != -EINPROGRESS) {
1906497f2e6bSLee Nipper common_nonsnoop_hash_unmap(dev, edesc, areq);
1907497f2e6bSLee Nipper kfree(edesc);
1908497f2e6bSLee Nipper }
1909497f2e6bSLee Nipper return ret;
1910497f2e6bSLee Nipper }
1911497f2e6bSLee Nipper
ahash_edesc_alloc(struct ahash_request * areq,unsigned int nbytes)1912497f2e6bSLee Nipper static struct talitos_edesc *ahash_edesc_alloc(struct ahash_request *areq,
1913497f2e6bSLee Nipper unsigned int nbytes)
1914497f2e6bSLee Nipper {
1915497f2e6bSLee Nipper struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
1916497f2e6bSLee Nipper struct talitos_ctx *ctx = crypto_ahash_ctx(tfm);
1917497f2e6bSLee Nipper struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
191837b5e889SLEROY Christophe struct talitos_private *priv = dev_get_drvdata(ctx->dev);
191937b5e889SLEROY Christophe bool is_sec1 = has_ftr_sec1(priv);
192037b5e889SLEROY Christophe
192137b5e889SLEROY Christophe if (is_sec1)
192237b5e889SLEROY Christophe nbytes -= req_ctx->nbuf;
1923497f2e6bSLee Nipper
1924aeb4c132SHerbert Xu return talitos_edesc_alloc(ctx->dev, req_ctx->psrc, NULL, NULL, 0,
192562293a37SHoria Geanta nbytes, 0, 0, 0, areq->base.flags, false);
1926497f2e6bSLee Nipper }
1927497f2e6bSLee Nipper
ahash_init(struct ahash_request * areq)1928497f2e6bSLee Nipper static int ahash_init(struct ahash_request *areq)
1929497f2e6bSLee Nipper {
1930497f2e6bSLee Nipper struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
19316a4967c3SLEROY Christophe struct talitos_ctx *ctx = crypto_ahash_ctx(tfm);
19326a4967c3SLEROY Christophe struct device *dev = ctx->dev;
1933497f2e6bSLee Nipper struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
193449f9783bSLEROY Christophe unsigned int size;
19356a4967c3SLEROY Christophe dma_addr_t dma;
1936497f2e6bSLee Nipper
1937497f2e6bSLee Nipper /* Initialize the context */
19383c0dd190SLEROY Christophe req_ctx->buf_idx = 0;
19395e833bc4SLee Nipper req_ctx->nbuf = 0;
194060f208d7SKim Phillips req_ctx->first = 1; /* first indicates h/w must init its context */
194160f208d7SKim Phillips req_ctx->swinit = 0; /* assume h/w init of context */
194249f9783bSLEROY Christophe size = (crypto_ahash_digestsize(tfm) <= SHA256_DIGEST_SIZE)
1943497f2e6bSLee Nipper ? TALITOS_MDEU_CONTEXT_SIZE_MD5_SHA1_SHA256
1944497f2e6bSLee Nipper : TALITOS_MDEU_CONTEXT_SIZE_SHA384_SHA512;
194549f9783bSLEROY Christophe req_ctx->hw_context_size = size;
1946497f2e6bSLee Nipper
19476a4967c3SLEROY Christophe dma = dma_map_single(dev, req_ctx->hw_context, req_ctx->hw_context_size,
19486a4967c3SLEROY Christophe DMA_TO_DEVICE);
19496a4967c3SLEROY Christophe dma_unmap_single(dev, dma, req_ctx->hw_context_size, DMA_TO_DEVICE);
19506a4967c3SLEROY Christophe
1951497f2e6bSLee Nipper return 0;
1952497f2e6bSLee Nipper }
1953497f2e6bSLee Nipper
195460f208d7SKim Phillips /*
195560f208d7SKim Phillips * on h/w without explicit sha224 support, we initialize h/w context
195660f208d7SKim Phillips * manually with sha224 constants, and tell it to run sha256.
195760f208d7SKim Phillips */
ahash_init_sha224_swinit(struct ahash_request * areq)195860f208d7SKim Phillips static int ahash_init_sha224_swinit(struct ahash_request *areq)
195960f208d7SKim Phillips {
196060f208d7SKim Phillips struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
196160f208d7SKim Phillips
1962a752447aSKim Phillips req_ctx->hw_context[0] = SHA224_H0;
1963a752447aSKim Phillips req_ctx->hw_context[1] = SHA224_H1;
1964a752447aSKim Phillips req_ctx->hw_context[2] = SHA224_H2;
1965a752447aSKim Phillips req_ctx->hw_context[3] = SHA224_H3;
1966a752447aSKim Phillips req_ctx->hw_context[4] = SHA224_H4;
1967a752447aSKim Phillips req_ctx->hw_context[5] = SHA224_H5;
1968a752447aSKim Phillips req_ctx->hw_context[6] = SHA224_H6;
1969a752447aSKim Phillips req_ctx->hw_context[7] = SHA224_H7;
197060f208d7SKim Phillips
197160f208d7SKim Phillips /* init 64-bit count */
197260f208d7SKim Phillips req_ctx->hw_context[8] = 0;
197360f208d7SKim Phillips req_ctx->hw_context[9] = 0;
197460f208d7SKim Phillips
19756a4967c3SLEROY Christophe ahash_init(areq);
19766a4967c3SLEROY Christophe req_ctx->swinit = 1;/* prevent h/w initting context with sha256 values*/
19776a4967c3SLEROY Christophe
197860f208d7SKim Phillips return 0;
197960f208d7SKim Phillips }
198060f208d7SKim Phillips
ahash_process_req(struct ahash_request * areq,unsigned int nbytes)1981497f2e6bSLee Nipper static int ahash_process_req(struct ahash_request *areq, unsigned int nbytes)
1982497f2e6bSLee Nipper {
1983497f2e6bSLee Nipper struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
1984497f2e6bSLee Nipper struct talitos_ctx *ctx = crypto_ahash_ctx(tfm);
1985497f2e6bSLee Nipper struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
1986497f2e6bSLee Nipper struct talitos_edesc *edesc;
1987497f2e6bSLee Nipper unsigned int blocksize =
1988497f2e6bSLee Nipper crypto_tfm_alg_blocksize(crypto_ahash_tfm(tfm));
1989497f2e6bSLee Nipper unsigned int nbytes_to_hash;
1990497f2e6bSLee Nipper unsigned int to_hash_later;
19915e833bc4SLee Nipper unsigned int nsg;
19928e409fe1SLABBE Corentin int nents;
199337b5e889SLEROY Christophe struct device *dev = ctx->dev;
199437b5e889SLEROY Christophe struct talitos_private *priv = dev_get_drvdata(dev);
199537b5e889SLEROY Christophe bool is_sec1 = has_ftr_sec1(priv);
19963c0dd190SLEROY Christophe u8 *ctx_buf = req_ctx->buf[req_ctx->buf_idx];
1997497f2e6bSLee Nipper
19985e833bc4SLee Nipper if (!req_ctx->last && (nbytes + req_ctx->nbuf <= blocksize)) {
19995e833bc4SLee Nipper /* Buffer up to one whole block */
20008e409fe1SLABBE Corentin nents = sg_nents_for_len(areq->src, nbytes);
20018e409fe1SLABBE Corentin if (nents < 0) {
2002854e25a6Sjianchunfu dev_err(dev, "Invalid number of src SG.\n");
20038e409fe1SLABBE Corentin return nents;
20048e409fe1SLABBE Corentin }
20058e409fe1SLABBE Corentin sg_copy_to_buffer(areq->src, nents,
20063c0dd190SLEROY Christophe ctx_buf + req_ctx->nbuf, nbytes);
20075e833bc4SLee Nipper req_ctx->nbuf += nbytes;
2008497f2e6bSLee Nipper return 0;
2009497f2e6bSLee Nipper }
2010497f2e6bSLee Nipper
20115e833bc4SLee Nipper /* At least (blocksize + 1) bytes are available to hash */
20125e833bc4SLee Nipper nbytes_to_hash = nbytes + req_ctx->nbuf;
20135e833bc4SLee Nipper to_hash_later = nbytes_to_hash & (blocksize - 1);
20145e833bc4SLee Nipper
20155e833bc4SLee Nipper if (req_ctx->last)
20165e833bc4SLee Nipper to_hash_later = 0;
20175e833bc4SLee Nipper else if (to_hash_later)
20185e833bc4SLee Nipper /* There is a partial block. Hash the full block(s) now */
20195e833bc4SLee Nipper nbytes_to_hash -= to_hash_later;
20205e833bc4SLee Nipper else {
20215e833bc4SLee Nipper /* Keep one block buffered */
20225e833bc4SLee Nipper nbytes_to_hash -= blocksize;
20235e833bc4SLee Nipper to_hash_later = blocksize;
2024497f2e6bSLee Nipper }
20255e833bc4SLee Nipper
20265e833bc4SLee Nipper /* Chain in any previously buffered data */
202737b5e889SLEROY Christophe if (!is_sec1 && req_ctx->nbuf) {
20285e833bc4SLee Nipper nsg = (req_ctx->nbuf < nbytes_to_hash) ? 2 : 1;
20295e833bc4SLee Nipper sg_init_table(req_ctx->bufsl, nsg);
20303c0dd190SLEROY Christophe sg_set_buf(req_ctx->bufsl, ctx_buf, req_ctx->nbuf);
20315e833bc4SLee Nipper if (nsg > 1)
2032c56f6d12SDan Williams sg_chain(req_ctx->bufsl, 2, areq->src);
20335e833bc4SLee Nipper req_ctx->psrc = req_ctx->bufsl;
203437b5e889SLEROY Christophe } else if (is_sec1 && req_ctx->nbuf && req_ctx->nbuf < blocksize) {
203558cdbc6dSChristophe Leroy int offset;
203658cdbc6dSChristophe Leroy
203737b5e889SLEROY Christophe if (nbytes_to_hash > blocksize)
203837b5e889SLEROY Christophe offset = blocksize - req_ctx->nbuf;
203937b5e889SLEROY Christophe else
204037b5e889SLEROY Christophe offset = nbytes_to_hash - req_ctx->nbuf;
204137b5e889SLEROY Christophe nents = sg_nents_for_len(areq->src, offset);
204237b5e889SLEROY Christophe if (nents < 0) {
2043854e25a6Sjianchunfu dev_err(dev, "Invalid number of src SG.\n");
204437b5e889SLEROY Christophe return nents;
204537b5e889SLEROY Christophe }
204637b5e889SLEROY Christophe sg_copy_to_buffer(areq->src, nents,
20473c0dd190SLEROY Christophe ctx_buf + req_ctx->nbuf, offset);
204837b5e889SLEROY Christophe req_ctx->nbuf += offset;
204958cdbc6dSChristophe Leroy req_ctx->psrc = scatterwalk_ffwd(req_ctx->bufsl, areq->src,
205058cdbc6dSChristophe Leroy offset);
20515e833bc4SLee Nipper } else
20525e833bc4SLee Nipper req_ctx->psrc = areq->src;
20535e833bc4SLee Nipper
2054497f2e6bSLee Nipper if (to_hash_later) {
20558e409fe1SLABBE Corentin nents = sg_nents_for_len(areq->src, nbytes);
20568e409fe1SLABBE Corentin if (nents < 0) {
2057854e25a6Sjianchunfu dev_err(dev, "Invalid number of src SG.\n");
20588e409fe1SLABBE Corentin return nents;
20598e409fe1SLABBE Corentin }
2060d0525723SAkinobu Mita sg_pcopy_to_buffer(areq->src, nents,
20613c0dd190SLEROY Christophe req_ctx->buf[(req_ctx->buf_idx + 1) & 1],
2062497f2e6bSLee Nipper to_hash_later,
2063497f2e6bSLee Nipper nbytes - to_hash_later);
2064497f2e6bSLee Nipper }
2065497f2e6bSLee Nipper req_ctx->to_hash_later = to_hash_later;
2066497f2e6bSLee Nipper
20675e833bc4SLee Nipper /* Allocate extended descriptor */
2068497f2e6bSLee Nipper edesc = ahash_edesc_alloc(areq, nbytes_to_hash);
2069497f2e6bSLee Nipper if (IS_ERR(edesc))
2070497f2e6bSLee Nipper return PTR_ERR(edesc);
2071497f2e6bSLee Nipper
2072497f2e6bSLee Nipper edesc->desc.hdr = ctx->desc_hdr_template;
2073497f2e6bSLee Nipper
2074497f2e6bSLee Nipper /* On last one, request SEC to pad; otherwise continue */
2075497f2e6bSLee Nipper if (req_ctx->last)
2076497f2e6bSLee Nipper edesc->desc.hdr |= DESC_HDR_MODE0_MDEU_PAD;
2077497f2e6bSLee Nipper else
2078497f2e6bSLee Nipper edesc->desc.hdr |= DESC_HDR_MODE0_MDEU_CONT;
2079497f2e6bSLee Nipper
208060f208d7SKim Phillips /* request SEC to INIT hash. */
208160f208d7SKim Phillips if (req_ctx->first && !req_ctx->swinit)
2082497f2e6bSLee Nipper edesc->desc.hdr |= DESC_HDR_MODE0_MDEU_INIT;
2083497f2e6bSLee Nipper
2084497f2e6bSLee Nipper /* When the tfm context has a keylen, it's an HMAC.
2085497f2e6bSLee Nipper * A first or last (ie. not middle) descriptor must request HMAC.
2086497f2e6bSLee Nipper */
2087497f2e6bSLee Nipper if (ctx->keylen && (req_ctx->first || req_ctx->last))
2088497f2e6bSLee Nipper edesc->desc.hdr |= DESC_HDR_MODE0_MDEU_HMAC;
2089497f2e6bSLee Nipper
209058cdbc6dSChristophe Leroy return common_nonsnoop_hash(edesc, areq, nbytes_to_hash, ahash_done);
2091497f2e6bSLee Nipper }
2092497f2e6bSLee Nipper
ahash_update(struct ahash_request * areq)2093497f2e6bSLee Nipper static int ahash_update(struct ahash_request *areq)
2094497f2e6bSLee Nipper {
2095497f2e6bSLee Nipper struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
2096497f2e6bSLee Nipper
2097497f2e6bSLee Nipper req_ctx->last = 0;
2098497f2e6bSLee Nipper
2099497f2e6bSLee Nipper return ahash_process_req(areq, areq->nbytes);
2100497f2e6bSLee Nipper }
2101497f2e6bSLee Nipper
ahash_final(struct ahash_request * areq)2102497f2e6bSLee Nipper static int ahash_final(struct ahash_request *areq)
2103497f2e6bSLee Nipper {
2104497f2e6bSLee Nipper struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
2105497f2e6bSLee Nipper
2106497f2e6bSLee Nipper req_ctx->last = 1;
2107497f2e6bSLee Nipper
2108497f2e6bSLee Nipper return ahash_process_req(areq, 0);
2109497f2e6bSLee Nipper }
2110497f2e6bSLee Nipper
ahash_finup(struct ahash_request * areq)2111497f2e6bSLee Nipper static int ahash_finup(struct ahash_request *areq)
2112497f2e6bSLee Nipper {
2113497f2e6bSLee Nipper struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
2114497f2e6bSLee Nipper
2115497f2e6bSLee Nipper req_ctx->last = 1;
2116497f2e6bSLee Nipper
2117497f2e6bSLee Nipper return ahash_process_req(areq, areq->nbytes);
2118497f2e6bSLee Nipper }
2119497f2e6bSLee Nipper
ahash_digest(struct ahash_request * areq)2120497f2e6bSLee Nipper static int ahash_digest(struct ahash_request *areq)
2121497f2e6bSLee Nipper {
2122*9826d1d6SEric Biggers ahash_init(areq);
2123*9826d1d6SEric Biggers return ahash_finup(areq);
2124*9826d1d6SEric Biggers }
2125497f2e6bSLee Nipper
ahash_digest_sha224_swinit(struct ahash_request * areq)2126*9826d1d6SEric Biggers static int ahash_digest_sha224_swinit(struct ahash_request *areq)
2127*9826d1d6SEric Biggers {
2128*9826d1d6SEric Biggers ahash_init_sha224_swinit(areq);
2129*9826d1d6SEric Biggers return ahash_finup(areq);
2130497f2e6bSLee Nipper }
2131497f2e6bSLee Nipper
ahash_export(struct ahash_request * areq,void * out)21323639ca84SHoria Geant? static int ahash_export(struct ahash_request *areq, void *out)
21333639ca84SHoria Geant? {
21343639ca84SHoria Geant? struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
21353639ca84SHoria Geant? struct talitos_export_state *export = out;
21366a4967c3SLEROY Christophe struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
21376a4967c3SLEROY Christophe struct talitos_ctx *ctx = crypto_ahash_ctx(tfm);
21386a4967c3SLEROY Christophe struct device *dev = ctx->dev;
21396a4967c3SLEROY Christophe dma_addr_t dma;
21406a4967c3SLEROY Christophe
21416a4967c3SLEROY Christophe dma = dma_map_single(dev, req_ctx->hw_context, req_ctx->hw_context_size,
21426a4967c3SLEROY Christophe DMA_FROM_DEVICE);
21436a4967c3SLEROY Christophe dma_unmap_single(dev, dma, req_ctx->hw_context_size, DMA_FROM_DEVICE);
21443639ca84SHoria Geant?
21453639ca84SHoria Geant? memcpy(export->hw_context, req_ctx->hw_context,
21463639ca84SHoria Geant? req_ctx->hw_context_size);
21473c0dd190SLEROY Christophe memcpy(export->buf, req_ctx->buf[req_ctx->buf_idx], req_ctx->nbuf);
21483639ca84SHoria Geant? export->swinit = req_ctx->swinit;
21493639ca84SHoria Geant? export->first = req_ctx->first;
21503639ca84SHoria Geant? export->last = req_ctx->last;
21513639ca84SHoria Geant? export->to_hash_later = req_ctx->to_hash_later;
21523639ca84SHoria Geant? export->nbuf = req_ctx->nbuf;
21533639ca84SHoria Geant?
21543639ca84SHoria Geant? return 0;
21553639ca84SHoria Geant? }
21563639ca84SHoria Geant?
ahash_import(struct ahash_request * areq,const void * in)21573639ca84SHoria Geant? static int ahash_import(struct ahash_request *areq, const void *in)
21583639ca84SHoria Geant? {
21593639ca84SHoria Geant? struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
21603639ca84SHoria Geant? struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
21616a4967c3SLEROY Christophe struct talitos_ctx *ctx = crypto_ahash_ctx(tfm);
21626a4967c3SLEROY Christophe struct device *dev = ctx->dev;
21633639ca84SHoria Geant? const struct talitos_export_state *export = in;
216449f9783bSLEROY Christophe unsigned int size;
21656a4967c3SLEROY Christophe dma_addr_t dma;
21663639ca84SHoria Geant?
21673639ca84SHoria Geant? memset(req_ctx, 0, sizeof(*req_ctx));
216849f9783bSLEROY Christophe size = (crypto_ahash_digestsize(tfm) <= SHA256_DIGEST_SIZE)
21693639ca84SHoria Geant? ? TALITOS_MDEU_CONTEXT_SIZE_MD5_SHA1_SHA256
21703639ca84SHoria Geant? : TALITOS_MDEU_CONTEXT_SIZE_SHA384_SHA512;
217149f9783bSLEROY Christophe req_ctx->hw_context_size = size;
217249f9783bSLEROY Christophe memcpy(req_ctx->hw_context, export->hw_context, size);
21733c0dd190SLEROY Christophe memcpy(req_ctx->buf[0], export->buf, export->nbuf);
21743639ca84SHoria Geant? req_ctx->swinit = export->swinit;
21753639ca84SHoria Geant? req_ctx->first = export->first;
21763639ca84SHoria Geant? req_ctx->last = export->last;
21773639ca84SHoria Geant? req_ctx->to_hash_later = export->to_hash_later;
21783639ca84SHoria Geant? req_ctx->nbuf = export->nbuf;
21793639ca84SHoria Geant?
21806a4967c3SLEROY Christophe dma = dma_map_single(dev, req_ctx->hw_context, req_ctx->hw_context_size,
21816a4967c3SLEROY Christophe DMA_TO_DEVICE);
21826a4967c3SLEROY Christophe dma_unmap_single(dev, dma, req_ctx->hw_context_size, DMA_TO_DEVICE);
21836a4967c3SLEROY Christophe
21843639ca84SHoria Geant? return 0;
21853639ca84SHoria Geant? }
21863639ca84SHoria Geant?
keyhash(struct crypto_ahash * tfm,const u8 * key,unsigned int keylen,u8 * hash)218779b3a418SLee Nipper static int keyhash(struct crypto_ahash *tfm, const u8 *key, unsigned int keylen,
218879b3a418SLee Nipper u8 *hash)
218979b3a418SLee Nipper {
219079b3a418SLee Nipper struct talitos_ctx *ctx = crypto_tfm_ctx(crypto_ahash_tfm(tfm));
219179b3a418SLee Nipper
219279b3a418SLee Nipper struct scatterlist sg[1];
219379b3a418SLee Nipper struct ahash_request *req;
2194f1c90ac3SGilad Ben-Yossef struct crypto_wait wait;
219579b3a418SLee Nipper int ret;
219679b3a418SLee Nipper
2197f1c90ac3SGilad Ben-Yossef crypto_init_wait(&wait);
219879b3a418SLee Nipper
219979b3a418SLee Nipper req = ahash_request_alloc(tfm, GFP_KERNEL);
220079b3a418SLee Nipper if (!req)
220179b3a418SLee Nipper return -ENOMEM;
220279b3a418SLee Nipper
220379b3a418SLee Nipper /* Keep tfm keylen == 0 during hash of the long key */
220479b3a418SLee Nipper ctx->keylen = 0;
220579b3a418SLee Nipper ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
2206f1c90ac3SGilad Ben-Yossef crypto_req_done, &wait);
220779b3a418SLee Nipper
220879b3a418SLee Nipper sg_init_one(&sg[0], key, keylen);
220979b3a418SLee Nipper
221079b3a418SLee Nipper ahash_request_set_crypt(req, sg, hash, keylen);
2211f1c90ac3SGilad Ben-Yossef ret = crypto_wait_req(crypto_ahash_digest(req), &wait);
2212f1c90ac3SGilad Ben-Yossef
221379b3a418SLee Nipper ahash_request_free(req);
221479b3a418SLee Nipper
221579b3a418SLee Nipper return ret;
221679b3a418SLee Nipper }
221779b3a418SLee Nipper
ahash_setkey(struct crypto_ahash * tfm,const u8 * key,unsigned int keylen)221879b3a418SLee Nipper static int ahash_setkey(struct crypto_ahash *tfm, const u8 *key,
221979b3a418SLee Nipper unsigned int keylen)
222079b3a418SLee Nipper {
222179b3a418SLee Nipper struct talitos_ctx *ctx = crypto_tfm_ctx(crypto_ahash_tfm(tfm));
22222e13ce08SLEROY Christophe struct device *dev = ctx->dev;
222379b3a418SLee Nipper unsigned int blocksize =
222479b3a418SLee Nipper crypto_tfm_alg_blocksize(crypto_ahash_tfm(tfm));
222579b3a418SLee Nipper unsigned int digestsize = crypto_ahash_digestsize(tfm);
222679b3a418SLee Nipper unsigned int keysize = keylen;
222779b3a418SLee Nipper u8 hash[SHA512_DIGEST_SIZE];
222879b3a418SLee Nipper int ret;
222979b3a418SLee Nipper
223079b3a418SLee Nipper if (keylen <= blocksize)
223179b3a418SLee Nipper memcpy(ctx->key, key, keysize);
223279b3a418SLee Nipper else {
223379b3a418SLee Nipper /* Must get the hash of the long key */
223479b3a418SLee Nipper ret = keyhash(tfm, key, keylen, hash);
223579b3a418SLee Nipper
2236674f368aSEric Biggers if (ret)
223779b3a418SLee Nipper return -EINVAL;
223879b3a418SLee Nipper
223979b3a418SLee Nipper keysize = digestsize;
224079b3a418SLee Nipper memcpy(ctx->key, hash, digestsize);
224179b3a418SLee Nipper }
224279b3a418SLee Nipper
22432e13ce08SLEROY Christophe if (ctx->keylen)
22442e13ce08SLEROY Christophe dma_unmap_single(dev, ctx->dma_key, ctx->keylen, DMA_TO_DEVICE);
22452e13ce08SLEROY Christophe
224679b3a418SLee Nipper ctx->keylen = keysize;
22472e13ce08SLEROY Christophe ctx->dma_key = dma_map_single(dev, ctx->key, keysize, DMA_TO_DEVICE);
224879b3a418SLee Nipper
224979b3a418SLee Nipper return 0;
225079b3a418SLee Nipper }
225179b3a418SLee Nipper
225279b3a418SLee Nipper
22539c4a7965SKim Phillips struct talitos_alg_template {
2254d5e4aaefSLee Nipper u32 type;
2255b0057763SLEROY Christophe u32 priority;
2256d5e4aaefSLee Nipper union {
2257373960d7SArd Biesheuvel struct skcipher_alg skcipher;
2258acbf7c62SLee Nipper struct ahash_alg hash;
2259aeb4c132SHerbert Xu struct aead_alg aead;
2260d5e4aaefSLee Nipper } alg;
22619c4a7965SKim Phillips __be32 desc_hdr_template;
22629c4a7965SKim Phillips };
22639c4a7965SKim Phillips
22649c4a7965SKim Phillips static struct talitos_alg_template driver_algs[] = {
2265991155baSHoria Geanta /* AEAD algorithms. These use a single-pass ipsec_esp descriptor */
2266d5e4aaefSLee Nipper { .type = CRYPTO_ALG_TYPE_AEAD,
2267aeb4c132SHerbert Xu .alg.aead = {
2268aeb4c132SHerbert Xu .base = {
226956af8cd4SLee Nipper .cra_name = "authenc(hmac(sha1),cbc(aes))",
2270aeb4c132SHerbert Xu .cra_driver_name = "authenc-hmac-sha1-"
2271aeb4c132SHerbert Xu "cbc-aes-talitos",
227256af8cd4SLee Nipper .cra_blocksize = AES_BLOCK_SIZE,
2273b8aa7dc5SMikulas Patocka .cra_flags = CRYPTO_ALG_ASYNC |
2274b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY,
2275aeb4c132SHerbert Xu },
22763952f17eSLee Nipper .ivsize = AES_BLOCK_SIZE,
22773952f17eSLee Nipper .maxauthsize = SHA1_DIGEST_SIZE,
22789c4a7965SKim Phillips },
22799c4a7965SKim Phillips .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
22809c4a7965SKim Phillips DESC_HDR_SEL0_AESU |
22819c4a7965SKim Phillips DESC_HDR_MODE0_AESU_CBC |
22829c4a7965SKim Phillips DESC_HDR_SEL1_MDEUA |
22839c4a7965SKim Phillips DESC_HDR_MODE1_MDEU_INIT |
22849c4a7965SKim Phillips DESC_HDR_MODE1_MDEU_PAD |
22859c4a7965SKim Phillips DESC_HDR_MODE1_MDEU_SHA1_HMAC,
228670bcaca7SLee Nipper },
2287d5e4aaefSLee Nipper { .type = CRYPTO_ALG_TYPE_AEAD,
22887405c8d7SLEROY Christophe .priority = TALITOS_CRA_PRIORITY_AEAD_HSNA,
22897405c8d7SLEROY Christophe .alg.aead = {
22907405c8d7SLEROY Christophe .base = {
22917405c8d7SLEROY Christophe .cra_name = "authenc(hmac(sha1),cbc(aes))",
22927405c8d7SLEROY Christophe .cra_driver_name = "authenc-hmac-sha1-"
2293a1a42f84SChristophe Leroy "cbc-aes-talitos-hsna",
22947405c8d7SLEROY Christophe .cra_blocksize = AES_BLOCK_SIZE,
2295b8aa7dc5SMikulas Patocka .cra_flags = CRYPTO_ALG_ASYNC |
2296b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY,
22977405c8d7SLEROY Christophe },
22987405c8d7SLEROY Christophe .ivsize = AES_BLOCK_SIZE,
22997405c8d7SLEROY Christophe .maxauthsize = SHA1_DIGEST_SIZE,
23007405c8d7SLEROY Christophe },
23017405c8d7SLEROY Christophe .desc_hdr_template = DESC_HDR_TYPE_HMAC_SNOOP_NO_AFEU |
23027405c8d7SLEROY Christophe DESC_HDR_SEL0_AESU |
23037405c8d7SLEROY Christophe DESC_HDR_MODE0_AESU_CBC |
23047405c8d7SLEROY Christophe DESC_HDR_SEL1_MDEUA |
23057405c8d7SLEROY Christophe DESC_HDR_MODE1_MDEU_INIT |
23067405c8d7SLEROY Christophe DESC_HDR_MODE1_MDEU_PAD |
23077405c8d7SLEROY Christophe DESC_HDR_MODE1_MDEU_SHA1_HMAC,
23087405c8d7SLEROY Christophe },
23097405c8d7SLEROY Christophe { .type = CRYPTO_ALG_TYPE_AEAD,
2310aeb4c132SHerbert Xu .alg.aead = {
2311aeb4c132SHerbert Xu .base = {
2312aeb4c132SHerbert Xu .cra_name = "authenc(hmac(sha1),"
2313aeb4c132SHerbert Xu "cbc(des3_ede))",
2314aeb4c132SHerbert Xu .cra_driver_name = "authenc-hmac-sha1-"
2315aeb4c132SHerbert Xu "cbc-3des-talitos",
231656af8cd4SLee Nipper .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2317b8aa7dc5SMikulas Patocka .cra_flags = CRYPTO_ALG_ASYNC |
2318b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY,
2319aeb4c132SHerbert Xu },
23203952f17eSLee Nipper .ivsize = DES3_EDE_BLOCK_SIZE,
23213952f17eSLee Nipper .maxauthsize = SHA1_DIGEST_SIZE,
2322ef7c5c85SHerbert Xu .setkey = aead_des3_setkey,
232370bcaca7SLee Nipper },
232470bcaca7SLee Nipper .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
232570bcaca7SLee Nipper DESC_HDR_SEL0_DEU |
232670bcaca7SLee Nipper DESC_HDR_MODE0_DEU_CBC |
232770bcaca7SLee Nipper DESC_HDR_MODE0_DEU_3DES |
232870bcaca7SLee Nipper DESC_HDR_SEL1_MDEUA |
232970bcaca7SLee Nipper DESC_HDR_MODE1_MDEU_INIT |
233070bcaca7SLee Nipper DESC_HDR_MODE1_MDEU_PAD |
233170bcaca7SLee Nipper DESC_HDR_MODE1_MDEU_SHA1_HMAC,
23323952f17eSLee Nipper },
2333d5e4aaefSLee Nipper { .type = CRYPTO_ALG_TYPE_AEAD,
23347405c8d7SLEROY Christophe .priority = TALITOS_CRA_PRIORITY_AEAD_HSNA,
23357405c8d7SLEROY Christophe .alg.aead = {
23367405c8d7SLEROY Christophe .base = {
23377405c8d7SLEROY Christophe .cra_name = "authenc(hmac(sha1),"
23387405c8d7SLEROY Christophe "cbc(des3_ede))",
23397405c8d7SLEROY Christophe .cra_driver_name = "authenc-hmac-sha1-"
2340a1a42f84SChristophe Leroy "cbc-3des-talitos-hsna",
23417405c8d7SLEROY Christophe .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2342b8aa7dc5SMikulas Patocka .cra_flags = CRYPTO_ALG_ASYNC |
2343b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY,
23447405c8d7SLEROY Christophe },
23457405c8d7SLEROY Christophe .ivsize = DES3_EDE_BLOCK_SIZE,
23467405c8d7SLEROY Christophe .maxauthsize = SHA1_DIGEST_SIZE,
2347ef7c5c85SHerbert Xu .setkey = aead_des3_setkey,
23487405c8d7SLEROY Christophe },
23497405c8d7SLEROY Christophe .desc_hdr_template = DESC_HDR_TYPE_HMAC_SNOOP_NO_AFEU |
23507405c8d7SLEROY Christophe DESC_HDR_SEL0_DEU |
23517405c8d7SLEROY Christophe DESC_HDR_MODE0_DEU_CBC |
23527405c8d7SLEROY Christophe DESC_HDR_MODE0_DEU_3DES |
23537405c8d7SLEROY Christophe DESC_HDR_SEL1_MDEUA |
23547405c8d7SLEROY Christophe DESC_HDR_MODE1_MDEU_INIT |
23557405c8d7SLEROY Christophe DESC_HDR_MODE1_MDEU_PAD |
23567405c8d7SLEROY Christophe DESC_HDR_MODE1_MDEU_SHA1_HMAC,
23577405c8d7SLEROY Christophe },
23587405c8d7SLEROY Christophe { .type = CRYPTO_ALG_TYPE_AEAD,
2359aeb4c132SHerbert Xu .alg.aead = {
2360aeb4c132SHerbert Xu .base = {
2361357fb605SHoria Geanta .cra_name = "authenc(hmac(sha224),cbc(aes))",
2362aeb4c132SHerbert Xu .cra_driver_name = "authenc-hmac-sha224-"
2363aeb4c132SHerbert Xu "cbc-aes-talitos",
2364357fb605SHoria Geanta .cra_blocksize = AES_BLOCK_SIZE,
2365b8aa7dc5SMikulas Patocka .cra_flags = CRYPTO_ALG_ASYNC |
2366b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY,
2367aeb4c132SHerbert Xu },
2368357fb605SHoria Geanta .ivsize = AES_BLOCK_SIZE,
2369357fb605SHoria Geanta .maxauthsize = SHA224_DIGEST_SIZE,
2370357fb605SHoria Geanta },
2371357fb605SHoria Geanta .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
2372357fb605SHoria Geanta DESC_HDR_SEL0_AESU |
2373357fb605SHoria Geanta DESC_HDR_MODE0_AESU_CBC |
2374357fb605SHoria Geanta DESC_HDR_SEL1_MDEUA |
2375357fb605SHoria Geanta DESC_HDR_MODE1_MDEU_INIT |
2376357fb605SHoria Geanta DESC_HDR_MODE1_MDEU_PAD |
2377357fb605SHoria Geanta DESC_HDR_MODE1_MDEU_SHA224_HMAC,
2378357fb605SHoria Geanta },
2379357fb605SHoria Geanta { .type = CRYPTO_ALG_TYPE_AEAD,
23807405c8d7SLEROY Christophe .priority = TALITOS_CRA_PRIORITY_AEAD_HSNA,
23817405c8d7SLEROY Christophe .alg.aead = {
23827405c8d7SLEROY Christophe .base = {
23837405c8d7SLEROY Christophe .cra_name = "authenc(hmac(sha224),cbc(aes))",
23847405c8d7SLEROY Christophe .cra_driver_name = "authenc-hmac-sha224-"
2385a1a42f84SChristophe Leroy "cbc-aes-talitos-hsna",
23867405c8d7SLEROY Christophe .cra_blocksize = AES_BLOCK_SIZE,
2387b8aa7dc5SMikulas Patocka .cra_flags = CRYPTO_ALG_ASYNC |
2388b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY,
23897405c8d7SLEROY Christophe },
23907405c8d7SLEROY Christophe .ivsize = AES_BLOCK_SIZE,
23917405c8d7SLEROY Christophe .maxauthsize = SHA224_DIGEST_SIZE,
23927405c8d7SLEROY Christophe },
23937405c8d7SLEROY Christophe .desc_hdr_template = DESC_HDR_TYPE_HMAC_SNOOP_NO_AFEU |
23947405c8d7SLEROY Christophe DESC_HDR_SEL0_AESU |
23957405c8d7SLEROY Christophe DESC_HDR_MODE0_AESU_CBC |
23967405c8d7SLEROY Christophe DESC_HDR_SEL1_MDEUA |
23977405c8d7SLEROY Christophe DESC_HDR_MODE1_MDEU_INIT |
23987405c8d7SLEROY Christophe DESC_HDR_MODE1_MDEU_PAD |
23997405c8d7SLEROY Christophe DESC_HDR_MODE1_MDEU_SHA224_HMAC,
24007405c8d7SLEROY Christophe },
24017405c8d7SLEROY Christophe { .type = CRYPTO_ALG_TYPE_AEAD,
2402aeb4c132SHerbert Xu .alg.aead = {
2403aeb4c132SHerbert Xu .base = {
2404aeb4c132SHerbert Xu .cra_name = "authenc(hmac(sha224),"
2405aeb4c132SHerbert Xu "cbc(des3_ede))",
2406aeb4c132SHerbert Xu .cra_driver_name = "authenc-hmac-sha224-"
2407aeb4c132SHerbert Xu "cbc-3des-talitos",
2408357fb605SHoria Geanta .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2409b8aa7dc5SMikulas Patocka .cra_flags = CRYPTO_ALG_ASYNC |
2410b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY,
2411aeb4c132SHerbert Xu },
2412357fb605SHoria Geanta .ivsize = DES3_EDE_BLOCK_SIZE,
2413357fb605SHoria Geanta .maxauthsize = SHA224_DIGEST_SIZE,
2414ef7c5c85SHerbert Xu .setkey = aead_des3_setkey,
2415357fb605SHoria Geanta },
2416357fb605SHoria Geanta .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
2417357fb605SHoria Geanta DESC_HDR_SEL0_DEU |
2418357fb605SHoria Geanta DESC_HDR_MODE0_DEU_CBC |
2419357fb605SHoria Geanta DESC_HDR_MODE0_DEU_3DES |
2420357fb605SHoria Geanta DESC_HDR_SEL1_MDEUA |
2421357fb605SHoria Geanta DESC_HDR_MODE1_MDEU_INIT |
2422357fb605SHoria Geanta DESC_HDR_MODE1_MDEU_PAD |
2423357fb605SHoria Geanta DESC_HDR_MODE1_MDEU_SHA224_HMAC,
2424357fb605SHoria Geanta },
2425357fb605SHoria Geanta { .type = CRYPTO_ALG_TYPE_AEAD,
24267405c8d7SLEROY Christophe .priority = TALITOS_CRA_PRIORITY_AEAD_HSNA,
24277405c8d7SLEROY Christophe .alg.aead = {
24287405c8d7SLEROY Christophe .base = {
24297405c8d7SLEROY Christophe .cra_name = "authenc(hmac(sha224),"
24307405c8d7SLEROY Christophe "cbc(des3_ede))",
24317405c8d7SLEROY Christophe .cra_driver_name = "authenc-hmac-sha224-"
2432a1a42f84SChristophe Leroy "cbc-3des-talitos-hsna",
24337405c8d7SLEROY Christophe .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2434b8aa7dc5SMikulas Patocka .cra_flags = CRYPTO_ALG_ASYNC |
2435b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY,
24367405c8d7SLEROY Christophe },
24377405c8d7SLEROY Christophe .ivsize = DES3_EDE_BLOCK_SIZE,
24387405c8d7SLEROY Christophe .maxauthsize = SHA224_DIGEST_SIZE,
2439ef7c5c85SHerbert Xu .setkey = aead_des3_setkey,
24407405c8d7SLEROY Christophe },
24417405c8d7SLEROY Christophe .desc_hdr_template = DESC_HDR_TYPE_HMAC_SNOOP_NO_AFEU |
24427405c8d7SLEROY Christophe DESC_HDR_SEL0_DEU |
24437405c8d7SLEROY Christophe DESC_HDR_MODE0_DEU_CBC |
24447405c8d7SLEROY Christophe DESC_HDR_MODE0_DEU_3DES |
24457405c8d7SLEROY Christophe DESC_HDR_SEL1_MDEUA |
24467405c8d7SLEROY Christophe DESC_HDR_MODE1_MDEU_INIT |
24477405c8d7SLEROY Christophe DESC_HDR_MODE1_MDEU_PAD |
24487405c8d7SLEROY Christophe DESC_HDR_MODE1_MDEU_SHA224_HMAC,
24497405c8d7SLEROY Christophe },
24507405c8d7SLEROY Christophe { .type = CRYPTO_ALG_TYPE_AEAD,
2451aeb4c132SHerbert Xu .alg.aead = {
2452aeb4c132SHerbert Xu .base = {
245356af8cd4SLee Nipper .cra_name = "authenc(hmac(sha256),cbc(aes))",
2454aeb4c132SHerbert Xu .cra_driver_name = "authenc-hmac-sha256-"
2455aeb4c132SHerbert Xu "cbc-aes-talitos",
245656af8cd4SLee Nipper .cra_blocksize = AES_BLOCK_SIZE,
2457b8aa7dc5SMikulas Patocka .cra_flags = CRYPTO_ALG_ASYNC |
2458b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY,
2459aeb4c132SHerbert Xu },
24603952f17eSLee Nipper .ivsize = AES_BLOCK_SIZE,
24613952f17eSLee Nipper .maxauthsize = SHA256_DIGEST_SIZE,
24623952f17eSLee Nipper },
24633952f17eSLee Nipper .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
24643952f17eSLee Nipper DESC_HDR_SEL0_AESU |
24653952f17eSLee Nipper DESC_HDR_MODE0_AESU_CBC |
24663952f17eSLee Nipper DESC_HDR_SEL1_MDEUA |
24673952f17eSLee Nipper DESC_HDR_MODE1_MDEU_INIT |
24683952f17eSLee Nipper DESC_HDR_MODE1_MDEU_PAD |
24693952f17eSLee Nipper DESC_HDR_MODE1_MDEU_SHA256_HMAC,
24703952f17eSLee Nipper },
2471d5e4aaefSLee Nipper { .type = CRYPTO_ALG_TYPE_AEAD,
24727405c8d7SLEROY Christophe .priority = TALITOS_CRA_PRIORITY_AEAD_HSNA,
24737405c8d7SLEROY Christophe .alg.aead = {
24747405c8d7SLEROY Christophe .base = {
24757405c8d7SLEROY Christophe .cra_name = "authenc(hmac(sha256),cbc(aes))",
24767405c8d7SLEROY Christophe .cra_driver_name = "authenc-hmac-sha256-"
2477a1a42f84SChristophe Leroy "cbc-aes-talitos-hsna",
24787405c8d7SLEROY Christophe .cra_blocksize = AES_BLOCK_SIZE,
2479b8aa7dc5SMikulas Patocka .cra_flags = CRYPTO_ALG_ASYNC |
2480b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY,
24817405c8d7SLEROY Christophe },
24827405c8d7SLEROY Christophe .ivsize = AES_BLOCK_SIZE,
24837405c8d7SLEROY Christophe .maxauthsize = SHA256_DIGEST_SIZE,
24847405c8d7SLEROY Christophe },
24857405c8d7SLEROY Christophe .desc_hdr_template = DESC_HDR_TYPE_HMAC_SNOOP_NO_AFEU |
24867405c8d7SLEROY Christophe DESC_HDR_SEL0_AESU |
24877405c8d7SLEROY Christophe DESC_HDR_MODE0_AESU_CBC |
24887405c8d7SLEROY Christophe DESC_HDR_SEL1_MDEUA |
24897405c8d7SLEROY Christophe DESC_HDR_MODE1_MDEU_INIT |
24907405c8d7SLEROY Christophe DESC_HDR_MODE1_MDEU_PAD |
24917405c8d7SLEROY Christophe DESC_HDR_MODE1_MDEU_SHA256_HMAC,
24927405c8d7SLEROY Christophe },
24937405c8d7SLEROY Christophe { .type = CRYPTO_ALG_TYPE_AEAD,
2494aeb4c132SHerbert Xu .alg.aead = {
2495aeb4c132SHerbert Xu .base = {
2496aeb4c132SHerbert Xu .cra_name = "authenc(hmac(sha256),"
2497aeb4c132SHerbert Xu "cbc(des3_ede))",
2498aeb4c132SHerbert Xu .cra_driver_name = "authenc-hmac-sha256-"
2499aeb4c132SHerbert Xu "cbc-3des-talitos",
250056af8cd4SLee Nipper .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2501b8aa7dc5SMikulas Patocka .cra_flags = CRYPTO_ALG_ASYNC |
2502b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY,
2503aeb4c132SHerbert Xu },
25043952f17eSLee Nipper .ivsize = DES3_EDE_BLOCK_SIZE,
25053952f17eSLee Nipper .maxauthsize = SHA256_DIGEST_SIZE,
2506ef7c5c85SHerbert Xu .setkey = aead_des3_setkey,
25073952f17eSLee Nipper },
25083952f17eSLee Nipper .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
25093952f17eSLee Nipper DESC_HDR_SEL0_DEU |
25103952f17eSLee Nipper DESC_HDR_MODE0_DEU_CBC |
25113952f17eSLee Nipper DESC_HDR_MODE0_DEU_3DES |
25123952f17eSLee Nipper DESC_HDR_SEL1_MDEUA |
25133952f17eSLee Nipper DESC_HDR_MODE1_MDEU_INIT |
25143952f17eSLee Nipper DESC_HDR_MODE1_MDEU_PAD |
25153952f17eSLee Nipper DESC_HDR_MODE1_MDEU_SHA256_HMAC,
25163952f17eSLee Nipper },
2517d5e4aaefSLee Nipper { .type = CRYPTO_ALG_TYPE_AEAD,
25187405c8d7SLEROY Christophe .priority = TALITOS_CRA_PRIORITY_AEAD_HSNA,
25197405c8d7SLEROY Christophe .alg.aead = {
25207405c8d7SLEROY Christophe .base = {
25217405c8d7SLEROY Christophe .cra_name = "authenc(hmac(sha256),"
25227405c8d7SLEROY Christophe "cbc(des3_ede))",
25237405c8d7SLEROY Christophe .cra_driver_name = "authenc-hmac-sha256-"
2524a1a42f84SChristophe Leroy "cbc-3des-talitos-hsna",
25257405c8d7SLEROY Christophe .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2526b8aa7dc5SMikulas Patocka .cra_flags = CRYPTO_ALG_ASYNC |
2527b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY,
25287405c8d7SLEROY Christophe },
25297405c8d7SLEROY Christophe .ivsize = DES3_EDE_BLOCK_SIZE,
25307405c8d7SLEROY Christophe .maxauthsize = SHA256_DIGEST_SIZE,
2531ef7c5c85SHerbert Xu .setkey = aead_des3_setkey,
25327405c8d7SLEROY Christophe },
25337405c8d7SLEROY Christophe .desc_hdr_template = DESC_HDR_TYPE_HMAC_SNOOP_NO_AFEU |
25347405c8d7SLEROY Christophe DESC_HDR_SEL0_DEU |
25357405c8d7SLEROY Christophe DESC_HDR_MODE0_DEU_CBC |
25367405c8d7SLEROY Christophe DESC_HDR_MODE0_DEU_3DES |
25377405c8d7SLEROY Christophe DESC_HDR_SEL1_MDEUA |
25387405c8d7SLEROY Christophe DESC_HDR_MODE1_MDEU_INIT |
25397405c8d7SLEROY Christophe DESC_HDR_MODE1_MDEU_PAD |
25407405c8d7SLEROY Christophe DESC_HDR_MODE1_MDEU_SHA256_HMAC,
25417405c8d7SLEROY Christophe },
25427405c8d7SLEROY Christophe { .type = CRYPTO_ALG_TYPE_AEAD,
2543aeb4c132SHerbert Xu .alg.aead = {
2544aeb4c132SHerbert Xu .base = {
2545357fb605SHoria Geanta .cra_name = "authenc(hmac(sha384),cbc(aes))",
2546aeb4c132SHerbert Xu .cra_driver_name = "authenc-hmac-sha384-"
2547aeb4c132SHerbert Xu "cbc-aes-talitos",
2548357fb605SHoria Geanta .cra_blocksize = AES_BLOCK_SIZE,
2549b8aa7dc5SMikulas Patocka .cra_flags = CRYPTO_ALG_ASYNC |
2550b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY,
2551aeb4c132SHerbert Xu },
2552357fb605SHoria Geanta .ivsize = AES_BLOCK_SIZE,
2553357fb605SHoria Geanta .maxauthsize = SHA384_DIGEST_SIZE,
2554357fb605SHoria Geanta },
2555357fb605SHoria Geanta .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
2556357fb605SHoria Geanta DESC_HDR_SEL0_AESU |
2557357fb605SHoria Geanta DESC_HDR_MODE0_AESU_CBC |
2558357fb605SHoria Geanta DESC_HDR_SEL1_MDEUB |
2559357fb605SHoria Geanta DESC_HDR_MODE1_MDEU_INIT |
2560357fb605SHoria Geanta DESC_HDR_MODE1_MDEU_PAD |
2561357fb605SHoria Geanta DESC_HDR_MODE1_MDEUB_SHA384_HMAC,
2562357fb605SHoria Geanta },
2563357fb605SHoria Geanta { .type = CRYPTO_ALG_TYPE_AEAD,
2564aeb4c132SHerbert Xu .alg.aead = {
2565aeb4c132SHerbert Xu .base = {
2566aeb4c132SHerbert Xu .cra_name = "authenc(hmac(sha384),"
2567aeb4c132SHerbert Xu "cbc(des3_ede))",
2568aeb4c132SHerbert Xu .cra_driver_name = "authenc-hmac-sha384-"
2569aeb4c132SHerbert Xu "cbc-3des-talitos",
2570357fb605SHoria Geanta .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2571b8aa7dc5SMikulas Patocka .cra_flags = CRYPTO_ALG_ASYNC |
2572b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY,
2573aeb4c132SHerbert Xu },
2574357fb605SHoria Geanta .ivsize = DES3_EDE_BLOCK_SIZE,
2575357fb605SHoria Geanta .maxauthsize = SHA384_DIGEST_SIZE,
2576ef7c5c85SHerbert Xu .setkey = aead_des3_setkey,
2577357fb605SHoria Geanta },
2578357fb605SHoria Geanta .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
2579357fb605SHoria Geanta DESC_HDR_SEL0_DEU |
2580357fb605SHoria Geanta DESC_HDR_MODE0_DEU_CBC |
2581357fb605SHoria Geanta DESC_HDR_MODE0_DEU_3DES |
2582357fb605SHoria Geanta DESC_HDR_SEL1_MDEUB |
2583357fb605SHoria Geanta DESC_HDR_MODE1_MDEU_INIT |
2584357fb605SHoria Geanta DESC_HDR_MODE1_MDEU_PAD |
2585357fb605SHoria Geanta DESC_HDR_MODE1_MDEUB_SHA384_HMAC,
2586357fb605SHoria Geanta },
2587357fb605SHoria Geanta { .type = CRYPTO_ALG_TYPE_AEAD,
2588aeb4c132SHerbert Xu .alg.aead = {
2589aeb4c132SHerbert Xu .base = {
2590357fb605SHoria Geanta .cra_name = "authenc(hmac(sha512),cbc(aes))",
2591aeb4c132SHerbert Xu .cra_driver_name = "authenc-hmac-sha512-"
2592aeb4c132SHerbert Xu "cbc-aes-talitos",
2593357fb605SHoria Geanta .cra_blocksize = AES_BLOCK_SIZE,
2594b8aa7dc5SMikulas Patocka .cra_flags = CRYPTO_ALG_ASYNC |
2595b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY,
2596aeb4c132SHerbert Xu },
2597357fb605SHoria Geanta .ivsize = AES_BLOCK_SIZE,
2598357fb605SHoria Geanta .maxauthsize = SHA512_DIGEST_SIZE,
2599357fb605SHoria Geanta },
2600357fb605SHoria Geanta .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
2601357fb605SHoria Geanta DESC_HDR_SEL0_AESU |
2602357fb605SHoria Geanta DESC_HDR_MODE0_AESU_CBC |
2603357fb605SHoria Geanta DESC_HDR_SEL1_MDEUB |
2604357fb605SHoria Geanta DESC_HDR_MODE1_MDEU_INIT |
2605357fb605SHoria Geanta DESC_HDR_MODE1_MDEU_PAD |
2606357fb605SHoria Geanta DESC_HDR_MODE1_MDEUB_SHA512_HMAC,
2607357fb605SHoria Geanta },
2608357fb605SHoria Geanta { .type = CRYPTO_ALG_TYPE_AEAD,
2609aeb4c132SHerbert Xu .alg.aead = {
2610aeb4c132SHerbert Xu .base = {
2611aeb4c132SHerbert Xu .cra_name = "authenc(hmac(sha512),"
2612aeb4c132SHerbert Xu "cbc(des3_ede))",
2613aeb4c132SHerbert Xu .cra_driver_name = "authenc-hmac-sha512-"
2614aeb4c132SHerbert Xu "cbc-3des-talitos",
2615357fb605SHoria Geanta .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2616b8aa7dc5SMikulas Patocka .cra_flags = CRYPTO_ALG_ASYNC |
2617b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY,
2618aeb4c132SHerbert Xu },
2619357fb605SHoria Geanta .ivsize = DES3_EDE_BLOCK_SIZE,
2620357fb605SHoria Geanta .maxauthsize = SHA512_DIGEST_SIZE,
2621ef7c5c85SHerbert Xu .setkey = aead_des3_setkey,
2622357fb605SHoria Geanta },
2623357fb605SHoria Geanta .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
2624357fb605SHoria Geanta DESC_HDR_SEL0_DEU |
2625357fb605SHoria Geanta DESC_HDR_MODE0_DEU_CBC |
2626357fb605SHoria Geanta DESC_HDR_MODE0_DEU_3DES |
2627357fb605SHoria Geanta DESC_HDR_SEL1_MDEUB |
2628357fb605SHoria Geanta DESC_HDR_MODE1_MDEU_INIT |
2629357fb605SHoria Geanta DESC_HDR_MODE1_MDEU_PAD |
2630357fb605SHoria Geanta DESC_HDR_MODE1_MDEUB_SHA512_HMAC,
2631357fb605SHoria Geanta },
2632357fb605SHoria Geanta { .type = CRYPTO_ALG_TYPE_AEAD,
2633aeb4c132SHerbert Xu .alg.aead = {
2634aeb4c132SHerbert Xu .base = {
263556af8cd4SLee Nipper .cra_name = "authenc(hmac(md5),cbc(aes))",
2636aeb4c132SHerbert Xu .cra_driver_name = "authenc-hmac-md5-"
2637aeb4c132SHerbert Xu "cbc-aes-talitos",
263856af8cd4SLee Nipper .cra_blocksize = AES_BLOCK_SIZE,
2639b8aa7dc5SMikulas Patocka .cra_flags = CRYPTO_ALG_ASYNC |
2640b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY,
2641aeb4c132SHerbert Xu },
26423952f17eSLee Nipper .ivsize = AES_BLOCK_SIZE,
26433952f17eSLee Nipper .maxauthsize = MD5_DIGEST_SIZE,
26443952f17eSLee Nipper },
26453952f17eSLee Nipper .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
26463952f17eSLee Nipper DESC_HDR_SEL0_AESU |
26473952f17eSLee Nipper DESC_HDR_MODE0_AESU_CBC |
26483952f17eSLee Nipper DESC_HDR_SEL1_MDEUA |
26493952f17eSLee Nipper DESC_HDR_MODE1_MDEU_INIT |
26503952f17eSLee Nipper DESC_HDR_MODE1_MDEU_PAD |
26513952f17eSLee Nipper DESC_HDR_MODE1_MDEU_MD5_HMAC,
26523952f17eSLee Nipper },
2653d5e4aaefSLee Nipper { .type = CRYPTO_ALG_TYPE_AEAD,
26547405c8d7SLEROY Christophe .priority = TALITOS_CRA_PRIORITY_AEAD_HSNA,
26557405c8d7SLEROY Christophe .alg.aead = {
26567405c8d7SLEROY Christophe .base = {
26577405c8d7SLEROY Christophe .cra_name = "authenc(hmac(md5),cbc(aes))",
26587405c8d7SLEROY Christophe .cra_driver_name = "authenc-hmac-md5-"
2659a1a42f84SChristophe Leroy "cbc-aes-talitos-hsna",
26607405c8d7SLEROY Christophe .cra_blocksize = AES_BLOCK_SIZE,
2661b8aa7dc5SMikulas Patocka .cra_flags = CRYPTO_ALG_ASYNC |
2662b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY,
26637405c8d7SLEROY Christophe },
26647405c8d7SLEROY Christophe .ivsize = AES_BLOCK_SIZE,
26657405c8d7SLEROY Christophe .maxauthsize = MD5_DIGEST_SIZE,
26667405c8d7SLEROY Christophe },
26677405c8d7SLEROY Christophe .desc_hdr_template = DESC_HDR_TYPE_HMAC_SNOOP_NO_AFEU |
26687405c8d7SLEROY Christophe DESC_HDR_SEL0_AESU |
26697405c8d7SLEROY Christophe DESC_HDR_MODE0_AESU_CBC |
26707405c8d7SLEROY Christophe DESC_HDR_SEL1_MDEUA |
26717405c8d7SLEROY Christophe DESC_HDR_MODE1_MDEU_INIT |
26727405c8d7SLEROY Christophe DESC_HDR_MODE1_MDEU_PAD |
26737405c8d7SLEROY Christophe DESC_HDR_MODE1_MDEU_MD5_HMAC,
26747405c8d7SLEROY Christophe },
26757405c8d7SLEROY Christophe { .type = CRYPTO_ALG_TYPE_AEAD,
2676aeb4c132SHerbert Xu .alg.aead = {
2677aeb4c132SHerbert Xu .base = {
267856af8cd4SLee Nipper .cra_name = "authenc(hmac(md5),cbc(des3_ede))",
2679aeb4c132SHerbert Xu .cra_driver_name = "authenc-hmac-md5-"
2680aeb4c132SHerbert Xu "cbc-3des-talitos",
268156af8cd4SLee Nipper .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2682b8aa7dc5SMikulas Patocka .cra_flags = CRYPTO_ALG_ASYNC |
2683b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY,
2684aeb4c132SHerbert Xu },
26853952f17eSLee Nipper .ivsize = DES3_EDE_BLOCK_SIZE,
26863952f17eSLee Nipper .maxauthsize = MD5_DIGEST_SIZE,
2687ef7c5c85SHerbert Xu .setkey = aead_des3_setkey,
26883952f17eSLee Nipper },
26893952f17eSLee Nipper .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
26903952f17eSLee Nipper DESC_HDR_SEL0_DEU |
26913952f17eSLee Nipper DESC_HDR_MODE0_DEU_CBC |
26923952f17eSLee Nipper DESC_HDR_MODE0_DEU_3DES |
26933952f17eSLee Nipper DESC_HDR_SEL1_MDEUA |
26943952f17eSLee Nipper DESC_HDR_MODE1_MDEU_INIT |
26953952f17eSLee Nipper DESC_HDR_MODE1_MDEU_PAD |
26963952f17eSLee Nipper DESC_HDR_MODE1_MDEU_MD5_HMAC,
26974de9d0b5SLee Nipper },
26987405c8d7SLEROY Christophe { .type = CRYPTO_ALG_TYPE_AEAD,
26997405c8d7SLEROY Christophe .priority = TALITOS_CRA_PRIORITY_AEAD_HSNA,
27007405c8d7SLEROY Christophe .alg.aead = {
27017405c8d7SLEROY Christophe .base = {
27027405c8d7SLEROY Christophe .cra_name = "authenc(hmac(md5),cbc(des3_ede))",
27037405c8d7SLEROY Christophe .cra_driver_name = "authenc-hmac-md5-"
2704a1a42f84SChristophe Leroy "cbc-3des-talitos-hsna",
27057405c8d7SLEROY Christophe .cra_blocksize = DES3_EDE_BLOCK_SIZE,
2706b8aa7dc5SMikulas Patocka .cra_flags = CRYPTO_ALG_ASYNC |
2707b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY,
27087405c8d7SLEROY Christophe },
27097405c8d7SLEROY Christophe .ivsize = DES3_EDE_BLOCK_SIZE,
27107405c8d7SLEROY Christophe .maxauthsize = MD5_DIGEST_SIZE,
2711ef7c5c85SHerbert Xu .setkey = aead_des3_setkey,
27127405c8d7SLEROY Christophe },
27137405c8d7SLEROY Christophe .desc_hdr_template = DESC_HDR_TYPE_HMAC_SNOOP_NO_AFEU |
27147405c8d7SLEROY Christophe DESC_HDR_SEL0_DEU |
27157405c8d7SLEROY Christophe DESC_HDR_MODE0_DEU_CBC |
27167405c8d7SLEROY Christophe DESC_HDR_MODE0_DEU_3DES |
27177405c8d7SLEROY Christophe DESC_HDR_SEL1_MDEUA |
27187405c8d7SLEROY Christophe DESC_HDR_MODE1_MDEU_INIT |
27197405c8d7SLEROY Christophe DESC_HDR_MODE1_MDEU_PAD |
27207405c8d7SLEROY Christophe DESC_HDR_MODE1_MDEU_MD5_HMAC,
27217405c8d7SLEROY Christophe },
2722373960d7SArd Biesheuvel /* SKCIPHER algorithms. */
2723373960d7SArd Biesheuvel { .type = CRYPTO_ALG_TYPE_SKCIPHER,
2724373960d7SArd Biesheuvel .alg.skcipher = {
2725373960d7SArd Biesheuvel .base.cra_name = "ecb(aes)",
2726373960d7SArd Biesheuvel .base.cra_driver_name = "ecb-aes-talitos",
2727373960d7SArd Biesheuvel .base.cra_blocksize = AES_BLOCK_SIZE,
2728b8aa7dc5SMikulas Patocka .base.cra_flags = CRYPTO_ALG_ASYNC |
2729b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY,
27305e75ae1bSLEROY Christophe .min_keysize = AES_MIN_KEY_SIZE,
27315e75ae1bSLEROY Christophe .max_keysize = AES_MAX_KEY_SIZE,
2732373960d7SArd Biesheuvel .setkey = skcipher_aes_setkey,
27335e75ae1bSLEROY Christophe },
27345e75ae1bSLEROY Christophe .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
27355e75ae1bSLEROY Christophe DESC_HDR_SEL0_AESU,
27365e75ae1bSLEROY Christophe },
2737373960d7SArd Biesheuvel { .type = CRYPTO_ALG_TYPE_SKCIPHER,
2738373960d7SArd Biesheuvel .alg.skcipher = {
2739373960d7SArd Biesheuvel .base.cra_name = "cbc(aes)",
2740373960d7SArd Biesheuvel .base.cra_driver_name = "cbc-aes-talitos",
2741373960d7SArd Biesheuvel .base.cra_blocksize = AES_BLOCK_SIZE,
2742b8aa7dc5SMikulas Patocka .base.cra_flags = CRYPTO_ALG_ASYNC |
2743b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY,
27444de9d0b5SLee Nipper .min_keysize = AES_MIN_KEY_SIZE,
27454de9d0b5SLee Nipper .max_keysize = AES_MAX_KEY_SIZE,
27464de9d0b5SLee Nipper .ivsize = AES_BLOCK_SIZE,
2747373960d7SArd Biesheuvel .setkey = skcipher_aes_setkey,
27484de9d0b5SLee Nipper },
27494de9d0b5SLee Nipper .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
27504de9d0b5SLee Nipper DESC_HDR_SEL0_AESU |
27514de9d0b5SLee Nipper DESC_HDR_MODE0_AESU_CBC,
27524de9d0b5SLee Nipper },
2753373960d7SArd Biesheuvel { .type = CRYPTO_ALG_TYPE_SKCIPHER,
2754373960d7SArd Biesheuvel .alg.skcipher = {
2755373960d7SArd Biesheuvel .base.cra_name = "ctr(aes)",
2756373960d7SArd Biesheuvel .base.cra_driver_name = "ctr-aes-talitos",
2757373960d7SArd Biesheuvel .base.cra_blocksize = 1,
2758b8aa7dc5SMikulas Patocka .base.cra_flags = CRYPTO_ALG_ASYNC |
2759b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY,
27605e75ae1bSLEROY Christophe .min_keysize = AES_MIN_KEY_SIZE,
27615e75ae1bSLEROY Christophe .max_keysize = AES_MAX_KEY_SIZE,
27625e75ae1bSLEROY Christophe .ivsize = AES_BLOCK_SIZE,
2763373960d7SArd Biesheuvel .setkey = skcipher_aes_setkey,
27645e75ae1bSLEROY Christophe },
276570d355ccSLEROY Christophe .desc_hdr_template = DESC_HDR_TYPE_AESU_CTR_NONSNOOP |
27665e75ae1bSLEROY Christophe DESC_HDR_SEL0_AESU |
27675e75ae1bSLEROY Christophe DESC_HDR_MODE0_AESU_CTR,
27685e75ae1bSLEROY Christophe },
2769373960d7SArd Biesheuvel { .type = CRYPTO_ALG_TYPE_SKCIPHER,
2770373960d7SArd Biesheuvel .alg.skcipher = {
277143a942d2SChristophe Leroy .base.cra_name = "ctr(aes)",
277243a942d2SChristophe Leroy .base.cra_driver_name = "ctr-aes-talitos",
277343a942d2SChristophe Leroy .base.cra_blocksize = 1,
277443a942d2SChristophe Leroy .base.cra_flags = CRYPTO_ALG_ASYNC |
277543a942d2SChristophe Leroy CRYPTO_ALG_ALLOCATES_MEMORY,
277643a942d2SChristophe Leroy .min_keysize = AES_MIN_KEY_SIZE,
277743a942d2SChristophe Leroy .max_keysize = AES_MAX_KEY_SIZE,
277843a942d2SChristophe Leroy .ivsize = AES_BLOCK_SIZE,
277943a942d2SChristophe Leroy .setkey = skcipher_aes_setkey,
278043a942d2SChristophe Leroy },
278143a942d2SChristophe Leroy .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
278243a942d2SChristophe Leroy DESC_HDR_SEL0_AESU |
278343a942d2SChristophe Leroy DESC_HDR_MODE0_AESU_CTR,
278443a942d2SChristophe Leroy },
278543a942d2SChristophe Leroy { .type = CRYPTO_ALG_TYPE_SKCIPHER,
278643a942d2SChristophe Leroy .alg.skcipher = {
2787373960d7SArd Biesheuvel .base.cra_name = "ecb(des)",
2788373960d7SArd Biesheuvel .base.cra_driver_name = "ecb-des-talitos",
2789373960d7SArd Biesheuvel .base.cra_blocksize = DES_BLOCK_SIZE,
2790b8aa7dc5SMikulas Patocka .base.cra_flags = CRYPTO_ALG_ASYNC |
2791b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY,
27925e75ae1bSLEROY Christophe .min_keysize = DES_KEY_SIZE,
27935e75ae1bSLEROY Christophe .max_keysize = DES_KEY_SIZE,
2794373960d7SArd Biesheuvel .setkey = skcipher_des_setkey,
27955e75ae1bSLEROY Christophe },
27965e75ae1bSLEROY Christophe .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
27975e75ae1bSLEROY Christophe DESC_HDR_SEL0_DEU,
27985e75ae1bSLEROY Christophe },
2799373960d7SArd Biesheuvel { .type = CRYPTO_ALG_TYPE_SKCIPHER,
2800373960d7SArd Biesheuvel .alg.skcipher = {
2801373960d7SArd Biesheuvel .base.cra_name = "cbc(des)",
2802373960d7SArd Biesheuvel .base.cra_driver_name = "cbc-des-talitos",
2803373960d7SArd Biesheuvel .base.cra_blocksize = DES_BLOCK_SIZE,
2804b8aa7dc5SMikulas Patocka .base.cra_flags = CRYPTO_ALG_ASYNC |
2805b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY,
28065e75ae1bSLEROY Christophe .min_keysize = DES_KEY_SIZE,
28075e75ae1bSLEROY Christophe .max_keysize = DES_KEY_SIZE,
28085e75ae1bSLEROY Christophe .ivsize = DES_BLOCK_SIZE,
2809373960d7SArd Biesheuvel .setkey = skcipher_des_setkey,
28105e75ae1bSLEROY Christophe },
28115e75ae1bSLEROY Christophe .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
28125e75ae1bSLEROY Christophe DESC_HDR_SEL0_DEU |
28135e75ae1bSLEROY Christophe DESC_HDR_MODE0_DEU_CBC,
28145e75ae1bSLEROY Christophe },
2815373960d7SArd Biesheuvel { .type = CRYPTO_ALG_TYPE_SKCIPHER,
2816373960d7SArd Biesheuvel .alg.skcipher = {
2817373960d7SArd Biesheuvel .base.cra_name = "ecb(des3_ede)",
2818373960d7SArd Biesheuvel .base.cra_driver_name = "ecb-3des-talitos",
2819373960d7SArd Biesheuvel .base.cra_blocksize = DES3_EDE_BLOCK_SIZE,
2820b8aa7dc5SMikulas Patocka .base.cra_flags = CRYPTO_ALG_ASYNC |
2821b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY,
28225e75ae1bSLEROY Christophe .min_keysize = DES3_EDE_KEY_SIZE,
28235e75ae1bSLEROY Christophe .max_keysize = DES3_EDE_KEY_SIZE,
2824373960d7SArd Biesheuvel .setkey = skcipher_des3_setkey,
28255e75ae1bSLEROY Christophe },
28265e75ae1bSLEROY Christophe .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
28275e75ae1bSLEROY Christophe DESC_HDR_SEL0_DEU |
28285e75ae1bSLEROY Christophe DESC_HDR_MODE0_DEU_3DES,
28295e75ae1bSLEROY Christophe },
2830373960d7SArd Biesheuvel { .type = CRYPTO_ALG_TYPE_SKCIPHER,
2831373960d7SArd Biesheuvel .alg.skcipher = {
2832373960d7SArd Biesheuvel .base.cra_name = "cbc(des3_ede)",
2833373960d7SArd Biesheuvel .base.cra_driver_name = "cbc-3des-talitos",
2834373960d7SArd Biesheuvel .base.cra_blocksize = DES3_EDE_BLOCK_SIZE,
2835b8aa7dc5SMikulas Patocka .base.cra_flags = CRYPTO_ALG_ASYNC |
2836b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY,
28374de9d0b5SLee Nipper .min_keysize = DES3_EDE_KEY_SIZE,
28384de9d0b5SLee Nipper .max_keysize = DES3_EDE_KEY_SIZE,
28394de9d0b5SLee Nipper .ivsize = DES3_EDE_BLOCK_SIZE,
2840373960d7SArd Biesheuvel .setkey = skcipher_des3_setkey,
28414de9d0b5SLee Nipper },
28424de9d0b5SLee Nipper .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
28434de9d0b5SLee Nipper DESC_HDR_SEL0_DEU |
28444de9d0b5SLee Nipper DESC_HDR_MODE0_DEU_CBC |
28454de9d0b5SLee Nipper DESC_HDR_MODE0_DEU_3DES,
2846497f2e6bSLee Nipper },
2847497f2e6bSLee Nipper /* AHASH algorithms. */
2848497f2e6bSLee Nipper { .type = CRYPTO_ALG_TYPE_AHASH,
2849497f2e6bSLee Nipper .alg.hash = {
2850497f2e6bSLee Nipper .halg.digestsize = MD5_DIGEST_SIZE,
28513639ca84SHoria Geant? .halg.statesize = sizeof(struct talitos_export_state),
2852497f2e6bSLee Nipper .halg.base = {
2853497f2e6bSLee Nipper .cra_name = "md5",
2854497f2e6bSLee Nipper .cra_driver_name = "md5-talitos",
2855b3988618SMartin Hicks .cra_blocksize = MD5_HMAC_BLOCK_SIZE,
2856b8aa7dc5SMikulas Patocka .cra_flags = CRYPTO_ALG_ASYNC |
2857b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY,
28589c4a7965SKim Phillips }
2859497f2e6bSLee Nipper },
2860497f2e6bSLee Nipper .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2861497f2e6bSLee Nipper DESC_HDR_SEL0_MDEUA |
2862497f2e6bSLee Nipper DESC_HDR_MODE0_MDEU_MD5,
2863497f2e6bSLee Nipper },
2864497f2e6bSLee Nipper { .type = CRYPTO_ALG_TYPE_AHASH,
2865497f2e6bSLee Nipper .alg.hash = {
2866497f2e6bSLee Nipper .halg.digestsize = SHA1_DIGEST_SIZE,
28673639ca84SHoria Geant? .halg.statesize = sizeof(struct talitos_export_state),
2868497f2e6bSLee Nipper .halg.base = {
2869497f2e6bSLee Nipper .cra_name = "sha1",
2870497f2e6bSLee Nipper .cra_driver_name = "sha1-talitos",
2871497f2e6bSLee Nipper .cra_blocksize = SHA1_BLOCK_SIZE,
2872b8aa7dc5SMikulas Patocka .cra_flags = CRYPTO_ALG_ASYNC |
2873b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY,
2874497f2e6bSLee Nipper }
2875497f2e6bSLee Nipper },
2876497f2e6bSLee Nipper .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2877497f2e6bSLee Nipper DESC_HDR_SEL0_MDEUA |
2878497f2e6bSLee Nipper DESC_HDR_MODE0_MDEU_SHA1,
2879497f2e6bSLee Nipper },
2880497f2e6bSLee Nipper { .type = CRYPTO_ALG_TYPE_AHASH,
2881497f2e6bSLee Nipper .alg.hash = {
288260f208d7SKim Phillips .halg.digestsize = SHA224_DIGEST_SIZE,
28833639ca84SHoria Geant? .halg.statesize = sizeof(struct talitos_export_state),
288460f208d7SKim Phillips .halg.base = {
288560f208d7SKim Phillips .cra_name = "sha224",
288660f208d7SKim Phillips .cra_driver_name = "sha224-talitos",
288760f208d7SKim Phillips .cra_blocksize = SHA224_BLOCK_SIZE,
2888b8aa7dc5SMikulas Patocka .cra_flags = CRYPTO_ALG_ASYNC |
2889b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY,
289060f208d7SKim Phillips }
289160f208d7SKim Phillips },
289260f208d7SKim Phillips .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
289360f208d7SKim Phillips DESC_HDR_SEL0_MDEUA |
289460f208d7SKim Phillips DESC_HDR_MODE0_MDEU_SHA224,
289560f208d7SKim Phillips },
289660f208d7SKim Phillips { .type = CRYPTO_ALG_TYPE_AHASH,
289760f208d7SKim Phillips .alg.hash = {
2898497f2e6bSLee Nipper .halg.digestsize = SHA256_DIGEST_SIZE,
28993639ca84SHoria Geant? .halg.statesize = sizeof(struct talitos_export_state),
2900497f2e6bSLee Nipper .halg.base = {
2901497f2e6bSLee Nipper .cra_name = "sha256",
2902497f2e6bSLee Nipper .cra_driver_name = "sha256-talitos",
2903497f2e6bSLee Nipper .cra_blocksize = SHA256_BLOCK_SIZE,
2904b8aa7dc5SMikulas Patocka .cra_flags = CRYPTO_ALG_ASYNC |
2905b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY,
2906497f2e6bSLee Nipper }
2907497f2e6bSLee Nipper },
2908497f2e6bSLee Nipper .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2909497f2e6bSLee Nipper DESC_HDR_SEL0_MDEUA |
2910497f2e6bSLee Nipper DESC_HDR_MODE0_MDEU_SHA256,
2911497f2e6bSLee Nipper },
2912497f2e6bSLee Nipper { .type = CRYPTO_ALG_TYPE_AHASH,
2913497f2e6bSLee Nipper .alg.hash = {
2914497f2e6bSLee Nipper .halg.digestsize = SHA384_DIGEST_SIZE,
29153639ca84SHoria Geant? .halg.statesize = sizeof(struct talitos_export_state),
2916497f2e6bSLee Nipper .halg.base = {
2917497f2e6bSLee Nipper .cra_name = "sha384",
2918497f2e6bSLee Nipper .cra_driver_name = "sha384-talitos",
2919497f2e6bSLee Nipper .cra_blocksize = SHA384_BLOCK_SIZE,
2920b8aa7dc5SMikulas Patocka .cra_flags = CRYPTO_ALG_ASYNC |
2921b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY,
2922497f2e6bSLee Nipper }
2923497f2e6bSLee Nipper },
2924497f2e6bSLee Nipper .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2925497f2e6bSLee Nipper DESC_HDR_SEL0_MDEUB |
2926497f2e6bSLee Nipper DESC_HDR_MODE0_MDEUB_SHA384,
2927497f2e6bSLee Nipper },
2928497f2e6bSLee Nipper { .type = CRYPTO_ALG_TYPE_AHASH,
2929497f2e6bSLee Nipper .alg.hash = {
2930497f2e6bSLee Nipper .halg.digestsize = SHA512_DIGEST_SIZE,
29313639ca84SHoria Geant? .halg.statesize = sizeof(struct talitos_export_state),
2932497f2e6bSLee Nipper .halg.base = {
2933497f2e6bSLee Nipper .cra_name = "sha512",
2934497f2e6bSLee Nipper .cra_driver_name = "sha512-talitos",
2935497f2e6bSLee Nipper .cra_blocksize = SHA512_BLOCK_SIZE,
2936b8aa7dc5SMikulas Patocka .cra_flags = CRYPTO_ALG_ASYNC |
2937b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY,
2938497f2e6bSLee Nipper }
2939497f2e6bSLee Nipper },
2940497f2e6bSLee Nipper .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2941497f2e6bSLee Nipper DESC_HDR_SEL0_MDEUB |
2942497f2e6bSLee Nipper DESC_HDR_MODE0_MDEUB_SHA512,
2943497f2e6bSLee Nipper },
294479b3a418SLee Nipper { .type = CRYPTO_ALG_TYPE_AHASH,
294579b3a418SLee Nipper .alg.hash = {
294679b3a418SLee Nipper .halg.digestsize = MD5_DIGEST_SIZE,
29473639ca84SHoria Geant? .halg.statesize = sizeof(struct talitos_export_state),
294879b3a418SLee Nipper .halg.base = {
294979b3a418SLee Nipper .cra_name = "hmac(md5)",
295079b3a418SLee Nipper .cra_driver_name = "hmac-md5-talitos",
2951b3988618SMartin Hicks .cra_blocksize = MD5_HMAC_BLOCK_SIZE,
2952b8aa7dc5SMikulas Patocka .cra_flags = CRYPTO_ALG_ASYNC |
2953b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY,
295479b3a418SLee Nipper }
295579b3a418SLee Nipper },
295679b3a418SLee Nipper .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
295779b3a418SLee Nipper DESC_HDR_SEL0_MDEUA |
295879b3a418SLee Nipper DESC_HDR_MODE0_MDEU_MD5,
295979b3a418SLee Nipper },
296079b3a418SLee Nipper { .type = CRYPTO_ALG_TYPE_AHASH,
296179b3a418SLee Nipper .alg.hash = {
296279b3a418SLee Nipper .halg.digestsize = SHA1_DIGEST_SIZE,
29633639ca84SHoria Geant? .halg.statesize = sizeof(struct talitos_export_state),
296479b3a418SLee Nipper .halg.base = {
296579b3a418SLee Nipper .cra_name = "hmac(sha1)",
296679b3a418SLee Nipper .cra_driver_name = "hmac-sha1-talitos",
296779b3a418SLee Nipper .cra_blocksize = SHA1_BLOCK_SIZE,
2968b8aa7dc5SMikulas Patocka .cra_flags = CRYPTO_ALG_ASYNC |
2969b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY,
297079b3a418SLee Nipper }
297179b3a418SLee Nipper },
297279b3a418SLee Nipper .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
297379b3a418SLee Nipper DESC_HDR_SEL0_MDEUA |
297479b3a418SLee Nipper DESC_HDR_MODE0_MDEU_SHA1,
297579b3a418SLee Nipper },
297679b3a418SLee Nipper { .type = CRYPTO_ALG_TYPE_AHASH,
297779b3a418SLee Nipper .alg.hash = {
297879b3a418SLee Nipper .halg.digestsize = SHA224_DIGEST_SIZE,
29793639ca84SHoria Geant? .halg.statesize = sizeof(struct talitos_export_state),
298079b3a418SLee Nipper .halg.base = {
298179b3a418SLee Nipper .cra_name = "hmac(sha224)",
298279b3a418SLee Nipper .cra_driver_name = "hmac-sha224-talitos",
298379b3a418SLee Nipper .cra_blocksize = SHA224_BLOCK_SIZE,
2984b8aa7dc5SMikulas Patocka .cra_flags = CRYPTO_ALG_ASYNC |
2985b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY,
298679b3a418SLee Nipper }
298779b3a418SLee Nipper },
298879b3a418SLee Nipper .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
298979b3a418SLee Nipper DESC_HDR_SEL0_MDEUA |
299079b3a418SLee Nipper DESC_HDR_MODE0_MDEU_SHA224,
299179b3a418SLee Nipper },
299279b3a418SLee Nipper { .type = CRYPTO_ALG_TYPE_AHASH,
299379b3a418SLee Nipper .alg.hash = {
299479b3a418SLee Nipper .halg.digestsize = SHA256_DIGEST_SIZE,
29953639ca84SHoria Geant? .halg.statesize = sizeof(struct talitos_export_state),
299679b3a418SLee Nipper .halg.base = {
299779b3a418SLee Nipper .cra_name = "hmac(sha256)",
299879b3a418SLee Nipper .cra_driver_name = "hmac-sha256-talitos",
299979b3a418SLee Nipper .cra_blocksize = SHA256_BLOCK_SIZE,
3000b8aa7dc5SMikulas Patocka .cra_flags = CRYPTO_ALG_ASYNC |
3001b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY,
300279b3a418SLee Nipper }
300379b3a418SLee Nipper },
300479b3a418SLee Nipper .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
300579b3a418SLee Nipper DESC_HDR_SEL0_MDEUA |
300679b3a418SLee Nipper DESC_HDR_MODE0_MDEU_SHA256,
300779b3a418SLee Nipper },
300879b3a418SLee Nipper { .type = CRYPTO_ALG_TYPE_AHASH,
300979b3a418SLee Nipper .alg.hash = {
301079b3a418SLee Nipper .halg.digestsize = SHA384_DIGEST_SIZE,
30113639ca84SHoria Geant? .halg.statesize = sizeof(struct talitos_export_state),
301279b3a418SLee Nipper .halg.base = {
301379b3a418SLee Nipper .cra_name = "hmac(sha384)",
301479b3a418SLee Nipper .cra_driver_name = "hmac-sha384-talitos",
301579b3a418SLee Nipper .cra_blocksize = SHA384_BLOCK_SIZE,
3016b8aa7dc5SMikulas Patocka .cra_flags = CRYPTO_ALG_ASYNC |
3017b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY,
301879b3a418SLee Nipper }
301979b3a418SLee Nipper },
302079b3a418SLee Nipper .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
302179b3a418SLee Nipper DESC_HDR_SEL0_MDEUB |
302279b3a418SLee Nipper DESC_HDR_MODE0_MDEUB_SHA384,
302379b3a418SLee Nipper },
302479b3a418SLee Nipper { .type = CRYPTO_ALG_TYPE_AHASH,
302579b3a418SLee Nipper .alg.hash = {
302679b3a418SLee Nipper .halg.digestsize = SHA512_DIGEST_SIZE,
30273639ca84SHoria Geant? .halg.statesize = sizeof(struct talitos_export_state),
302879b3a418SLee Nipper .halg.base = {
302979b3a418SLee Nipper .cra_name = "hmac(sha512)",
303079b3a418SLee Nipper .cra_driver_name = "hmac-sha512-talitos",
303179b3a418SLee Nipper .cra_blocksize = SHA512_BLOCK_SIZE,
3032b8aa7dc5SMikulas Patocka .cra_flags = CRYPTO_ALG_ASYNC |
3033b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY,
303479b3a418SLee Nipper }
303579b3a418SLee Nipper },
303679b3a418SLee Nipper .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
303779b3a418SLee Nipper DESC_HDR_SEL0_MDEUB |
303879b3a418SLee Nipper DESC_HDR_MODE0_MDEUB_SHA512,
303979b3a418SLee Nipper }
30409c4a7965SKim Phillips };
30419c4a7965SKim Phillips
30429c4a7965SKim Phillips struct talitos_crypto_alg {
30439c4a7965SKim Phillips struct list_head entry;
30449c4a7965SKim Phillips struct device *dev;
3045acbf7c62SLee Nipper struct talitos_alg_template algt;
30469c4a7965SKim Phillips };
30479c4a7965SKim Phillips
talitos_init_common(struct talitos_ctx * ctx,struct talitos_crypto_alg * talitos_alg)304889d124cbSJonas Eymann static int talitos_init_common(struct talitos_ctx *ctx,
304989d124cbSJonas Eymann struct talitos_crypto_alg *talitos_alg)
30509c4a7965SKim Phillips {
30515228f0f7SKim Phillips struct talitos_private *priv;
30529c4a7965SKim Phillips
30539c4a7965SKim Phillips /* update context with ptr to dev */
30549c4a7965SKim Phillips ctx->dev = talitos_alg->dev;
305519bbbc63SKim Phillips
30565228f0f7SKim Phillips /* assign SEC channel to tfm in round-robin fashion */
30575228f0f7SKim Phillips priv = dev_get_drvdata(ctx->dev);
30585228f0f7SKim Phillips ctx->ch = atomic_inc_return(&priv->last_chan) &
30595228f0f7SKim Phillips (priv->num_channels - 1);
30605228f0f7SKim Phillips
30619c4a7965SKim Phillips /* copy descriptor header template value */
3062acbf7c62SLee Nipper ctx->desc_hdr_template = talitos_alg->algt.desc_hdr_template;
30639c4a7965SKim Phillips
3064602dba5aSKim Phillips /* select done notification */
3065602dba5aSKim Phillips ctx->desc_hdr_template |= DESC_HDR_DONE_NOTIFY;
3066602dba5aSKim Phillips
3067497f2e6bSLee Nipper return 0;
3068497f2e6bSLee Nipper }
3069497f2e6bSLee Nipper
talitos_cra_init_aead(struct crypto_aead * tfm)3070aeb4c132SHerbert Xu static int talitos_cra_init_aead(struct crypto_aead *tfm)
3071497f2e6bSLee Nipper {
307289d124cbSJonas Eymann struct aead_alg *alg = crypto_aead_alg(tfm);
307389d124cbSJonas Eymann struct talitos_crypto_alg *talitos_alg;
307489d124cbSJonas Eymann struct talitos_ctx *ctx = crypto_aead_ctx(tfm);
307589d124cbSJonas Eymann
307689d124cbSJonas Eymann talitos_alg = container_of(alg, struct talitos_crypto_alg,
307789d124cbSJonas Eymann algt.alg.aead);
307889d124cbSJonas Eymann
307989d124cbSJonas Eymann return talitos_init_common(ctx, talitos_alg);
30809c4a7965SKim Phillips }
30819c4a7965SKim Phillips
talitos_cra_init_skcipher(struct crypto_skcipher * tfm)3082373960d7SArd Biesheuvel static int talitos_cra_init_skcipher(struct crypto_skcipher *tfm)
3083373960d7SArd Biesheuvel {
3084373960d7SArd Biesheuvel struct skcipher_alg *alg = crypto_skcipher_alg(tfm);
3085373960d7SArd Biesheuvel struct talitos_crypto_alg *talitos_alg;
3086373960d7SArd Biesheuvel struct talitos_ctx *ctx = crypto_skcipher_ctx(tfm);
3087373960d7SArd Biesheuvel
3088373960d7SArd Biesheuvel talitos_alg = container_of(alg, struct talitos_crypto_alg,
3089373960d7SArd Biesheuvel algt.alg.skcipher);
3090373960d7SArd Biesheuvel
3091373960d7SArd Biesheuvel return talitos_init_common(ctx, talitos_alg);
3092373960d7SArd Biesheuvel }
3093373960d7SArd Biesheuvel
talitos_cra_init_ahash(struct crypto_tfm * tfm)3094497f2e6bSLee Nipper static int talitos_cra_init_ahash(struct crypto_tfm *tfm)
3095497f2e6bSLee Nipper {
3096373960d7SArd Biesheuvel struct crypto_alg *alg = tfm->__crt_alg;
3097373960d7SArd Biesheuvel struct talitos_crypto_alg *talitos_alg;
3098497f2e6bSLee Nipper struct talitos_ctx *ctx = crypto_tfm_ctx(tfm);
3099497f2e6bSLee Nipper
3100373960d7SArd Biesheuvel talitos_alg = container_of(__crypto_ahash_alg(alg),
3101373960d7SArd Biesheuvel struct talitos_crypto_alg,
3102373960d7SArd Biesheuvel algt.alg.hash);
3103497f2e6bSLee Nipper
3104497f2e6bSLee Nipper ctx->keylen = 0;
3105497f2e6bSLee Nipper crypto_ahash_set_reqsize(__crypto_ahash_cast(tfm),
3106497f2e6bSLee Nipper sizeof(struct talitos_ahash_req_ctx));
3107497f2e6bSLee Nipper
3108373960d7SArd Biesheuvel return talitos_init_common(ctx, talitos_alg);
3109497f2e6bSLee Nipper }
3110497f2e6bSLee Nipper
talitos_cra_exit(struct crypto_tfm * tfm)31112e13ce08SLEROY Christophe static void talitos_cra_exit(struct crypto_tfm *tfm)
31122e13ce08SLEROY Christophe {
31132e13ce08SLEROY Christophe struct talitos_ctx *ctx = crypto_tfm_ctx(tfm);
31142e13ce08SLEROY Christophe struct device *dev = ctx->dev;
31152e13ce08SLEROY Christophe
31162e13ce08SLEROY Christophe if (ctx->keylen)
31172e13ce08SLEROY Christophe dma_unmap_single(dev, ctx->dma_key, ctx->keylen, DMA_TO_DEVICE);
31182e13ce08SLEROY Christophe }
31192e13ce08SLEROY Christophe
31209c4a7965SKim Phillips /*
31219c4a7965SKim Phillips * given the alg's descriptor header template, determine whether descriptor
31229c4a7965SKim Phillips * type and primary/secondary execution units required match the hw
31239c4a7965SKim Phillips * capabilities description provided in the device tree node.
31249c4a7965SKim Phillips */
hw_supports(struct device * dev,__be32 desc_hdr_template)31259c4a7965SKim Phillips static int hw_supports(struct device *dev, __be32 desc_hdr_template)
31269c4a7965SKim Phillips {
31279c4a7965SKim Phillips struct talitos_private *priv = dev_get_drvdata(dev);
31289c4a7965SKim Phillips int ret;
31299c4a7965SKim Phillips
31309c4a7965SKim Phillips ret = (1 << DESC_TYPE(desc_hdr_template) & priv->desc_types) &&
31319c4a7965SKim Phillips (1 << PRIMARY_EU(desc_hdr_template) & priv->exec_units);
31329c4a7965SKim Phillips
31339c4a7965SKim Phillips if (SECONDARY_EU(desc_hdr_template))
31349c4a7965SKim Phillips ret = ret && (1 << SECONDARY_EU(desc_hdr_template)
31359c4a7965SKim Phillips & priv->exec_units);
31369c4a7965SKim Phillips
31379c4a7965SKim Phillips return ret;
31389c4a7965SKim Phillips }
31399c4a7965SKim Phillips
talitos_remove(struct platform_device * ofdev)3140ce52705eSUwe Kleine-König static void talitos_remove(struct platform_device *ofdev)
31419c4a7965SKim Phillips {
31429c4a7965SKim Phillips struct device *dev = &ofdev->dev;
31439c4a7965SKim Phillips struct talitos_private *priv = dev_get_drvdata(dev);
31449c4a7965SKim Phillips struct talitos_crypto_alg *t_alg, *n;
31459c4a7965SKim Phillips int i;
31469c4a7965SKim Phillips
31479c4a7965SKim Phillips list_for_each_entry_safe(t_alg, n, &priv->alg_list, entry) {
3148acbf7c62SLee Nipper switch (t_alg->algt.type) {
3149373960d7SArd Biesheuvel case CRYPTO_ALG_TYPE_SKCIPHER:
3150373960d7SArd Biesheuvel crypto_unregister_skcipher(&t_alg->algt.alg.skcipher);
3151acbf7c62SLee Nipper break;
3152aeb4c132SHerbert Xu case CRYPTO_ALG_TYPE_AEAD:
3153aeb4c132SHerbert Xu crypto_unregister_aead(&t_alg->algt.alg.aead);
31545fc194eaSGustavo A. R. Silva break;
3155acbf7c62SLee Nipper case CRYPTO_ALG_TYPE_AHASH:
3156acbf7c62SLee Nipper crypto_unregister_ahash(&t_alg->algt.alg.hash);
3157acbf7c62SLee Nipper break;
3158acbf7c62SLee Nipper }
31599c4a7965SKim Phillips list_del(&t_alg->entry);
31609c4a7965SKim Phillips }
31619c4a7965SKim Phillips
31629c4a7965SKim Phillips if (hw_supports(dev, DESC_HDR_SEL0_RNG))
31639c4a7965SKim Phillips talitos_unregister_rng(dev);
31649c4a7965SKim Phillips
3165c3e337f8SKim Phillips for (i = 0; i < 2; i++)
31662cdba3cfSKim Phillips if (priv->irq[i]) {
3167c3e337f8SKim Phillips free_irq(priv->irq[i], dev);
3168c3e337f8SKim Phillips irq_dispose_mapping(priv->irq[i]);
31699c4a7965SKim Phillips }
31709c4a7965SKim Phillips
3171c3e337f8SKim Phillips tasklet_kill(&priv->done_task[0]);
31722cdba3cfSKim Phillips if (priv->irq[1])
3173c3e337f8SKim Phillips tasklet_kill(&priv->done_task[1]);
31749c4a7965SKim Phillips }
31759c4a7965SKim Phillips
talitos_alg_alloc(struct device * dev,struct talitos_alg_template * template)31769c4a7965SKim Phillips static struct talitos_crypto_alg *talitos_alg_alloc(struct device *dev,
31779c4a7965SKim Phillips struct talitos_alg_template
31789c4a7965SKim Phillips *template)
31799c4a7965SKim Phillips {
318060f208d7SKim Phillips struct talitos_private *priv = dev_get_drvdata(dev);
31819c4a7965SKim Phillips struct talitos_crypto_alg *t_alg;
31829c4a7965SKim Phillips struct crypto_alg *alg;
31839c4a7965SKim Phillips
318424b92ff2SLEROY Christophe t_alg = devm_kzalloc(dev, sizeof(struct talitos_crypto_alg),
318524b92ff2SLEROY Christophe GFP_KERNEL);
31869c4a7965SKim Phillips if (!t_alg)
31879c4a7965SKim Phillips return ERR_PTR(-ENOMEM);
31889c4a7965SKim Phillips
3189acbf7c62SLee Nipper t_alg->algt = *template;
3190acbf7c62SLee Nipper
3191acbf7c62SLee Nipper switch (t_alg->algt.type) {
3192373960d7SArd Biesheuvel case CRYPTO_ALG_TYPE_SKCIPHER:
3193373960d7SArd Biesheuvel alg = &t_alg->algt.alg.skcipher.base;
31942e13ce08SLEROY Christophe alg->cra_exit = talitos_cra_exit;
3195373960d7SArd Biesheuvel t_alg->algt.alg.skcipher.init = talitos_cra_init_skcipher;
3196373960d7SArd Biesheuvel t_alg->algt.alg.skcipher.setkey =
3197373960d7SArd Biesheuvel t_alg->algt.alg.skcipher.setkey ?: skcipher_setkey;
3198373960d7SArd Biesheuvel t_alg->algt.alg.skcipher.encrypt = skcipher_encrypt;
3199373960d7SArd Biesheuvel t_alg->algt.alg.skcipher.decrypt = skcipher_decrypt;
320043a942d2SChristophe Leroy if (!strcmp(alg->cra_name, "ctr(aes)") && !has_ftr_sec1(priv) &&
320143a942d2SChristophe Leroy DESC_TYPE(t_alg->algt.desc_hdr_template) !=
320243a942d2SChristophe Leroy DESC_TYPE(DESC_HDR_TYPE_AESU_CTR_NONSNOOP)) {
320343a942d2SChristophe Leroy devm_kfree(dev, t_alg);
320443a942d2SChristophe Leroy return ERR_PTR(-ENOTSUPP);
320543a942d2SChristophe Leroy }
3206497f2e6bSLee Nipper break;
3207acbf7c62SLee Nipper case CRYPTO_ALG_TYPE_AEAD:
3208aeb4c132SHerbert Xu alg = &t_alg->algt.alg.aead.base;
32092e13ce08SLEROY Christophe alg->cra_exit = talitos_cra_exit;
3210aeb4c132SHerbert Xu t_alg->algt.alg.aead.init = talitos_cra_init_aead;
3211ef7c5c85SHerbert Xu t_alg->algt.alg.aead.setkey = t_alg->algt.alg.aead.setkey ?:
3212ef7c5c85SHerbert Xu aead_setkey;
3213aeb4c132SHerbert Xu t_alg->algt.alg.aead.encrypt = aead_encrypt;
3214aeb4c132SHerbert Xu t_alg->algt.alg.aead.decrypt = aead_decrypt;
32156cda075aSLEROY Christophe if (!(priv->features & TALITOS_FTR_SHA224_HWINIT) &&
32166cda075aSLEROY Christophe !strncmp(alg->cra_name, "authenc(hmac(sha224)", 20)) {
321724b92ff2SLEROY Christophe devm_kfree(dev, t_alg);
32186cda075aSLEROY Christophe return ERR_PTR(-ENOTSUPP);
32196cda075aSLEROY Christophe }
3220acbf7c62SLee Nipper break;
3221acbf7c62SLee Nipper case CRYPTO_ALG_TYPE_AHASH:
3222acbf7c62SLee Nipper alg = &t_alg->algt.alg.hash.halg.base;
3223497f2e6bSLee Nipper alg->cra_init = talitos_cra_init_ahash;
3224ad4cd51fSLEROY Christophe alg->cra_exit = talitos_cra_exit;
3225b286e003SKim Phillips t_alg->algt.alg.hash.init = ahash_init;
3226b286e003SKim Phillips t_alg->algt.alg.hash.update = ahash_update;
3227b286e003SKim Phillips t_alg->algt.alg.hash.final = ahash_final;
3228b286e003SKim Phillips t_alg->algt.alg.hash.finup = ahash_finup;
3229b286e003SKim Phillips t_alg->algt.alg.hash.digest = ahash_digest;
323056136631SLEROY Christophe if (!strncmp(alg->cra_name, "hmac", 4))
3231b286e003SKim Phillips t_alg->algt.alg.hash.setkey = ahash_setkey;
32323639ca84SHoria Geant? t_alg->algt.alg.hash.import = ahash_import;
32333639ca84SHoria Geant? t_alg->algt.alg.hash.export = ahash_export;
3234b286e003SKim Phillips
323579b3a418SLee Nipper if (!(priv->features & TALITOS_FTR_HMAC_OK) &&
32360b2730d8SKim Phillips !strncmp(alg->cra_name, "hmac", 4)) {
323724b92ff2SLEROY Christophe devm_kfree(dev, t_alg);
323879b3a418SLee Nipper return ERR_PTR(-ENOTSUPP);
32390b2730d8SKim Phillips }
324060f208d7SKim Phillips if (!(priv->features & TALITOS_FTR_SHA224_HWINIT) &&
324179b3a418SLee Nipper (!strcmp(alg->cra_name, "sha224") ||
324279b3a418SLee Nipper !strcmp(alg->cra_name, "hmac(sha224)"))) {
324360f208d7SKim Phillips t_alg->algt.alg.hash.init = ahash_init_sha224_swinit;
3244*9826d1d6SEric Biggers t_alg->algt.alg.hash.digest =
3245*9826d1d6SEric Biggers ahash_digest_sha224_swinit;
324660f208d7SKim Phillips t_alg->algt.desc_hdr_template =
324760f208d7SKim Phillips DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
324860f208d7SKim Phillips DESC_HDR_SEL0_MDEUA |
324960f208d7SKim Phillips DESC_HDR_MODE0_MDEU_SHA256;
325060f208d7SKim Phillips }
3251497f2e6bSLee Nipper break;
32521d11911aSKim Phillips default:
32531d11911aSKim Phillips dev_err(dev, "unknown algorithm type %d\n", t_alg->algt.type);
325424b92ff2SLEROY Christophe devm_kfree(dev, t_alg);
32551d11911aSKim Phillips return ERR_PTR(-EINVAL);
3256acbf7c62SLee Nipper }
32579c4a7965SKim Phillips
32589c4a7965SKim Phillips alg->cra_module = THIS_MODULE;
3259b0057763SLEROY Christophe if (t_alg->algt.priority)
3260b0057763SLEROY Christophe alg->cra_priority = t_alg->algt.priority;
3261b0057763SLEROY Christophe else
32629c4a7965SKim Phillips alg->cra_priority = TALITOS_CRA_PRIORITY;
3263492444c3SEric Biggers if (has_ftr_sec1(priv) && t_alg->algt.type != CRYPTO_ALG_TYPE_AHASH)
3264c9cca703SChristophe Leroy alg->cra_alignmask = 3;
3265c9cca703SChristophe Leroy else
32669c4a7965SKim Phillips alg->cra_alignmask = 0;
32679c4a7965SKim Phillips alg->cra_ctxsize = sizeof(struct talitos_ctx);
3268d912bb76SNikos Mavrogiannopoulos alg->cra_flags |= CRYPTO_ALG_KERN_DRIVER_ONLY;
32699c4a7965SKim Phillips
32709c4a7965SKim Phillips t_alg->dev = dev;
32719c4a7965SKim Phillips
32729c4a7965SKim Phillips return t_alg;
32739c4a7965SKim Phillips }
32749c4a7965SKim Phillips
talitos_probe_irq(struct platform_device * ofdev)3275c3e337f8SKim Phillips static int talitos_probe_irq(struct platform_device *ofdev)
3276c3e337f8SKim Phillips {
3277c3e337f8SKim Phillips struct device *dev = &ofdev->dev;
3278c3e337f8SKim Phillips struct device_node *np = ofdev->dev.of_node;
3279c3e337f8SKim Phillips struct talitos_private *priv = dev_get_drvdata(dev);
3280c3e337f8SKim Phillips int err;
3281dd3c0987SLEROY Christophe bool is_sec1 = has_ftr_sec1(priv);
3282c3e337f8SKim Phillips
3283c3e337f8SKim Phillips priv->irq[0] = irq_of_parse_and_map(np, 0);
32842cdba3cfSKim Phillips if (!priv->irq[0]) {
3285c3e337f8SKim Phillips dev_err(dev, "failed to map irq\n");
3286c3e337f8SKim Phillips return -EINVAL;
3287c3e337f8SKim Phillips }
3288dd3c0987SLEROY Christophe if (is_sec1) {
3289dd3c0987SLEROY Christophe err = request_irq(priv->irq[0], talitos1_interrupt_4ch, 0,
3290dd3c0987SLEROY Christophe dev_driver_string(dev), dev);
3291dd3c0987SLEROY Christophe goto primary_out;
3292dd3c0987SLEROY Christophe }
3293c3e337f8SKim Phillips
3294c3e337f8SKim Phillips priv->irq[1] = irq_of_parse_and_map(np, 1);
3295c3e337f8SKim Phillips
3296c3e337f8SKim Phillips /* get the primary irq line */
32972cdba3cfSKim Phillips if (!priv->irq[1]) {
3298dd3c0987SLEROY Christophe err = request_irq(priv->irq[0], talitos2_interrupt_4ch, 0,
3299c3e337f8SKim Phillips dev_driver_string(dev), dev);
3300c3e337f8SKim Phillips goto primary_out;
3301c3e337f8SKim Phillips }
3302c3e337f8SKim Phillips
3303dd3c0987SLEROY Christophe err = request_irq(priv->irq[0], talitos2_interrupt_ch0_2, 0,
3304c3e337f8SKim Phillips dev_driver_string(dev), dev);
3305c3e337f8SKim Phillips if (err)
3306c3e337f8SKim Phillips goto primary_out;
3307c3e337f8SKim Phillips
3308c3e337f8SKim Phillips /* get the secondary irq line */
3309dd3c0987SLEROY Christophe err = request_irq(priv->irq[1], talitos2_interrupt_ch1_3, 0,
3310c3e337f8SKim Phillips dev_driver_string(dev), dev);
3311c3e337f8SKim Phillips if (err) {
3312c3e337f8SKim Phillips dev_err(dev, "failed to request secondary irq\n");
3313c3e337f8SKim Phillips irq_dispose_mapping(priv->irq[1]);
33142cdba3cfSKim Phillips priv->irq[1] = 0;
3315c3e337f8SKim Phillips }
3316c3e337f8SKim Phillips
3317c3e337f8SKim Phillips return err;
3318c3e337f8SKim Phillips
3319c3e337f8SKim Phillips primary_out:
3320c3e337f8SKim Phillips if (err) {
3321c3e337f8SKim Phillips dev_err(dev, "failed to request primary irq\n");
3322c3e337f8SKim Phillips irq_dispose_mapping(priv->irq[0]);
33232cdba3cfSKim Phillips priv->irq[0] = 0;
3324c3e337f8SKim Phillips }
3325c3e337f8SKim Phillips
3326c3e337f8SKim Phillips return err;
3327c3e337f8SKim Phillips }
3328c3e337f8SKim Phillips
talitos_probe(struct platform_device * ofdev)33291c48a5c9SGrant Likely static int talitos_probe(struct platform_device *ofdev)
33309c4a7965SKim Phillips {
33319c4a7965SKim Phillips struct device *dev = &ofdev->dev;
333261c7a080SGrant Likely struct device_node *np = ofdev->dev.of_node;
33339c4a7965SKim Phillips struct talitos_private *priv;
33349c4a7965SKim Phillips int i, err;
33355fa7fa14SLEROY Christophe int stride;
3336fd5ea7f0SLEROY Christophe struct resource *res;
33379c4a7965SKim Phillips
333824b92ff2SLEROY Christophe priv = devm_kzalloc(dev, sizeof(struct talitos_private), GFP_KERNEL);
33399c4a7965SKim Phillips if (!priv)
33409c4a7965SKim Phillips return -ENOMEM;
33419c4a7965SKim Phillips
3342f3de9cb1SKevin Hao INIT_LIST_HEAD(&priv->alg_list);
3343f3de9cb1SKevin Hao
33449c4a7965SKim Phillips dev_set_drvdata(dev, priv);
33459c4a7965SKim Phillips
33469c4a7965SKim Phillips priv->ofdev = ofdev;
33479c4a7965SKim Phillips
3348511d63cbSHoria Geanta spin_lock_init(&priv->reg_lock);
3349511d63cbSHoria Geanta
3350fd5ea7f0SLEROY Christophe res = platform_get_resource(ofdev, IORESOURCE_MEM, 0);
3351fd5ea7f0SLEROY Christophe if (!res)
3352fd5ea7f0SLEROY Christophe return -ENXIO;
3353fd5ea7f0SLEROY Christophe priv->reg = devm_ioremap(dev, res->start, resource_size(res));
33549c4a7965SKim Phillips if (!priv->reg) {
33559c4a7965SKim Phillips dev_err(dev, "failed to of_iomap\n");
33569c4a7965SKim Phillips err = -ENOMEM;
33579c4a7965SKim Phillips goto err_out;
33589c4a7965SKim Phillips }
33599c4a7965SKim Phillips
33609c4a7965SKim Phillips /* get SEC version capabilities from device tree */
3361fa14c6cfSLEROY Christophe of_property_read_u32(np, "fsl,num-channels", &priv->num_channels);
3362fa14c6cfSLEROY Christophe of_property_read_u32(np, "fsl,channel-fifo-len", &priv->chfifo_len);
3363fa14c6cfSLEROY Christophe of_property_read_u32(np, "fsl,exec-units-mask", &priv->exec_units);
3364fa14c6cfSLEROY Christophe of_property_read_u32(np, "fsl,descriptor-types-mask",
3365fa14c6cfSLEROY Christophe &priv->desc_types);
33669c4a7965SKim Phillips
33679c4a7965SKim Phillips if (!is_power_of_2(priv->num_channels) || !priv->chfifo_len ||
33689c4a7965SKim Phillips !priv->exec_units || !priv->desc_types) {
33699c4a7965SKim Phillips dev_err(dev, "invalid property data in device tree node\n");
33709c4a7965SKim Phillips err = -EINVAL;
33719c4a7965SKim Phillips goto err_out;
33729c4a7965SKim Phillips }
33739c4a7965SKim Phillips
3374f3c85bc1SLee Nipper if (of_device_is_compatible(np, "fsl,sec3.0"))
3375f3c85bc1SLee Nipper priv->features |= TALITOS_FTR_SRC_LINK_TBL_LEN_INCLUDES_EXTENT;
3376f3c85bc1SLee Nipper
3377fe5720e2SKim Phillips if (of_device_is_compatible(np, "fsl,sec2.1"))
337860f208d7SKim Phillips priv->features |= TALITOS_FTR_HW_AUTH_CHECK |
337979b3a418SLee Nipper TALITOS_FTR_SHA224_HWINIT |
338079b3a418SLee Nipper TALITOS_FTR_HMAC_OK;
3381fe5720e2SKim Phillips
338221590888SLEROY Christophe if (of_device_is_compatible(np, "fsl,sec1.0"))
338321590888SLEROY Christophe priv->features |= TALITOS_FTR_SEC1;
338421590888SLEROY Christophe
33855fa7fa14SLEROY Christophe if (of_device_is_compatible(np, "fsl,sec1.2")) {
33865fa7fa14SLEROY Christophe priv->reg_deu = priv->reg + TALITOS12_DEU;
33875fa7fa14SLEROY Christophe priv->reg_aesu = priv->reg + TALITOS12_AESU;
33885fa7fa14SLEROY Christophe priv->reg_mdeu = priv->reg + TALITOS12_MDEU;
33895fa7fa14SLEROY Christophe stride = TALITOS1_CH_STRIDE;
33905fa7fa14SLEROY Christophe } else if (of_device_is_compatible(np, "fsl,sec1.0")) {
33915fa7fa14SLEROY Christophe priv->reg_deu = priv->reg + TALITOS10_DEU;
33925fa7fa14SLEROY Christophe priv->reg_aesu = priv->reg + TALITOS10_AESU;
33935fa7fa14SLEROY Christophe priv->reg_mdeu = priv->reg + TALITOS10_MDEU;
33945fa7fa14SLEROY Christophe priv->reg_afeu = priv->reg + TALITOS10_AFEU;
33955fa7fa14SLEROY Christophe priv->reg_rngu = priv->reg + TALITOS10_RNGU;
33965fa7fa14SLEROY Christophe priv->reg_pkeu = priv->reg + TALITOS10_PKEU;
33975fa7fa14SLEROY Christophe stride = TALITOS1_CH_STRIDE;
33985fa7fa14SLEROY Christophe } else {
33995fa7fa14SLEROY Christophe priv->reg_deu = priv->reg + TALITOS2_DEU;
34005fa7fa14SLEROY Christophe priv->reg_aesu = priv->reg + TALITOS2_AESU;
34015fa7fa14SLEROY Christophe priv->reg_mdeu = priv->reg + TALITOS2_MDEU;
34025fa7fa14SLEROY Christophe priv->reg_afeu = priv->reg + TALITOS2_AFEU;
34035fa7fa14SLEROY Christophe priv->reg_rngu = priv->reg + TALITOS2_RNGU;
34045fa7fa14SLEROY Christophe priv->reg_pkeu = priv->reg + TALITOS2_PKEU;
34055fa7fa14SLEROY Christophe priv->reg_keu = priv->reg + TALITOS2_KEU;
34065fa7fa14SLEROY Christophe priv->reg_crcu = priv->reg + TALITOS2_CRCU;
34075fa7fa14SLEROY Christophe stride = TALITOS2_CH_STRIDE;
34085fa7fa14SLEROY Christophe }
34095fa7fa14SLEROY Christophe
3410dd3c0987SLEROY Christophe err = talitos_probe_irq(ofdev);
3411dd3c0987SLEROY Christophe if (err)
3412dd3c0987SLEROY Christophe goto err_out;
3413dd3c0987SLEROY Christophe
3414c8c74647SChristophe Leroy if (has_ftr_sec1(priv)) {
34159c02e285SLEROY Christophe if (priv->num_channels == 1)
34169c02e285SLEROY Christophe tasklet_init(&priv->done_task[0], talitos1_done_ch0,
34179c02e285SLEROY Christophe (unsigned long)dev);
34189c02e285SLEROY Christophe else
3419dd3c0987SLEROY Christophe tasklet_init(&priv->done_task[0], talitos1_done_4ch,
3420dd3c0987SLEROY Christophe (unsigned long)dev);
3421dd3c0987SLEROY Christophe } else {
34229c02e285SLEROY Christophe if (priv->irq[1]) {
3423dd3c0987SLEROY Christophe tasklet_init(&priv->done_task[0], talitos2_done_ch0_2,
3424dd3c0987SLEROY Christophe (unsigned long)dev);
3425dd3c0987SLEROY Christophe tasklet_init(&priv->done_task[1], talitos2_done_ch1_3,
3426dd3c0987SLEROY Christophe (unsigned long)dev);
34279c02e285SLEROY Christophe } else if (priv->num_channels == 1) {
34289c02e285SLEROY Christophe tasklet_init(&priv->done_task[0], talitos2_done_ch0,
34299c02e285SLEROY Christophe (unsigned long)dev);
34309c02e285SLEROY Christophe } else {
34319c02e285SLEROY Christophe tasklet_init(&priv->done_task[0], talitos2_done_4ch,
34329c02e285SLEROY Christophe (unsigned long)dev);
3433dd3c0987SLEROY Christophe }
3434dd3c0987SLEROY Christophe }
3435dd3c0987SLEROY Christophe
3436a86854d0SKees Cook priv->chan = devm_kcalloc(dev,
3437a86854d0SKees Cook priv->num_channels,
3438a86854d0SKees Cook sizeof(struct talitos_channel),
3439a86854d0SKees Cook GFP_KERNEL);
34404b992628SKim Phillips if (!priv->chan) {
34414b992628SKim Phillips dev_err(dev, "failed to allocate channel management space\n");
34429c4a7965SKim Phillips err = -ENOMEM;
34439c4a7965SKim Phillips goto err_out;
34449c4a7965SKim Phillips }
34459c4a7965SKim Phillips
3446f641ddddSMartin Hicks priv->fifo_len = roundup_pow_of_two(priv->chfifo_len);
3447f641ddddSMartin Hicks
3448c3e337f8SKim Phillips for (i = 0; i < priv->num_channels; i++) {
34495fa7fa14SLEROY Christophe priv->chan[i].reg = priv->reg + stride * (i + 1);
34502cdba3cfSKim Phillips if (!priv->irq[1] || !(i & 1))
3451c3e337f8SKim Phillips priv->chan[i].reg += TALITOS_CH_BASE_OFFSET;
3452ad42d5fcSKim Phillips
34534b992628SKim Phillips spin_lock_init(&priv->chan[i].head_lock);
34544b992628SKim Phillips spin_lock_init(&priv->chan[i].tail_lock);
34559c4a7965SKim Phillips
3456a86854d0SKees Cook priv->chan[i].fifo = devm_kcalloc(dev,
3457a86854d0SKees Cook priv->fifo_len,
3458a86854d0SKees Cook sizeof(struct talitos_request),
3459a86854d0SKees Cook GFP_KERNEL);
34604b992628SKim Phillips if (!priv->chan[i].fifo) {
34619c4a7965SKim Phillips dev_err(dev, "failed to allocate request fifo %d\n", i);
34629c4a7965SKim Phillips err = -ENOMEM;
34639c4a7965SKim Phillips goto err_out;
34649c4a7965SKim Phillips }
34659c4a7965SKim Phillips
34664b992628SKim Phillips atomic_set(&priv->chan[i].submit_count,
34674b992628SKim Phillips -(priv->chfifo_len - 1));
3468f641ddddSMartin Hicks }
34699c4a7965SKim Phillips
347081eb024cSKim Phillips dma_set_mask(dev, DMA_BIT_MASK(36));
347181eb024cSKim Phillips
34729c4a7965SKim Phillips /* reset and initialize the h/w */
34739c4a7965SKim Phillips err = init_device(dev);
34749c4a7965SKim Phillips if (err) {
34759c4a7965SKim Phillips dev_err(dev, "failed to initialize device\n");
34769c4a7965SKim Phillips goto err_out;
34779c4a7965SKim Phillips }
34789c4a7965SKim Phillips
34799c4a7965SKim Phillips /* register the RNG, if available */
34809c4a7965SKim Phillips if (hw_supports(dev, DESC_HDR_SEL0_RNG)) {
34819c4a7965SKim Phillips err = talitos_register_rng(dev);
34829c4a7965SKim Phillips if (err) {
34839c4a7965SKim Phillips dev_err(dev, "failed to register hwrng: %d\n", err);
34849c4a7965SKim Phillips goto err_out;
34859c4a7965SKim Phillips } else
34869c4a7965SKim Phillips dev_info(dev, "hwrng\n");
34879c4a7965SKim Phillips }
34889c4a7965SKim Phillips
34899c4a7965SKim Phillips /* register crypto algorithms the device supports */
34909c4a7965SKim Phillips for (i = 0; i < ARRAY_SIZE(driver_algs); i++) {
34919c4a7965SKim Phillips if (hw_supports(dev, driver_algs[i].desc_hdr_template)) {
34929c4a7965SKim Phillips struct talitos_crypto_alg *t_alg;
3493aeb4c132SHerbert Xu struct crypto_alg *alg = NULL;
34949c4a7965SKim Phillips
34959c4a7965SKim Phillips t_alg = talitos_alg_alloc(dev, &driver_algs[i]);
34969c4a7965SKim Phillips if (IS_ERR(t_alg)) {
34979c4a7965SKim Phillips err = PTR_ERR(t_alg);
34980b2730d8SKim Phillips if (err == -ENOTSUPP)
349979b3a418SLee Nipper continue;
35009c4a7965SKim Phillips goto err_out;
35019c4a7965SKim Phillips }
35029c4a7965SKim Phillips
3503acbf7c62SLee Nipper switch (t_alg->algt.type) {
3504373960d7SArd Biesheuvel case CRYPTO_ALG_TYPE_SKCIPHER:
3505373960d7SArd Biesheuvel err = crypto_register_skcipher(
3506373960d7SArd Biesheuvel &t_alg->algt.alg.skcipher);
3507373960d7SArd Biesheuvel alg = &t_alg->algt.alg.skcipher.base;
3508acbf7c62SLee Nipper break;
3509aeb4c132SHerbert Xu
3510aeb4c132SHerbert Xu case CRYPTO_ALG_TYPE_AEAD:
3511aeb4c132SHerbert Xu err = crypto_register_aead(
3512aeb4c132SHerbert Xu &t_alg->algt.alg.aead);
3513aeb4c132SHerbert Xu alg = &t_alg->algt.alg.aead.base;
3514aeb4c132SHerbert Xu break;
3515aeb4c132SHerbert Xu
3516acbf7c62SLee Nipper case CRYPTO_ALG_TYPE_AHASH:
3517acbf7c62SLee Nipper err = crypto_register_ahash(
3518acbf7c62SLee Nipper &t_alg->algt.alg.hash);
3519aeb4c132SHerbert Xu alg = &t_alg->algt.alg.hash.halg.base;
3520acbf7c62SLee Nipper break;
3521acbf7c62SLee Nipper }
35229c4a7965SKim Phillips if (err) {
35239c4a7965SKim Phillips dev_err(dev, "%s alg registration failed\n",
3524aeb4c132SHerbert Xu alg->cra_driver_name);
352524b92ff2SLEROY Christophe devm_kfree(dev, t_alg);
3526991155baSHoria Geanta } else
35279c4a7965SKim Phillips list_add_tail(&t_alg->entry, &priv->alg_list);
35289c4a7965SKim Phillips }
35299c4a7965SKim Phillips }
35305b859b6eSKim Phillips if (!list_empty(&priv->alg_list))
35315b859b6eSKim Phillips dev_info(dev, "%s algorithms registered in /proc/crypto\n",
35325b859b6eSKim Phillips (char *)of_get_property(np, "compatible", NULL));
35339c4a7965SKim Phillips
35349c4a7965SKim Phillips return 0;
35359c4a7965SKim Phillips
35369c4a7965SKim Phillips err_out:
35379c4a7965SKim Phillips talitos_remove(ofdev);
35389c4a7965SKim Phillips
35399c4a7965SKim Phillips return err;
35409c4a7965SKim Phillips }
35419c4a7965SKim Phillips
35426c3f975aSMárton Németh static const struct of_device_id talitos_match[] = {
35430635b7dbSLEROY Christophe #ifdef CONFIG_CRYPTO_DEV_TALITOS1
35440635b7dbSLEROY Christophe {
35450635b7dbSLEROY Christophe .compatible = "fsl,sec1.0",
35460635b7dbSLEROY Christophe },
35470635b7dbSLEROY Christophe #endif
35480635b7dbSLEROY Christophe #ifdef CONFIG_CRYPTO_DEV_TALITOS2
35499c4a7965SKim Phillips {
35509c4a7965SKim Phillips .compatible = "fsl,sec2.0",
35519c4a7965SKim Phillips },
35520635b7dbSLEROY Christophe #endif
35539c4a7965SKim Phillips {},
35549c4a7965SKim Phillips };
35559c4a7965SKim Phillips MODULE_DEVICE_TABLE(of, talitos_match);
35569c4a7965SKim Phillips
35571c48a5c9SGrant Likely static struct platform_driver talitos_driver = {
35584018294bSGrant Likely .driver = {
35599c4a7965SKim Phillips .name = "talitos",
35604018294bSGrant Likely .of_match_table = talitos_match,
35614018294bSGrant Likely },
35629c4a7965SKim Phillips .probe = talitos_probe,
3563ce52705eSUwe Kleine-König .remove_new = talitos_remove,
35649c4a7965SKim Phillips };
35659c4a7965SKim Phillips
3566741e8c2dSAxel Lin module_platform_driver(talitos_driver);
35679c4a7965SKim Phillips
35689c4a7965SKim Phillips MODULE_LICENSE("GPL");
35699c4a7965SKim Phillips MODULE_AUTHOR("Kim Phillips <kim.phillips@freescale.com>");
35709c4a7965SKim Phillips MODULE_DESCRIPTION("Freescale integrated security engine (SEC) driver");
3571