From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753579AbaGKMcZ (ORCPT ); Fri, 11 Jul 2014 08:32:25 -0400 Received: from pegase1.c-s.fr ([93.17.236.30]:49987 "EHLO mailhub1.si.c-s.fr" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751493AbaGKMcF (ORCPT ); Fri, 11 Jul 2014 08:32:05 -0400 X-Greylist: delayed 1341 seconds by postgrey-1.27 at vger.kernel.org; Fri, 11 Jul 2014 08:32:04 EDT From: Christophe Leroy To: Kim Phillips , Herbert Xu , "David S. Miller" , Benjamin Herrenschmidt , Paul Mackerras CC: linux-kernel@vger.kernel.org, linuxppc-dev@lists.ozlabs.org, Joakim Tjernlund , linux-crypto@vger.kernel.org Subject: [RFC, prePATCH] crypto: talitos modified for powerpc 88x security engine Message-Id: <20140711120939.DD0031A9740@localhost.localdomain> Date: Fri, 11 Jul 2014 14:09:39 +0200 (CEST) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Here is a pre-patch for the support of the SEC ENGINE of MPC88x/MPC82xx I have tried to make use of defines in order to keep a single driver for the two TALITOS variants as suggested by Kim, but I'm not too happy about the quantity of #ifdef For the time being, it only supports basic crypto operations, not the combined authentication/encryption ones. Note that it has been tested on MPC885, but not on MPC82xx I would be happy to receive comments and suggestions in order to improve this first try. Not-yet-signed-off-by: Christophe Leroy Index: b/drivers/crypto/talitos.c =================================================================== --- a/drivers/crypto/talitos.c +++ b/drivers/crypto/talitos.c @@ -53,10 +53,26 @@ #include "talitos.h" +#ifdef CONFIG_CRYPTO_DEV_TALITOS1 +static u8 padded_hash[64] = { 0x80, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, +}; +#endif + static void to_talitos_ptr(struct talitos_ptr *talitos_ptr, dma_addr_t dma_addr) { talitos_ptr->ptr = cpu_to_be32(lower_32_bits(dma_addr)); +#ifdef CONFIG_CRYPTO_DEV_TALITOS1 + talitos_ptr->res = 0; +#else talitos_ptr->eptr = upper_32_bits(dma_addr); +#endif } /* @@ -72,7 +88,11 @@ talitos_ptr->len = cpu_to_be16(len); to_talitos_ptr(talitos_ptr, dma_addr); +#ifdef CONFIG_CRYPTO_DEV_TALITOS1 + talitos_ptr->res = 0; +#else talitos_ptr->j_extent = extent; +#endif } /* @@ -91,9 +111,17 @@ struct talitos_private *priv = dev_get_drvdata(dev); unsigned int timeout = TALITOS_TIMEOUT; +#ifdef CONFIG_CRYPTO_DEV_TALITOS1 + setbits32(priv->chan[ch].reg + TALITOS_CCCR_LO, TALITOS_CCCR_LO_RESET); +#else setbits32(priv->chan[ch].reg + TALITOS_CCCR, TALITOS_CCCR_RESET); +#endif +#ifdef CONFIG_CRYPTO_DEV_TALITOS1 + while ((in_be32(priv->chan[ch].reg + TALITOS_CCCR_LO) & TALITOS_CCCR_LO_RESET) +#else while ((in_be32(priv->chan[ch].reg + TALITOS_CCCR) & TALITOS_CCCR_RESET) +#endif && --timeout) cpu_relax(); @@ -101,10 +129,11 @@ dev_err(dev, "failed to reset channel %d\n", ch); return -EIO; } +dev_err(dev, "success to reset channel %d\n", ch); /* set 36-bit addressing, done writeback enable and done IRQ enable */ setbits32(priv->chan[ch].reg + TALITOS_CCCR_LO, TALITOS_CCCR_LO_EAE | - TALITOS_CCCR_LO_CDWE | TALITOS_CCCR_LO_CDIE); + TALITOS_CCCR_LO_CDWE | TALITOS_CCCR_LO_CDIE /*| TALITOS_CCCR_LO_NT*/); /* and ICCR writeback, if available */ if (priv->features & TALITOS_FTR_HW_AUTH_CHECK) @@ -169,8 +198,15 @@ } /* enable channel done and error interrupts */ +#ifdef CONFIG_CRYPTO_DEV_TALITOS1 + clrbits32(priv->reg + TALITOS_IMR, TALITOS_IMR_INIT); + clrbits32(priv->reg + TALITOS_IMR_LO, TALITOS_IMR_LO_INIT); + /* disable parity error check in DEU because of erroneous? test vectors */ + setbits32(priv->reg + TALITOS_DEUICR, TALITOS_DEUICR_KPE); +#else setbits32(priv->reg + TALITOS_IMR, TALITOS_IMR_INIT); setbits32(priv->reg + TALITOS_IMR_LO, TALITOS_IMR_LO_INIT); +#endif /* disable integrity check error interrupts (use writeback instead) */ if (priv->features & TALITOS_FTR_HW_AUTH_CHECK) @@ -228,6 +264,7 @@ /* GO! */ wmb(); + out_be32(priv->chan[ch].reg + TALITOS_FF, upper_32_bits(request->dma_desc)); out_be32(priv->chan[ch].reg + TALITOS_FF_LO, @@ -300,6 +337,7 @@ /* * process completed requests for channels that have done status */ +#ifdef CONFIG_CRYPTO_DEV_TALITOS1 #define DEF_TALITOS_DONE(name, ch_done_mask) \ static void talitos_done_##name(unsigned long data) \ { \ @@ -307,6 +345,33 @@ struct talitos_private *priv = dev_get_drvdata(dev); \ unsigned long flags; \ \ + if (ch_done_mask & 0x10000000) \ + flush_channel(dev, 0, 0, 0); \ + if (priv->num_channels == 1) \ + goto out; \ + if (ch_done_mask & 0x40000000) \ + flush_channel(dev, 1, 0, 0); \ + if (ch_done_mask & 0x00010000) \ + flush_channel(dev, 2, 0, 0); \ + if (ch_done_mask & 0x00040000) \ + flush_channel(dev, 3, 0, 0); \ + \ +out: \ + /* At this point, all completed channels have been processed */ \ + /* Unmask done interrupts for channels completed later on. */ \ + spin_lock_irqsave(&priv->reg_lock, flags); \ + clrbits32(priv->reg + TALITOS_IMR, ch_done_mask); \ + clrbits32(priv->reg + TALITOS_IMR_LO, TALITOS_IMR_LO_INIT); \ + spin_unlock_irqrestore(&priv->reg_lock, flags); \ +} +#else +#define DEF_TALITOS_DONE(name, ch_done_mask) \ +static void talitos_done_##name(unsigned long data) \ +{ \ + struct device *dev = (struct device *)data; \ + struct talitos_private *priv = dev_get_drvdata(dev); \ + unsigned long flags; \ + \ if (ch_done_mask & 1) \ flush_channel(dev, 0, 0, 0); \ if (priv->num_channels == 1) \ @@ -326,6 +391,7 @@ setbits32(priv->reg + TALITOS_IMR_LO, TALITOS_IMR_LO_INIT); \ spin_unlock_irqrestore(&priv->reg_lock, flags); \ } +#endif DEF_TALITOS_DONE(4ch, TALITOS_ISR_4CHDONE) DEF_TALITOS_DONE(ch0_2, TALITOS_ISR_CH_0_2_DONE) DEF_TALITOS_DONE(ch1_3, TALITOS_ISR_CH_1_3_DONE) @@ -433,13 +499,24 @@ static void talitos_error(struct device *dev, u32 isr, u32 isr_lo) { struct talitos_private *priv = dev_get_drvdata(dev); +#ifndef CONFIG_CRYPTO_DEV_TALITOS1 unsigned int timeout = TALITOS_TIMEOUT; +#endif int ch, error, reset_dev = 0, reset_ch = 0; u32 v, v_lo; +#ifdef CONFIG_CRYPTO_DEV_TALITOS1 + reset_ch = 1; +#endif for (ch = 0; ch < priv->num_channels; ch++) { /* skip channels without errors */ + +#ifdef CONFIG_CRYPTO_DEV_TALITOS1 + /* 29 , 31, 17, 19 */ + if (!(isr & (1 << (29 + (ch & 1) * 2 - (ch & 2) * 6)))) +#else if (!(isr & (1 << (ch * 2 + 1)))) +#endif continue; error = -EINVAL; @@ -447,6 +524,14 @@ v = in_be32(priv->chan[ch].reg + TALITOS_CCPSR); v_lo = in_be32(priv->chan[ch].reg + TALITOS_CCPSR_LO); +#ifdef CONFIG_CRYPTO_DEV_TALITOS1 + if (v_lo & TALITOS_CCPSR_LO_TEA) + dev_err(dev, "master data transfer error\n"); + if (v_lo & TALITOS_CCPSR_LO_PNC) + dev_err(dev, "pointeur not complete error\n"); + if (v_lo & TALITOS_CCPSR_LO_PAR) + dev_err(dev, "parity error\n"); +#else if (v_lo & TALITOS_CCPSR_LO_DOF) { dev_err(dev, "double fetch fifo overflow error\n"); error = -EAGAIN; @@ -463,12 +548,19 @@ dev_err(dev, "s/g data length zero error\n"); if (v_lo & TALITOS_CCPSR_LO_FPZ) dev_err(dev, "fetch pointer zero error\n"); +#endif if (v_lo & TALITOS_CCPSR_LO_IDH) dev_err(dev, "illegal descriptor header error\n"); +#ifdef CONFIG_CRYPTO_DEV_TALITOS1 + if (v_lo & TALITOS_CCPSR_LO_SA) + dev_err(dev, "static assignment error\n"); +#else if (v_lo & TALITOS_CCPSR_LO_IEU) dev_err(dev, "invalid execution unit error\n"); +#endif if (v_lo & TALITOS_CCPSR_LO_EU) report_eu_error(dev, ch, current_desc_hdr(dev, ch)); +#ifndef CONFIG_CRYPTO_DEV_TALITOS1 if (v_lo & TALITOS_CCPSR_LO_GB) dev_err(dev, "gather boundary error\n"); if (v_lo & TALITOS_CCPSR_LO_GRL) @@ -477,9 +569,13 @@ dev_err(dev, "scatter boundary error\n"); if (v_lo & TALITOS_CCPSR_LO_SRL) dev_err(dev, "scatter return/length error\n"); +#endif flush_channel(dev, ch, error, reset_ch); +#ifdef CONFIG_CRYPTO_DEV_TALITOS1 + reset_channel(dev, ch); +#else if (reset_ch) { reset_channel(dev, ch); } else { @@ -495,10 +591,17 @@ reset_dev = 1; } } +#endif } if (reset_dev || isr & ~TALITOS_ISR_4CHERR || isr_lo) { - dev_err(dev, "done overflow, internal time out, or rngu error: " +#ifdef CONFIG_CRYPTO_DEV_TALITOS1 + if (isr_lo & TALITOS_ISR_TEA_ERR) + dev_err(dev, "TEA error: " "ISR 0x%08x_%08x\n", isr, isr_lo); + else +#endif + dev_err(dev, "done overflow, internal time out, or rngu error: " + "ISR 0x%08x_%08x\n", isr, isr_lo); /* purge request queues */ for (ch = 0; ch < priv->num_channels; ch++) @@ -509,6 +612,7 @@ } } +#ifdef CONFIG_CRYPTO_DEV_TALITOS1 #define DEF_TALITOS_INTERRUPT(name, ch_done_mask, ch_err_mask, tlet) \ static irqreturn_t talitos_interrupt_##name(int irq, void *data) \ { \ @@ -523,7 +627,39 @@ /* Acknowledge interrupt */ \ out_be32(priv->reg + TALITOS_ICR, isr & (ch_done_mask | ch_err_mask)); \ out_be32(priv->reg + TALITOS_ICR_LO, isr_lo); \ + if (unlikely(isr & ch_err_mask || isr_lo & TALITOS_IMR_LO_INIT)) { \ + spin_unlock_irqrestore(&priv->reg_lock, flags); \ + talitos_error(dev, isr & ch_err_mask, isr_lo); \ + } \ + else { \ + if (likely(isr & ch_done_mask)) { \ + /* mask further done interrupts. */ \ + setbits32(priv->reg + TALITOS_IMR, ch_done_mask); \ + /* done_task will unmask done interrupts at exit */ \ + tasklet_schedule(&priv->done_task[tlet]); \ + } \ + spin_unlock_irqrestore(&priv->reg_lock, flags); \ + } \ \ + return (isr & (ch_done_mask | ch_err_mask) || isr_lo) ? IRQ_HANDLED : \ + IRQ_NONE; \ +} +#else +#define DEF_TALITOS_INTERRUPT(name, ch_done_mask, ch_err_mask, tlet) \ +static irqreturn_t talitos_interrupt_##name(int irq, void *data) \ +{ \ + struct device *dev = data; \ + struct talitos_private *priv = dev_get_drvdata(dev); \ + u32 isr, isr_lo; \ + unsigned long flags; \ + \ + spin_lock_irqsave(&priv->reg_lock, flags); \ + isr = in_be32(priv->reg + TALITOS_ISR); \ + isr_lo = in_be32(priv->reg + TALITOS_ISR_LO); \ + /* Acknowledge interrupt */ \ + out_be32(priv->reg + TALITOS_ICR, isr & (ch_done_mask | ch_err_mask)); \ + out_be32(priv->reg + TALITOS_ICR_LO, isr_lo); \ + \ if (unlikely(isr & ch_err_mask || isr_lo)) { \ spin_unlock_irqrestore(&priv->reg_lock, flags); \ talitos_error(dev, isr & ch_err_mask, isr_lo); \ @@ -541,6 +677,7 @@ return (isr & (ch_done_mask | ch_err_mask) || isr_lo) ? IRQ_HANDLED : \ IRQ_NONE; \ } +#endif DEF_TALITOS_INTERRUPT(4ch, TALITOS_ISR_4CHDONE, TALITOS_ISR_4CHERR, 0) DEF_TALITOS_INTERRUPT(ch0_2, TALITOS_ISR_CH_0_2_DONE, TALITOS_ISR_CH_0_2_ERR, 0) DEF_TALITOS_INTERRUPT(ch1_3, TALITOS_ISR_CH_1_3_DONE, TALITOS_ISR_CH_1_3_ERR, 1) @@ -638,6 +775,10 @@ unsigned int enckeylen; unsigned int authkeylen; unsigned int authsize; +#ifdef CONFIG_CRYPTO_DEV_TALITOS1 + u8 *ptr_in; + u8 *ptr_out; +#endif }; #define HASH_MAX_BLOCK_SIZE SHA512_BLOCK_SIZE @@ -646,7 +787,7 @@ struct talitos_ahash_req_ctx { u32 hw_context[TALITOS_MDEU_MAX_CONTEXT_SIZE / sizeof(u32)]; unsigned int hw_context_size; - u8 buf[HASH_MAX_BLOCK_SIZE]; + u8 buf[4096]; u8 bufnext[HASH_MAX_BLOCK_SIZE]; unsigned int swinit; unsigned int first; @@ -657,6 +798,7 @@ struct scatterlist *psrc; }; +#ifndef CONFIG_CRYPTO_DEV_TALITOS1 static int aead_setauthsize(struct crypto_aead *authenc, unsigned int authsize) { @@ -711,6 +853,7 @@ crypto_aead_set_flags(authenc, CRYPTO_TFM_RES_BAD_KEY_LEN); return -EINVAL; } +#endif /* * talitos_edesc - s/w-extended descriptor @@ -796,6 +939,7 @@ dma_unmap_sg(dev, src, src_nents, DMA_BIDIRECTIONAL); } +#ifndef CONFIG_CRYPTO_DEV_TALITOS1 static void ipsec_esp_unmap(struct device *dev, struct talitos_edesc *edesc, struct aead_request *areq) @@ -1091,6 +1235,7 @@ } return ret; } +#endif /* * derive number of elements in scatterlist @@ -1213,6 +1358,7 @@ return edesc; } +#ifndef CONFIG_CRYPTO_DEV_TALITOS1 static struct talitos_edesc *aead_edesc_alloc(struct aead_request *areq, u8 *iv, int icv_stashing) { @@ -1315,6 +1461,7 @@ return ipsec_esp(edesc, areq, req->seq, ipsec_esp_encrypt_done); } +#endif static int ablkcipher_setkey(struct crypto_ablkcipher *cipher, const u8 *key, unsigned int keylen) @@ -1331,7 +1478,21 @@ struct talitos_edesc *edesc, struct ablkcipher_request *areq) { + struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(areq); + struct talitos_ctx *ctx = crypto_ablkcipher_ctx(cipher); + unmap_single_talitos_ptr(dev, &edesc->desc.ptr[5], DMA_FROM_DEVICE); + if (ctx->ptr_out) { + unsigned int cryptlen = areq->nbytes; + + sg_copy_from_buffer(areq->dst, edesc->dst_nents ? : 1, ctx->ptr_out, cryptlen); + unmap_single_talitos_ptr(dev, &edesc->desc.ptr[4], DMA_FROM_DEVICE); + kfree(ctx->ptr_out); + } + if (ctx->ptr_in) { + unmap_single_talitos_ptr(dev, &edesc->desc.ptr[3], DMA_TO_DEVICE); + kfree(ctx->ptr_in); + } unmap_single_talitos_ptr(dev, &edesc->desc.ptr[2], DMA_TO_DEVICE); unmap_single_talitos_ptr(dev, &edesc->desc.ptr[1], DMA_TO_DEVICE); @@ -1375,13 +1536,16 @@ /* first DWORD empty */ desc->ptr[0].len = 0; to_talitos_ptr(&desc->ptr[0], 0); +#ifndef CONFIG_CRYPTO_DEV_TALITOS1 desc->ptr[0].j_extent = 0; +#endif /* cipher iv */ to_talitos_ptr(&desc->ptr[1], edesc->iv_dma); desc->ptr[1].len = cpu_to_be16(ivsize); +#ifndef CONFIG_CRYPTO_DEV_TALITOS1 desc->ptr[1].j_extent = 0; - +#endif /* cipher key */ map_single_talitos_ptr(dev, &desc->ptr[2], ctx->keylen, (char *)&ctx->key, 0, DMA_TO_DEVICE); @@ -1390,7 +1554,9 @@ * cipher in */ desc->ptr[3].len = cpu_to_be16(cryptlen); +#ifndef CONFIG_CRYPTO_DEV_TALITOS1 desc->ptr[3].j_extent = 0; +#endif sg_count = talitos_map_sg(dev, areq->src, edesc->src_nents ? : 1, (areq->src == areq->dst) ? DMA_BIDIRECTIONAL @@ -1398,8 +1564,17 @@ edesc->src_chained); if (sg_count == 1) { +#ifdef CONFIG_CRYPTO_DEV_TALITOS1 + ctx->ptr_in = NULL; +#endif to_talitos_ptr(&desc->ptr[3], sg_dma_address(areq->src)); } else { +#ifdef CONFIG_CRYPTO_DEV_TALITOS1 + ctx->ptr_in = kzalloc(cryptlen, GFP_DMA); + sg_copy_to_buffer(areq->src, sg_count, ctx->ptr_in, cryptlen); + map_single_talitos_ptr(dev, &desc->ptr[3], cryptlen, + (char *)ctx->ptr_in, 0, DMA_TO_DEVICE); +#else sg_count = sg_to_link_tbl(areq->src, sg_count, cryptlen, &edesc->link_tbl[0]); if (sg_count > 1) { @@ -1412,12 +1587,17 @@ /* Only one segment now, so no link tbl needed */ to_talitos_ptr(&desc->ptr[3], sg_dma_address(areq->src)); +#endif +#ifndef CONFIG_CRYPTO_DEV_TALITOS1 } +#endif } /* cipher out */ desc->ptr[4].len = cpu_to_be16(cryptlen); +#ifndef CONFIG_CRYPTO_DEV_TALITOS1 desc->ptr[4].j_extent = 0; +#endif if (areq->src != areq->dst) sg_count = talitos_map_sg(dev, areq->dst, @@ -1425,8 +1605,16 @@ DMA_FROM_DEVICE, edesc->dst_chained); if (sg_count == 1) { +#ifdef CONFIG_CRYPTO_DEV_TALITOS1 + ctx->ptr_out = NULL; +#endif to_talitos_ptr(&desc->ptr[4], sg_dma_address(areq->dst)); } else { +#ifdef CONFIG_CRYPTO_DEV_TALITOS1 + ctx->ptr_out = kzalloc(cryptlen, GFP_DMA); + map_single_talitos_ptr(dev, &desc->ptr[4], cryptlen, + (char *)ctx->ptr_out, 0, DMA_FROM_DEVICE); +#else struct talitos_ptr *link_tbl_ptr = &edesc->link_tbl[edesc->src_nents + 1]; @@ -1438,6 +1626,7 @@ link_tbl_ptr); dma_sync_single_for_device(ctx->dev, edesc->dma_link_tbl, edesc->dma_len, DMA_BIDIRECTIONAL); +#endif } /* iv out */ @@ -1447,7 +1636,12 @@ /* last DWORD empty */ desc->ptr[6].len = 0; to_talitos_ptr(&desc->ptr[6], 0); +#ifndef CONFIG_CRYPTO_DEV_TALITOS1 desc->ptr[6].j_extent = 0; +#endif +#ifdef CONFIG_CRYPTO_DEV_TALITOS1 + desc->next_desc = 0; +#endif ret = talitos_submit(dev, ctx->ch, desc, callback, areq); if (ret != -EINPROGRESS) { @@ -1578,9 +1772,10 @@ } /* HMAC key */ - if (ctx->keylen) + if (ctx->keylen) { map_single_talitos_ptr(dev, &desc->ptr[2], ctx->keylen, (char *)&ctx->key, 0, DMA_TO_DEVICE); + } else desc->ptr[2] = zero_entry; @@ -1588,7 +1783,9 @@ * data in */ desc->ptr[3].len = cpu_to_be16(length); +#ifndef CONFIG_CRYPTO_DEV_TALITOS1 desc->ptr[3].j_extent = 0; +#endif sg_count = talitos_map_sg(dev, req_ctx->psrc, edesc->src_nents ? : 1, @@ -1597,6 +1794,7 @@ if (sg_count == 1) { to_talitos_ptr(&desc->ptr[3], sg_dma_address(req_ctx->psrc)); } else { +#ifndef CONFIG_CRYPTO_DEV_TALITOS1 sg_count = sg_to_link_tbl(req_ctx->psrc, sg_count, length, &edesc->link_tbl[0]); if (sg_count > 1) { @@ -1611,6 +1809,7 @@ to_talitos_ptr(&desc->ptr[3], sg_dma_address(req_ctx->psrc)); } +#endif } /* fifth DWORD empty */ @@ -1628,7 +1827,22 @@ /* last DWORD empty */ desc->ptr[6] = zero_entry; +#ifdef CONFIG_CRYPTO_DEV_TALITOS1 + desc->next_desc = 0; +#endif +#ifdef CONFIG_CRYPTO_DEV_TALITOS1 + /* + * SEC1 doesn't like hashing of 0 sized message, so we do the padding + * ourself and submit a padded block + */ + if (desc->ptr[3].len == 0) { + pr_err_once("Bug in SEC1, padding ourself\n"); + edesc->desc.hdr &= ~DESC_HDR_MODE0_MDEU_PAD; + map_single_talitos_ptr(dev, &desc->ptr[3], sizeof(padded_hash), + (char *)padded_hash, 0, DMA_TO_DEVICE); + } +#endif ret = talitos_submit(dev, ctx->ch, desc, callback, areq); if (ret != -EINPROGRESS) { common_nonsnoop_hash_unmap(dev, edesc, areq); @@ -1702,7 +1916,10 @@ crypto_tfm_alg_blocksize(crypto_ahash_tfm(tfm)); unsigned int nbytes_to_hash; unsigned int to_hash_later; +#ifndef CONFIG_CRYPTO_DEV_TALITOS1 unsigned int nsg; +#endif + int nents; bool chained; if (!req_ctx->last && (nbytes + req_ctx->nbuf <= blocksize)) { @@ -1730,6 +1947,16 @@ } /* Chain in any previously buffered data */ +#ifdef CONFIG_CRYPTO_DEV_TALITOS1 + if ((nents = sg_count(areq->src, nbytes, &chained)) > 1 || req_ctx->nbuf) { + sg_copy_to_buffer(areq->src, nents, + req_ctx->buf + req_ctx->nbuf, + nbytes_to_hash - req_ctx->nbuf); + sg_init_one(req_ctx->bufsl, req_ctx->buf, nbytes_to_hash); + req_ctx->psrc = req_ctx->bufsl; + } else + req_ctx->psrc = areq->src; +#else if (req_ctx->nbuf) { nsg = (req_ctx->nbuf < nbytes_to_hash) ? 2 : 1; sg_init_table(req_ctx->bufsl, nsg); @@ -1739,9 +1966,9 @@ req_ctx->psrc = req_ctx->bufsl; } else req_ctx->psrc = areq->src; - +#endif if (to_hash_later) { - int nents = sg_count(areq->src, nbytes, &chained); + nents = sg_count(areq->src, nbytes, &chained); sg_pcopy_to_buffer(areq->src, nents, req_ctx->bufnext, to_hash_later, @@ -2407,6 +2634,7 @@ return 0; } +#ifndef CONFIG_CRYPTO_DEV_TALITOS1 static int talitos_cra_init_aead(struct crypto_tfm *tfm) { struct talitos_ctx *ctx = crypto_tfm_ctx(tfm); @@ -2418,6 +2646,7 @@ return 0; } +#endif static int talitos_cra_init_ahash(struct crypto_tfm *tfm) { @@ -2524,6 +2753,7 @@ alg->cra_ablkcipher.decrypt = ablkcipher_decrypt; alg->cra_ablkcipher.geniv = "eseqiv"; break; +#ifndef CONFIG_CRYPTO_DEV_TALITOS1 case CRYPTO_ALG_TYPE_AEAD: alg = &t_alg->algt.alg.crypto; alg->cra_init = talitos_cra_init_aead; @@ -2535,6 +2765,7 @@ alg->cra_aead.givencrypt = aead_givencrypt; alg->cra_aead.geniv = ""; break; +#endif case CRYPTO_ALG_TYPE_AHASH: alg = &t_alg->algt.alg.hash.halg.base; alg->cra_init = talitos_cra_init_ahash; @@ -2698,6 +2929,9 @@ TALITOS_FTR_SHA224_HWINIT | TALITOS_FTR_HMAC_OK; + if (of_device_is_compatible(np, "fsl,sec1.2")) + priv->features |= TALITOS_FTR_HMAC_OK; + priv->chan = kzalloc(sizeof(struct talitos_channel) * priv->num_channels, GFP_KERNEL); if (!priv->chan) { @@ -2801,9 +3035,15 @@ } static const struct of_device_id talitos_match[] = { +#ifdef CONFIG_CRYPTO_DEV_TALITOS1 { + .compatible = "fsl,sec1.0", + }, +#else + { .compatible = "fsl,sec2.0", }, +#endif {}, }; MODULE_DEVICE_TABLE(of, talitos_match); Index: b/drivers/crypto/talitos.h =================================================================== --- a/drivers/crypto/talitos.h +++ b/drivers/crypto/talitos.h @@ -28,8 +28,16 @@ * */ +#if defined(CONFIG_PPC_8xx) || defined(CONFIG_PPC_82xx) +#define CONFIG_CRYPTO_DEV_TALITOS1 +#endif + #define TALITOS_TIMEOUT 100000 +#ifdef CONFIG_CRYPTO_DEV_TALITOS1 +#define TALITOS_MAX_DATA_LEN 32768 +#else #define TALITOS_MAX_DATA_LEN 65535 +#endif #define DESC_TYPE(desc_hdr) ((be32_to_cpu(desc_hdr) >> 3) & 0x1f) #define PRIMARY_EU(desc_hdr) ((be32_to_cpu(desc_hdr) >> 28) & 0xf) @@ -37,24 +45,39 @@ /* descriptor pointer entry */ struct talitos_ptr { +#ifdef CONFIG_CRYPTO_DEV_TALITOS1 + __be16 res; /* reserved */ __be16 len; /* length */ + __be32 ptr; /* address */ +#else + __be16 len; /* length */ u8 j_extent; /* jump to sg link table and/or extent */ u8 eptr; /* extended address */ __be32 ptr; /* address */ +#endif }; static const struct talitos_ptr zero_entry = { .len = 0, +#ifdef CONFIG_CRYPTO_DEV_TALITOS1 + .res = 0, +#else .j_extent = 0, .eptr = 0, +#endif .ptr = 0 }; /* descriptor */ struct talitos_desc { __be32 hdr; /* header high bits */ +#ifndef CONFIG_CRYPTO_DEV_TALITOS1 __be32 hdr_lo; /* header low bits */ +#endif struct talitos_ptr ptr[7]; /* ptr/len pair array */ +#ifdef CONFIG_CRYPTO_DEV_TALITOS1 + __be32 next_desc; +#endif }; /** @@ -155,42 +178,84 @@ #define TALITOS_MCR_RCA1 (1 << 14) /* remap channel 1 */ #define TALITOS_MCR_RCA2 (1 << 13) /* remap channel 2 */ #define TALITOS_MCR_RCA3 (1 << 12) /* remap channel 3 */ +#ifdef CONFIG_CRYPTO_DEV_TALITOS1 +#define TALITOS_MCR_SWR 0x01000000 /* s/w reset */ +#else #define TALITOS_MCR_SWR 0x1 /* s/w reset */ +#endif #define TALITOS_MCR_LO 0x1034 #define TALITOS_IMR 0x1008 /* interrupt mask register */ +#ifdef CONFIG_CRYPTO_DEV_TALITOS1 +#define TALITOS_IMR_INIT 0xf00f0000 /* enable channel IRQs */ +#define TALITOS_IMR_DONE 0x50050000 /* done IRQs */ +#else #define TALITOS_IMR_INIT 0x100ff /* enable channel IRQs */ #define TALITOS_IMR_DONE 0x00055 /* done IRQs */ +#endif #define TALITOS_IMR_LO 0x100C +#ifdef CONFIG_CRYPTO_DEV_TALITOS1 +#define TALITOS_IMR_LO_INIT 0x2000000 /* allow RNGU error IRQs */ +#else #define TALITOS_IMR_LO_INIT 0x20000 /* allow RNGU error IRQs */ +#endif #define TALITOS_ISR 0x1010 /* interrupt status register */ +#ifdef CONFIG_CRYPTO_DEV_TALITOS1 +#define TALITOS_ISR_4CHERR 0xa00a0000 /* 4 channel errors mask */ +#define TALITOS_ISR_4CHDONE 0x50050000 /* 4 channel done mask */ +#define TALITOS_ISR_CH_0_2_ERR 0x20020000 /* channels 0, 2 errors mask */ +#define TALITOS_ISR_CH_0_2_DONE 0x10010000 /* channels 0, 2 done mask */ +#define TALITOS_ISR_CH_1_3_ERR 0x80080000 /* channels 1, 3 errors mask */ +#define TALITOS_ISR_CH_1_3_DONE 0x40040000 /* channels 1, 3 done mask */ +#define TALITOS_ISR_TEA_ERR 0x00000040 +#else #define TALITOS_ISR_4CHERR 0xaa /* 4 channel errors mask */ #define TALITOS_ISR_4CHDONE 0x55 /* 4 channel done mask */ #define TALITOS_ISR_CH_0_2_ERR 0x22 /* channels 0, 2 errors mask */ #define TALITOS_ISR_CH_0_2_DONE 0x11 /* channels 0, 2 done mask */ #define TALITOS_ISR_CH_1_3_ERR 0x88 /* channels 1, 3 errors mask */ #define TALITOS_ISR_CH_1_3_DONE 0x44 /* channels 1, 3 done mask */ +#endif #define TALITOS_ISR_LO 0x1014 #define TALITOS_ICR 0x1018 /* interrupt clear register */ #define TALITOS_ICR_LO 0x101C /* channel register address stride */ +#ifdef CONFIG_CRYPTO_DEV_TALITOS1 #define TALITOS_CH_BASE_OFFSET 0x1000 /* default channel map base */ +#define TALITOS_CH_STRIDE 0x1000 +#else +#define TALITOS_CH_BASE_OFFSET 0x1000 /* default channel map base */ #define TALITOS_CH_STRIDE 0x100 +#endif /* channel configuration register */ #define TALITOS_CCCR 0x8 +#ifdef CONFIG_CRYPTO_DEV_TALITOS1 +#else #define TALITOS_CCCR_CONT 0x2 /* channel continue */ #define TALITOS_CCCR_RESET 0x1 /* channel reset */ +#endif #define TALITOS_CCCR_LO 0xc #define TALITOS_CCCR_LO_IWSE 0x80 /* chan. ICCR writeback enab. */ #define TALITOS_CCCR_LO_EAE 0x20 /* extended address enable */ #define TALITOS_CCCR_LO_CDWE 0x10 /* chan. done writeback enab. */ #define TALITOS_CCCR_LO_NT 0x4 /* notification type */ #define TALITOS_CCCR_LO_CDIE 0x2 /* channel done IRQ enable */ +#ifdef CONFIG_CRYPTO_DEV_TALITOS1 +#define TALITOS_CCCR_LO_RESET 0x1 /* channel reset */ +#endif /* CCPSR: channel pointer status register */ #define TALITOS_CCPSR 0x10 #define TALITOS_CCPSR_LO 0x14 +#ifdef CONFIG_CRYPTO_DEV_TALITOS1 +#define TALITOS_CCPSR_LO_TEA 0x2000 /* master data transfer error */ +#define TALITOS_CCPSR_LO_PNC 0x1000 /* pointeur not complete error */ +#define TALITOS_CCPSR_LO_PAR 0x0800 /* parity error */ +#define TALITOS_CCPSR_LO_IDH 0x0400 /* illegal desc hdr error */ +#define TALITOS_CCPSR_LO_SA 0x0200 /* static assignment error */ +#define TALITOS_CCPSR_LO_EU 0x0100 /* EU error detected */ +#else #define TALITOS_CCPSR_LO_DOF 0x8000 /* double FF write oflow error */ #define TALITOS_CCPSR_LO_SOF 0x4000 /* single FF write oflow error */ #define TALITOS_CCPSR_LO_MDTE 0x2000 /* master data transfer error */ @@ -203,6 +268,7 @@ #define TALITOS_CCPSR_LO_GRL 0x0040 /* gather return/length error */ #define TALITOS_CCPSR_LO_SB 0x0020 /* scatter boundary error */ #define TALITOS_CCPSR_LO_SRL 0x0010 /* scatter return/length error */ +#endif /* channel fetch fifo register */ #define TALITOS_FF 0x48 @@ -225,8 +291,16 @@ #define TALITOS_SCATTER_LO 0xe4 /* execution unit interrupt status registers */ +#ifdef CONFIG_CRYPTO_DEV_TALITOS1 +#define TALITOS_DEUISR 0x5030 /* DES unit */ +#define TALITOS_DEUISR_LO 0x5034 +#define TALITOS_DEUICR 0x5038 /* interrupt control */ +#define TALITOS_DEUICR_KPE 0x00200000 /* Key Parity Error */ +#else #define TALITOS_DEUISR 0x2030 /* DES unit */ #define TALITOS_DEUISR_LO 0x2034 +#endif + #define TALITOS_AESUISR 0x4030 /* AES unit */ #define TALITOS_AESUISR_LO 0x4034 #define TALITOS_MDEUISR 0x6030 /* message digest unit */ @@ -234,6 +308,7 @@ #define TALITOS_MDEUICR 0x6038 /* interrupt control */ #define TALITOS_MDEUICR_LO 0x603c #define TALITOS_MDEUICR_LO_ICE 0x4000 /* integrity check IRQ enable */ + #define TALITOS_AFEUISR 0x8030 /* arc4 unit */ #define TALITOS_AFEUISR_LO 0x8034 #define TALITOS_RNGUISR 0xa030 /* random number unit */