From patchwork Thu Jan 26 16:07:52 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cyrille Pitchen X-Patchwork-Id: 9539645 X-Patchwork-Delegate: herbert@gondor.apana.org.au Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id E904860429 for ; Thu, 26 Jan 2017 16:13:30 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id D68D026E96 for ; Thu, 26 Jan 2017 16:13:30 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id C9EF627D4D; Thu, 26 Jan 2017 16:13:30 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 77CE926E96 for ; Thu, 26 Jan 2017 16:13:30 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753042AbdAZQNO (ORCPT ); Thu, 26 Jan 2017 11:13:14 -0500 Received: from smtpout.microchip.com ([198.175.253.82]:35469 "EHLO email.microchip.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1752817AbdAZQNG (ORCPT ); Thu, 26 Jan 2017 11:13:06 -0500 Received: from tenerife.corp.atmel.com (10.10.76.4) by chn-sv-exch06.mchp-main.com (10.10.76.107) with Microsoft SMTP Server id 14.3.181.6; Thu, 26 Jan 2017 09:11:56 -0700 From: Cyrille Pitchen To: , , CC: , , , , Cyrille Pitchen Subject: [PATCH v3 07/12] crypto: atmel-sha: add atmel_sha_cpu_start() Date: Thu, 26 Jan 2017 17:07:52 +0100 Message-ID: <14bce182b9defe7bb4a41507901566825bc18b89.1485443478.git.cyrille.pitchen@atmel.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: References: MIME-Version: 1.0 X-Brightmail-Tracker: H4sIAAAAAAAAC+NgFjrEKsWRWlGSWpSXmKPExsXCxeXDontGvivC4MLDWcd5Le59P89sMed8C4tF9ysZi02Pr7Fa3L/3k8ni8q45bBbfLjezW0w9vZbFgcNjwa+tLB6frlxh8tiy8iaTx7YDqh6bl9R7fN4kF8AWxZqZl5RfkcCacfp8O1vBDZmK/2ffsDUwNoh3MXJyCAmsZ5SYcC8YxGYTMJR4++AoK4gtIhAosbDlFWMXIxcHs8A6RomW5rfMIAlhATeJHztesIDYLAKqEl9+rgKzeQXiJc5MPQVWIyEgJ3HzXCeYzSlgK7Hy12o2iGU2Et133jJC1AtKnJz5BKyXWUBC4uCLF8wQNWpAi1dAzQmUeLPiNCuE7STxf+VMdgjbTuLw9ItQtoPE/fsz2GBqDm59DmVrS2x/tQ+qV0di28F+FgjbVmLPjIlMELa7xINHy6FsX4lZDxugaqIkTvV/Zp3AKDELyamzkJy6gJFpFaO0s4efbnCYrmuEs4eBmV5uckaBbm5iZp5ecn7uJkZIhGbvYDwyP+IQoyQHk5Io703tzgghvqT8lMqMxOKM+KLSnNTiQ4wyHBxKErz75boihASLUtNTK9Iyc4CpAibNxMF5iFGCg0dJhHciSA1vcUFibnFmOkT+FKOklDhvJ0hCACSRUZoH13uJUVRKmPe0KFCOpyC1KDezBCJ+i1GY4yGTEEtefl6qFNCdDECgwfiKUZyDUUmY9yrILJ7MvBK4Ha+A1jMBrb/A3A6yviQRISXVwJjOqsHBVhNeVHTb/PWXTxNW/q87zc9zVXNe5feSp/Fr63N1Vv1x8sq/LZ3wqmmXtc/l7k9cbd+MjqV56Ef71d2v2Pk1+cO9+DvVszN9lpWcdyqJfb1sddiurqWdgcrXPfRj/73+pjbB9KSGffnT6I+Z9pv8nNvufNm/QPD9951yWqcShX3fzlNiKc5INNRiLipO BACFnAd+VQMAAA== Sender: linux-crypto-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-crypto@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP This patch adds a simple function to perform data transfer with PIO, hence handled by the CPU. Signed-off-by: Cyrille Pitchen --- drivers/crypto/atmel-sha.c | 90 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) diff --git a/drivers/crypto/atmel-sha.c b/drivers/crypto/atmel-sha.c index be0d72cf4352..58d9ca8ac0f2 100644 --- a/drivers/crypto/atmel-sha.c +++ b/drivers/crypto/atmel-sha.c @@ -64,6 +64,8 @@ #define SHA_FLAGS_ERROR BIT(23) #define SHA_FLAGS_PAD BIT(24) #define SHA_FLAGS_RESTORE BIT(25) +#define SHA_FLAGS_IDATAR0 BIT(26) +#define SHA_FLAGS_WAIT_DATARDY BIT(27) #define SHA_OP_UPDATE 1 #define SHA_OP_FINAL 2 @@ -141,6 +143,7 @@ struct atmel_sha_dev { struct ahash_request *req; bool is_async; atmel_sha_fn_t resume; + atmel_sha_fn_t cpu_transfer_complete; struct atmel_sha_dma dma_lch_in; @@ -1317,6 +1320,93 @@ static irqreturn_t atmel_sha_irq(int irq, void *dev_id) return IRQ_NONE; } + +/* CPU transfer functions */ + +static int atmel_sha_cpu_transfer(struct atmel_sha_dev *dd) +{ + struct ahash_request *req = dd->req; + struct atmel_sha_reqctx *ctx = ahash_request_ctx(req); + const u32 *words = (const u32 *)ctx->buffer; + size_t i, num_words; + u32 isr, din, din_inc; + + din_inc = (ctx->flags & SHA_FLAGS_IDATAR0) ? 0 : 1; + for (;;) { + /* Write data into the Input Data Registers. */ + num_words = DIV_ROUND_UP(ctx->bufcnt, sizeof(u32)); + for (i = 0, din = 0; i < num_words; ++i, din += din_inc) + atmel_sha_write(dd, SHA_REG_DIN(din), words[i]); + + ctx->offset += ctx->bufcnt; + ctx->total -= ctx->bufcnt; + + if (!ctx->total) + break; + + /* + * Prepare next block: + * Fill ctx->buffer now with the next data to be written into + * IDATARx: it gives time for the SHA hardware to process + * the current data so the SHA_INT_DATARDY flag might be set + * in SHA_ISR when polling this register at the beginning of + * the next loop. + */ + ctx->bufcnt = min_t(size_t, ctx->block_size, ctx->total); + scatterwalk_map_and_copy(ctx->buffer, ctx->sg, + ctx->offset, ctx->bufcnt, 0); + + /* Wait for hardware to be ready again. */ + isr = atmel_sha_read(dd, SHA_ISR); + if (!(isr & SHA_INT_DATARDY)) { + /* Not ready yet. */ + dd->resume = atmel_sha_cpu_transfer; + atmel_sha_write(dd, SHA_IER, SHA_INT_DATARDY); + return -EINPROGRESS; + } + } + + if (unlikely(!(ctx->flags & SHA_FLAGS_WAIT_DATARDY))) + return dd->cpu_transfer_complete(dd); + + return atmel_sha_wait_for_data_ready(dd, dd->cpu_transfer_complete); +} + +static int atmel_sha_cpu_start(struct atmel_sha_dev *dd, + struct scatterlist *sg, + unsigned int len, + bool idatar0_only, + bool wait_data_ready, + atmel_sha_fn_t resume) +{ + struct ahash_request *req = dd->req; + struct atmel_sha_reqctx *ctx = ahash_request_ctx(req); + + if (!len) + return resume(dd); + + ctx->flags &= ~(SHA_FLAGS_IDATAR0 | SHA_FLAGS_WAIT_DATARDY); + + if (idatar0_only) + ctx->flags |= SHA_FLAGS_IDATAR0; + + if (wait_data_ready) + ctx->flags |= SHA_FLAGS_WAIT_DATARDY; + + ctx->sg = sg; + ctx->total = len; + ctx->offset = 0; + + /* Prepare the first block to be written. */ + ctx->bufcnt = min_t(size_t, ctx->block_size, ctx->total); + scatterwalk_map_and_copy(ctx->buffer, ctx->sg, + ctx->offset, ctx->bufcnt, 0); + + dd->cpu_transfer_complete = resume; + return atmel_sha_cpu_transfer(dd); +} + + static void atmel_sha_unregister_algs(struct atmel_sha_dev *dd) { int i;