From patchwork Thu Dec 17 16:48:42 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cyrille Pitchen X-Patchwork-Id: 7874551 X-Patchwork-Delegate: herbert@gondor.apana.org.au Return-Path: X-Original-To: patchwork-linux-crypto@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 6A20F9F387 for ; Thu, 17 Dec 2015 16:52:26 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 7C46C20444 for ; Thu, 17 Dec 2015 16:52:25 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 865082015A for ; Thu, 17 Dec 2015 16:52:24 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S967364AbbLQQwD (ORCPT ); Thu, 17 Dec 2015 11:52:03 -0500 Received: from eusmtp01.atmel.com ([212.144.249.242]:56763 "EHLO eusmtp01.atmel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S966668AbbLQQwB (ORCPT ); Thu, 17 Dec 2015 11:52:01 -0500 Received: from tenerife.corp.atmel.com (10.161.101.13) by eusmtp01.atmel.com (10.161.101.30) with Microsoft SMTP Server id 14.3.235.1; Thu, 17 Dec 2015 17:51:54 +0100 From: Cyrille Pitchen To: , , CC: , , , Cyrille Pitchen Subject: [PATCH 11/24] crypto: atmel-aes: rework crypto request completion Date: Thu, 17 Dec 2015 17:48:42 +0100 Message-ID: <1237ced97e6c1b8f676c8e8d68899a503a35f260.1450366831.git.cyrille.pitchen@atmel.com> X-Mailer: git-send-email 1.8.2.2 In-Reply-To: References: MIME-Version: 1.0 Sender: linux-crypto-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-crypto@vger.kernel.org X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP This patch introduces a new callback 'resume' in the struct atmel_aes_dev. This callback is run to resume/complete the processing of the crypto request when woken up by I/O events such as AES interrupts or DMA completion. This callback will help implementing the GCM mode support in further patches. Signed-off-by: Cyrille Pitchen --- drivers/crypto/atmel-aes.c | 74 +++++++++++++++++++++++++++++----------------- 1 file changed, 47 insertions(+), 27 deletions(-) diff --git a/drivers/crypto/atmel-aes.c b/drivers/crypto/atmel-aes.c index c10c54ccc606..ac551ee2d624 100644 --- a/drivers/crypto/atmel-aes.c +++ b/drivers/crypto/atmel-aes.c @@ -119,6 +119,9 @@ struct atmel_aes_dev { struct crypto_async_request *areq; struct atmel_aes_base_ctx *ctx; + bool is_async; + atmel_aes_fn_t resume; + struct device *dev; struct clk *iclk; int irq; @@ -319,14 +322,17 @@ static inline void atmel_aes_set_mode(struct atmel_aes_dev *dd, dd->flags = (dd->flags & AES_FLAGS_PERSISTENT) | rctx->mode; } -static void atmel_aes_finish_req(struct atmel_aes_dev *dd, int err) +static inline int atmel_aes_complete(struct atmel_aes_dev *dd, int err) { - struct ablkcipher_request *req = ablkcipher_request_cast(dd->areq); - clk_disable_unprepare(dd->iclk); dd->flags &= ~AES_FLAGS_BUSY; - req->base.complete(&req->base, err); + if (dd->is_async) + dd->areq->complete(dd->areq, err); + + tasklet_schedule(&dd->queue_task); + + return err; } static void atmel_aes_dma_callback(void *data) @@ -423,6 +429,8 @@ static int atmel_aes_crypt_dma(struct atmel_aes_dev *dd, return 0; } +static int atmel_aes_cpu_complete(struct atmel_aes_dev *dd); + static int atmel_aes_crypt_cpu_start(struct atmel_aes_dev *dd) { struct ablkcipher_request *req = ablkcipher_request_cast(dd->areq); @@ -455,9 +463,12 @@ static int atmel_aes_crypt_cpu_start(struct atmel_aes_dev *dd) atmel_aes_write_n(dd, AES_IDATAR(0), (u32 *) dd->buf_in, dd->bufcnt >> 2); - return 0; + dd->resume = atmel_aes_cpu_complete; + return -EINPROGRESS; } +static int atmel_aes_dma_complete(struct atmel_aes_dev *dd); + static int atmel_aes_crypt_dma_start(struct atmel_aes_dev *dd) { int err, fast = 0, in, out; @@ -524,7 +535,8 @@ static int atmel_aes_crypt_dma_start(struct atmel_aes_dev *dd) dma_unmap_sg(dd->dev, dd->out_sg, 1, DMA_TO_DEVICE); } - return err; + dd->resume = atmel_aes_dma_complete; + return err ? : -EINPROGRESS; } static void atmel_aes_write_ctrl(struct atmel_aes_dev *dd, bool use_dma, @@ -590,9 +602,10 @@ static int atmel_aes_handle_queue(struct atmel_aes_dev *dd, dd->areq = areq; dd->ctx = ctx; + dd->is_async = (areq != new_areq); err = ctx->start(dd); - return (areq != new_areq) ? ret : err; + return (dd->is_async) ? ret : err; } static int atmel_aes_start(struct atmel_aes_dev *dd) @@ -621,10 +634,9 @@ static int atmel_aes_start(struct atmel_aes_dev *dd) else err = atmel_aes_crypt_cpu_start(dd); } - if (err) { + if (err && err != -EINPROGRESS) { /* aes_task will not finish it, so do it here */ - atmel_aes_finish_req(dd, err); - tasklet_schedule(&dd->queue_task); + return atmel_aes_complete(dd, err); } return -EINPROGRESS; @@ -1149,20 +1161,14 @@ static void atmel_aes_queue_task(unsigned long data) static void atmel_aes_done_task(unsigned long data) { struct atmel_aes_dev *dd = (struct atmel_aes_dev *) data; - int err; - - if (!(dd->flags & AES_FLAGS_DMA)) { - atmel_aes_read_n(dd, AES_ODATAR(0), (u32 *) dd->buf_out, - dd->bufcnt >> 2); - if (sg_copy_from_buffer(dd->out_sg, dd->nb_out_sg, - dd->buf_out, dd->bufcnt)) - err = 0; - else - err = -EINVAL; + dd->is_async = true; + (void)dd->resume(dd); +} - goto cpu_end; - } +static int atmel_aes_dma_complete(struct atmel_aes_dev *dd) +{ + int err; err = atmel_aes_crypt_dma_stop(dd); @@ -1177,13 +1183,27 @@ static void atmel_aes_done_task(unsigned long data) } if (!err) err = atmel_aes_crypt_dma_start(dd); - if (!err) - return; /* DMA started. Not fininishing. */ + if (!err || err == -EINPROGRESS) + return -EINPROGRESS; /* DMA started. Not fininishing. */ } -cpu_end: - atmel_aes_finish_req(dd, err); - atmel_aes_handle_queue(dd, NULL); + return atmel_aes_complete(dd, err); +} + +static int atmel_aes_cpu_complete(struct atmel_aes_dev *dd) +{ + int err; + + atmel_aes_read_n(dd, AES_ODATAR(0), (u32 *) dd->buf_out, + dd->bufcnt >> 2); + + if (sg_copy_from_buffer(dd->out_sg, dd->nb_out_sg, + dd->buf_out, dd->bufcnt)) + err = 0; + else + err = -EINVAL; + + return atmel_aes_complete(dd, err); } static irqreturn_t atmel_aes_irq(int irq, void *dev_id)