[RFC, prePATCH] crypto: talitos modified for powerpc 88x security engine

From: Christophe Leroy
Date: Fri Jul 11 2014 - 08:32:30 EST


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 <christophe.leroy@xxxxxx>

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 = "<built-in>";
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 */
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/