From patchwork Thu Dec 22 16:37:56 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cyrille Pitchen X-Patchwork-Id: 9485321 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 5B9EB601C0 for ; Thu, 22 Dec 2016 16:39:32 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 4D6B628066 for ; Thu, 22 Dec 2016 16:39:32 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 427542811E; Thu, 22 Dec 2016 16:39:32 +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 E4B9728066 for ; Thu, 22 Dec 2016 16:39:31 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S966335AbcLVQiH (ORCPT ); Thu, 22 Dec 2016 11:38:07 -0500 Received: from exsmtp02.microchip.com ([198.175.253.38]:49431 "EHLO email.microchip.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S966295AbcLVQiG (ORCPT ); Thu, 22 Dec 2016 11:38:06 -0500 Received: from tenerife.corp.atmel.com (10.10.76.4) by chn-sv-exch02.mchp-main.com (10.10.76.38) with Microsoft SMTP Server id 14.3.181.6; Thu, 22 Dec 2016 09:38:05 -0700 From: Cyrille Pitchen To: , , CC: , , , Cyrille Pitchen Subject: [PATCH v2 07/12] crypto: atmel-sha: add atmel_sha_cpu_start() Date: Thu, 22 Dec 2016 17:37:56 +0100 Message-ID: <39e69aee6fcce63e8c9aa083ac8c28171ac5f3b9.1482424395.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+NgFupkVWLjYuHi8mHRzWOMiTC4snzWFkaLwwunMFo8eN/JYjFt+jtmi3uftjFadExZxeTAGsAQxZqZl5RfkcCacfp8O1vBDZmK/2ffsDUwNoh3MXJxCAmsY5RYdXYjSxcjJwebgKHE2wdHWUFsEYFAiYUtrxhBipgFpjNKPFj9jh0kISzgJvHhz30mEJtFQFWiZ2EzUJyDg1cgXqJjGy9IWEJATuLmuU5mEJtTwFZi/dx7rCAlQgI2EgffCoGEeQUEJU7OfAK2lllAQuLgixdg5UICakBrVzBDjAmUONU9jxHCdpKY9XMzC4RtJ3F4+kV2CNte4tK+SywwNZc+vmCCsLUltr/axwph60hsO9gPVWMrsWfGRKgad4kHj5ZD2b4Ssx42QNVESdxu3sU+gVFiFpJTZyE5dQEj0ypGaWcPP93gMF3XCGcPAyO93OSMAt3cxMw8veT83E2MkGhS28E4s8f/EKMkB5OSKO/WSefDhfiS8lMqMxKLM+KLSnNSiw8xSnDwKInwblwOlOMtLkjMLc5Mh0nJcHAoSfBGgKQEi1LTUyvSMnNKUosg0qcYJaXEeaNBkgIgfRmleXC5S4yiUsK8UUuBcjwFqUW5mSUQ8VuMwhwPmYRY8vLzUqWATmQAAg3GV4ziHIxKwrz7QWbxZOaVwJ3wCug6JqDr1u0+DXJdSSJCSqqBUexCutvhCaZiNuLsyh/2sf+rVojM+O8kevHUzLdrdvH2Ol1xjfi9Y3NqfH3d1yBF/ei51/b3u6taHp6whb8rQCAsYNGkj6trn8hWfwoRWOBUtzilz22CKVtB3rO1a7vn2XhpH1F9y7dGu+7/1Kaire2zzDjXuy4Uex7XfDcml8/1s3zdkbvMSizFGYmGWsxFxYkAXQYhthwDAAA= 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;