Add support for PIO mode for GCM mode. Signed-off-by: Lokesh Vutla <lokeshvutla@xxxxxx> --- drivers/crypto/omap-aes-gcm.c | 10 ++++++---- drivers/crypto/omap-aes.c | 24 ++++++++++++++++++------ drivers/crypto/omap-aes.h | 3 ++- 3 files changed, 26 insertions(+), 11 deletions(-) diff --git a/drivers/crypto/omap-aes-gcm.c b/drivers/crypto/omap-aes-gcm.c index 9c68ff0..370891b 100644 --- a/drivers/crypto/omap-aes-gcm.c +++ b/drivers/crypto/omap-aes-gcm.c @@ -52,8 +52,8 @@ static void omap_aes_gcm_done_task(struct omap_aes_dev *dd) u8 *tag; int pages, alen, clen, i, ret = 0, nsg; - alen = ALIGN(dd->assoc_len, AES_BLOCK_SIZE); - clen = ALIGN(dd->total, AES_BLOCK_SIZE); + alen = ALIGN(dd->assoc_len_save, AES_BLOCK_SIZE); + clen = ALIGN(dd->total_save, AES_BLOCK_SIZE); nsg = 1 + !!(dd->assoc_len && dd->total); @@ -161,7 +161,9 @@ static int omap_aes_gcm_copy_buffers(struct omap_aes_dev *dd, dd->in_sg = dd->in_sgl; dd->total = cryptlen; + dd->total_save = cryptlen; dd->assoc_len = req->assoclen; + dd->assoc_len_save = req->assoclen; dd->authsize = authlen; if (omap_aes_check_aligned(req->dst, cryptlen)) { @@ -248,14 +250,14 @@ static int do_encrypt_iv(struct aead_request *req, u32 *tag) return ret; } -void omap_aes_gcm_dma_out_callback(void *data) +void omap_aes_gcm_process_auth_tag(void *data) { struct omap_aes_dev *dd = data; int i, val; u32 *auth_tag, tag[4]; if (!(dd->flags & FLAGS_ENCRYPT)) - scatterwalk_map_and_copy(tag, dd->aead_req->src, dd->total, + scatterwalk_map_and_copy(tag, dd->aead_req->src, dd->total_save, dd->authsize, 0); auth_tag = dd->ctx->auth_tag; diff --git a/drivers/crypto/omap-aes.c b/drivers/crypto/omap-aes.c index 11f3850..8aeb913 100644 --- a/drivers/crypto/omap-aes.c +++ b/drivers/crypto/omap-aes.c @@ -340,7 +340,7 @@ static int omap_aes_crypt_dma(struct omap_aes_dev *dd, } if (dd->flags & FLAGS_GCM) - tx_out->callback = omap_aes_gcm_dma_out_callback; + tx_out->callback = omap_aes_gcm_process_auth_tag; else tx_out->callback = omap_aes_dma_out_callback; tx_out->callback_param = dd; @@ -927,8 +927,15 @@ static irqreturn_t omap_aes_irq(int irq, void *dev_id) status &= ~AES_REG_IRQ_DATA_IN; omap_aes_write(dd, AES_REG_IRQ_STATUS(dd), status); - /* Enable DATA_OUT interrupt */ - omap_aes_write(dd, AES_REG_IRQ_ENABLE(dd), 0x4); + /* + * if GCM mode enable DATA_IN till assoc data is copied + * else Enable DATA_OUT interrupt + * */ + if ((dd->flags & FLAGS_GCM) && dd->assoc_len) + dd->assoc_len -= min((size_t)AES_BLOCK_SIZE, + dd->assoc_len); + else + omap_aes_write(dd, AES_REG_IRQ_ENABLE(dd), 0x4); } else if (status & AES_REG_IRQ_DATA_OUT) { omap_aes_write(dd, AES_REG_IRQ_ENABLE(dd), 0x0); @@ -961,12 +968,17 @@ static irqreturn_t omap_aes_irq(int irq, void *dev_id) status &= ~AES_REG_IRQ_DATA_OUT; omap_aes_write(dd, AES_REG_IRQ_STATUS(dd), status); - if (!dd->total) + if (!dd->total) { /* All bytes read! */ - tasklet_schedule(&dd->done_task); - else + if (dd->flags & FLAGS_GCM) + /* Process auth tag and call done_task */ + omap_aes_gcm_process_auth_tag(dd); + else + tasklet_schedule(&dd->done_task); + } else { /* Enable DATA_IN interrupt for next block */ omap_aes_write(dd, AES_REG_IRQ_ENABLE(dd), 0x2); + } } return IRQ_HANDLED; diff --git a/drivers/crypto/omap-aes.h b/drivers/crypto/omap-aes.h index 0863874..e0621dd 100644 --- a/drivers/crypto/omap-aes.h +++ b/drivers/crypto/omap-aes.h @@ -164,6 +164,7 @@ struct omap_aes_dev { size_t total; size_t total_save; size_t assoc_len; + size_t assoc_len_save; size_t authsize; struct scatterlist *in_sg; @@ -199,7 +200,7 @@ int omap_aes_gcm_decrypt(struct aead_request *req); int omap_aes_write_ctrl(struct omap_aes_dev *dd); int omap_aes_check_aligned(struct scatterlist *sg, int total); int omap_aes_crypt_dma_start(struct omap_aes_dev *dd); -void omap_aes_gcm_dma_out_callback(void *data); +void omap_aes_gcm_process_auth_tag(void *data); int omap_aes_crypt_dma_stop(struct omap_aes_dev *dd); #endif -- 1.7.9.5 -- 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