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: 7874701 Return-Path: X-Original-To: patchwork-linux-arm@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 726A19F387 for ; Thu, 17 Dec 2015 16:55:39 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 7ADC92042C for ; Thu, 17 Dec 2015 16:55:38 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 85AD2202A1 for ; Thu, 17 Dec 2015 16:55:37 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1a9bor-000810-71; Thu, 17 Dec 2015 16:54:21 +0000 Received: from eusmtp01.atmel.com ([212.144.249.242]) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1a9bn5-0005FD-8o for linux-arm-kernel@lists.infradead.org; Thu, 17 Dec 2015 16:52:34 +0000 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: , , 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 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20151217_085231_874162_3E66461B X-CRM114-Status: GOOD ( 14.29 ) X-Spam-Score: -4.2 (----) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Cyrille Pitchen , linux-crypto@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Spam-Status: No, score=-4.2 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, 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)