SEC2 and SEC1 error handling will be different because so many bits are different. So we move error handling into talitos2.c Signed-off-by: Christophe Leroy <christophe.leroy@xxxxxx> --- drivers/crypto/talitos.c | 103 +++++----------------------------------------- drivers/crypto/talitos.h | 8 ++++ drivers/crypto/talitos2.c | 82 ++++++++++++++++++++++++++++++++++++ 3 files changed, 101 insertions(+), 92 deletions(-) diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c index 32848e5..de31ab0 100644 --- a/drivers/crypto/talitos.c +++ b/drivers/crypto/talitos.c @@ -68,7 +68,7 @@ static unsigned int do_reset_channel(struct talitos_private *priv, int ch) return timeout; } -static int reset_channel(struct device *dev, int ch) +int talitos_reset_channel(struct device *dev, int ch) { struct talitos_private *priv = dev_get_drvdata(dev); unsigned int timeout = do_reset_channel(priv, ch); @@ -124,7 +124,7 @@ static void do_init_device(struct talitos_private *priv) setbits32(priv->reg + TALITOS_IMR_LO, TALITOS_IMR_LO_INIT); } -static int init_device(struct device *dev) +int talitos_init_device(struct device *dev) { struct talitos_private *priv = dev_get_drvdata(dev); int ch, err; @@ -145,7 +145,7 @@ static int init_device(struct device *dev) /* reset channels */ for (ch = 0; ch < priv->num_channels; ch++) { - err = reset_channel(dev, ch); + err = talitos_reset_channel(dev, ch); if (err) return err; } @@ -223,7 +223,7 @@ EXPORT_SYMBOL(talitos_submit); /* * process what was done, notify callback of error if not */ -static void flush_channel(struct device *dev, int ch, int error, int reset_ch) +void talitos_flush_channel(struct device *dev, int ch, int error, int reset_ch) { struct talitos_private *priv = dev_get_drvdata(dev); struct talitos_request *request, saved_req; @@ -289,15 +289,15 @@ static void talitos_done_##name(unsigned long data) \ unsigned long flags; \ \ if (ch_done_mask & 1) \ - flush_channel(dev, 0, 0, 0); \ + talitos_flush_channel(dev, 0, 0, 0); \ if (priv->num_channels == 1) \ goto out; \ if (ch_done_mask & (1 << 2)) \ - flush_channel(dev, 1, 0, 0); \ + talitos_flush_channel(dev, 1, 0, 0); \ if (ch_done_mask & (1 << 4)) \ - flush_channel(dev, 2, 0, 0); \ + talitos_flush_channel(dev, 2, 0, 0); \ if (ch_done_mask & (1 << 6)) \ - flush_channel(dev, 3, 0, 0); \ + talitos_flush_channel(dev, 3, 0, 0); \ \ out: \ /* At this point, all completed channels have been processed */ \ @@ -345,10 +345,11 @@ static u32 current_desc_hdr(struct device *dev, int ch) /* * user diagnostics; report root cause of error based on execution unit status */ -static void report_eu_error(struct device *dev, int ch, u32 desc_hdr) +void talitos_report_eu_error(struct device *dev, int ch) { struct talitos_private *priv = dev_get_drvdata(dev); int i; + u32 desc_hdr = current_desc_hdr(dev, ch); if (!desc_hdr) desc_hdr = in_be32(priv->chan[ch].reg + TALITOS_DESCBUF); @@ -417,88 +418,6 @@ static void report_eu_error(struct device *dev, int ch, u32 desc_hdr) in_be32(priv->chan[ch].reg + TALITOS_DESCBUF_LO + 8*i)); } -/* - * recover from error interrupts - */ -static void talitos_error(struct device *dev, u32 isr, u32 isr_lo) -{ - struct talitos_private *priv = dev_get_drvdata(dev); - unsigned int timeout = TALITOS_TIMEOUT; - int ch, error, reset_dev = 0, reset_ch = 0; - u32 v, v_lo; - - for (ch = 0; ch < priv->num_channels; ch++) { - /* skip channels without errors */ - if (!(isr & (1 << (ch * 2 + 1)))) - continue; - - error = -EINVAL; - - v = in_be32(priv->chan[ch].reg + TALITOS_CCPSR); - v_lo = in_be32(priv->chan[ch].reg + TALITOS_CCPSR_LO); - - if (v_lo & TALITOS_CCPSR_LO_DOF) { - dev_err(dev, "double fetch fifo overflow error\n"); - error = -EAGAIN; - reset_ch = 1; - } - if (v_lo & TALITOS_CCPSR_LO_SOF) { - /* h/w dropped descriptor */ - dev_err(dev, "single fetch fifo overflow error\n"); - error = -EAGAIN; - } - if (v_lo & TALITOS_CCPSR_LO_MDTE) - dev_err(dev, "master data transfer error\n"); - if (v_lo & TALITOS_CCPSR_LO_SGDLZ) - 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"); - if (v_lo & TALITOS_CCPSR_LO_IDH) - dev_err(dev, "illegal descriptor header error\n"); - if (v_lo & TALITOS_CCPSR_LO_IEU) - dev_err(dev, "invalid execution unit error\n"); - if (v_lo & TALITOS_CCPSR_LO_EU) - report_eu_error(dev, ch, current_desc_hdr(dev, ch)); - if (v_lo & TALITOS_CCPSR_LO_GB) - dev_err(dev, "gather boundary error\n"); - if (v_lo & TALITOS_CCPSR_LO_GRL) - dev_err(dev, "gather return/length error\n"); - if (v_lo & TALITOS_CCPSR_LO_SB) - dev_err(dev, "scatter boundary error\n"); - if (v_lo & TALITOS_CCPSR_LO_SRL) - dev_err(dev, "scatter return/length error\n"); - - flush_channel(dev, ch, error, reset_ch); - - if (reset_ch) { - reset_channel(dev, ch); - } else { - setbits32(priv->chan[ch].reg + TALITOS_CCCR, - TALITOS_CCCR_CONT); - setbits32(priv->chan[ch].reg + TALITOS_CCCR_LO, 0); - while ((in_be32(priv->chan[ch].reg + TALITOS_CCCR) & - TALITOS_CCCR_CONT) && --timeout) - cpu_relax(); - if (timeout == 0) { - dev_err(dev, "failed to restart channel %d\n", - ch); - reset_dev = 1; - } - } - } - if (reset_dev || isr & ~TALITOS_ISR_4CHERR || isr_lo) { - 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++) - flush_channel(dev, ch, -EIO, 1); - - /* reset and reinitialize the device */ - init_device(dev); - } -} - #define DEF_TALITOS_INTERRUPT(name, ch_done_mask, ch_err_mask, tlet) \ static irqreturn_t talitos_interrupt_##name(int irq, void *data) \ { \ @@ -2106,7 +2025,7 @@ static int talitos_probe(struct platform_device *ofdev) dma_set_mask(dev, DMA_BIT_MASK(36)); /* reset and initialize the h/w */ - err = init_device(dev); + err = talitos_init_device(dev); if (err) { dev_err(dev, "failed to initialize device\n"); goto err_out; diff --git a/drivers/crypto/talitos.h b/drivers/crypto/talitos.h index 46233cb..f95e4bc 100644 --- a/drivers/crypto/talitos.h +++ b/drivers/crypto/talitos.h @@ -145,6 +145,14 @@ extern struct talitos_edesc *talitos_edesc_alloc(struct device *dev, int icv_stashing, u32 cryptoflags, bool encrypt); + +extern int talitos_reset_channel(struct device *dev, int ch); +extern int talitos_init_device(struct device *dev); +extern void talitos_flush_channel(struct device *dev, int ch, int error, + int reset_ch); +extern void talitos_report_eu_error(struct device *dev, int ch); +extern void talitos_error(struct device *dev, u32 isr, u32 isr_lo); + extern int talitos_cra_init(struct crypto_tfm *tfm); /* .features flag */ diff --git a/drivers/crypto/talitos2.c b/drivers/crypto/talitos2.c index 024cbbd..80f6bc0 100644 --- a/drivers/crypto/talitos2.c +++ b/drivers/crypto/talitos2.c @@ -183,6 +183,88 @@ void map_sg_out_talitos_ptr(struct device *dev, struct scatterlist *dst, } } +/* + * recover from error interrupts + */ +void talitos_error(struct device *dev, u32 isr, u32 isr_lo) +{ + struct talitos_private *priv = dev_get_drvdata(dev); + unsigned int timeout = TALITOS_TIMEOUT; + int ch, error, reset_dev = 0, reset_ch = 0; + u32 v, v_lo; + + for (ch = 0; ch < priv->num_channels; ch++) { + /* skip channels without errors */ + if (!(isr & (1 << (ch * 2 + 1)))) + continue; + + error = -EINVAL; + + v = in_be32(priv->chan[ch].reg + TALITOS_CCPSR); + v_lo = in_be32(priv->chan[ch].reg + TALITOS_CCPSR_LO); + + if (v_lo & TALITOS_CCPSR_LO_DOF) { + dev_err(dev, "double fetch fifo overflow error\n"); + error = -EAGAIN; + reset_ch = 1; + } + if (v_lo & TALITOS_CCPSR_LO_SOF) { + /* h/w dropped descriptor */ + dev_err(dev, "single fetch fifo overflow error\n"); + error = -EAGAIN; + } + if (v_lo & TALITOS_CCPSR_LO_MDTE) + dev_err(dev, "master data transfer error\n"); + if (v_lo & TALITOS_CCPSR_LO_SGDLZ) + 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"); + if (v_lo & TALITOS_CCPSR_LO_IDH) + dev_err(dev, "illegal descriptor header error\n"); + if (v_lo & TALITOS_CCPSR_LO_IEU) + dev_err(dev, "invalid execution unit error\n"); + if (v_lo & TALITOS_CCPSR_LO_EU) + talitos_report_eu_error(dev, ch); + if (v_lo & TALITOS_CCPSR_LO_GB) + dev_err(dev, "gather boundary error\n"); + if (v_lo & TALITOS_CCPSR_LO_GRL) + dev_err(dev, "gather return/length error\n"); + if (v_lo & TALITOS_CCPSR_LO_SB) + dev_err(dev, "scatter boundary error\n"); + if (v_lo & TALITOS_CCPSR_LO_SRL) + dev_err(dev, "scatter return/length error\n"); + + talitos_flush_channel(dev, ch, error, reset_ch); + + if (reset_ch) { + talitos_reset_channel(dev, ch); + } else { + setbits32(priv->chan[ch].reg + TALITOS_CCCR, + TALITOS_CCCR_CONT); + setbits32(priv->chan[ch].reg + TALITOS_CCCR_LO, 0); + while ((in_be32(priv->chan[ch].reg + TALITOS_CCCR) & + TALITOS_CCCR_CONT) && --timeout) + cpu_relax(); + if (timeout == 0) { + dev_err(dev, "failed to restart channel %d\n", + ch); + reset_dev = 1; + } + } + } + if (reset_dev || isr & ~TALITOS_ISR_4CHERR || isr_lo) { + 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++) + talitos_flush_channel(dev, ch, -EIO, 1); + + /* reset and reinitialize the device */ + talitos_init_device(dev); + } +} + int aead_setauthsize(struct crypto_aead *authenc, unsigned int authsize) { -- 2.1.0 -- To unsubscribe from this list: send the line "unsubscribe linux-crypto" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html