From patchwork Thu Aug 3 13:46:03 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cosar Dindar X-Patchwork-Id: 9879193 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 E6B1E60360 for ; Thu, 3 Aug 2017 13:47:11 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id DC00C287B9 for ; Thu, 3 Aug 2017 13:47:11 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id D0A93288FC; Thu, 3 Aug 2017 13:47:11 +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.5 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, RCVD_IN_DNSWL_HI, RCVD_IN_SORBS_SPAM 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 D212B287B9 for ; Thu, 3 Aug 2017 13:47:10 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752052AbdHCNrA (ORCPT ); Thu, 3 Aug 2017 09:47:00 -0400 Received: from mail-wm0-f68.google.com ([74.125.82.68]:33652 "EHLO mail-wm0-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751872AbdHCNqk (ORCPT ); Thu, 3 Aug 2017 09:46:40 -0400 Received: by mail-wm0-f68.google.com with SMTP id q189so2278663wmd.0; Thu, 03 Aug 2017 06:46:39 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id; bh=exnt1Fcj6H2lxT/pbcjtXwzHtKOL++MaCt8kfK+8Y6Q=; b=Jb4MD+PCGoLRZQyeChiTnSkYtQ0l6Vc99LRVo/InmxhgSR5LF6p436mAwDn2J8LZfE bg6/PWFVwaRsTYn44YBMUdGliCYlLdjrBcyy5BdKqiVQ8ivUcY6i45s5mhbqWYxyjl1H dSZPlyYYEmjqOV/M4C/io0n7EirUihCZQF90LqG/thVMkCz7qEJ1lTCdLpU97u/P9JXL NmqYgTWpGrOscmab00HU736uxpA4rj/jO62hGhPOXwpNYpet808G0uTLYLuD9VvrPM3p 4MvhQr/zWILhw5NnLboq8FNtqiMCgI9j5Z3fRL3qmqxxRZ/ZHLe9c3BoQJEZW3LJWG4O FBZw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=exnt1Fcj6H2lxT/pbcjtXwzHtKOL++MaCt8kfK+8Y6Q=; b=bUMxqJBA7hu9f6WOIpQrHYPUntiytzuPpO2yDCK3keae8dHwxsKSNU7vQtO7wFgXfX BZWSCFi0hRKzrphQXHZbEO4w8/dy93HoPXisA6B/SEaNdvrcAuw27EPzWA0A9/VJfvr3 Oktt08FaR8sXluKpA6Vu752a/Bkw1CtpIkFwAuLTgshb5AA2XTYE/I65nV9/DWjg1V1l RSl2QaT+PUGqvNdkCjY1S4VLqLWJPHgCssRPtZpfUNYT1kDp4rKhydb6uo6qPQJDNnKO +56jaU7b/S5VhugSYnjmyVEJ1tMXRbAfQem26sJC9FTW4BOyI2VdioQvfVr1uAlMQzKF FrVg== X-Gm-Message-State: AIVw110oLUIYxJ6CBE2eajAnmgFFmz1VsEyzEjENelyXfej2AVZ1JW9Q puPXRe5LUZX3lw== X-Received: by 10.80.146.168 with SMTP id k37mr1987810eda.23.1501767998996; Thu, 03 Aug 2017 06:46:38 -0700 (PDT) Received: from osboxes.netas.lab.nortel.com ([217.78.105.58]) by smtp.gmail.com with ESMTPSA id t4sm120113edt.86.2017.08.03.06.46.37 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 03 Aug 2017 06:46:38 -0700 (PDT) From: Cosar Dindar To: herbert@gondor.apana.org.au Cc: davem@davemloft.net, mcoquelin.stm32@gmail.com, alexandre.torgue@st.com, fabien.dessenne@st.com, weiyongjun1@huawei.com, lionel.debieve@st.com, linux-crypto@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, Cosar Dindar Subject: [PATCH v5] crypto : stm32 - Add STM32F4 CRC32 support Date: Thu, 3 Aug 2017 16:46:03 +0300 Message-Id: <408e795dea80840a909bab590ea498848e5e3800.1501766734.git.cosardindar@gmail.com> X-Mailer: git-send-email 2.7.4 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 CRC (CRC32 Crypto) support for STM32F4 series. As an hardware limitation polynomial and key setting are not supported. They are fixed as 0x4C11DB7 (poly) and 0xFFFFFFFF (key). CRC32C Castagnoli algorithm is not used. Signed-off-by: Cosar Dindar --- Changes in v5: - shash_alg struct definitons are defined seperately according to the platform type. Changes in v4: - Edited patch summary. Changes in v3: - Rearranged patch order to fix build test error. Changes in v2: - Patchset created instead of one patch. drivers/crypto/stm32/stm32_crc32.c | 101 ++++++++++++++++++++++++++++++++----- 1 file changed, 89 insertions(+), 12 deletions(-) diff --git a/drivers/crypto/stm32/stm32_crc32.c b/drivers/crypto/stm32/stm32_crc32.c index ec83b1e..39b28b8 100644 --- a/drivers/crypto/stm32/stm32_crc32.c +++ b/drivers/crypto/stm32/stm32_crc32.c @@ -1,12 +1,14 @@ /* * Copyright (C) STMicroelectronics SA 2017 * Author: Fabien Dessenne + * Author: Cosar Dindar * License terms: GNU General Public License (GPL), version 2 */ #include #include #include +#include #include #include @@ -37,8 +39,12 @@ struct stm32_crc { struct device *dev; void __iomem *regs; struct clk *clk; + struct shash_alg *algs; u8 pending_data[sizeof(u32)]; size_t nb_pending_bytes; + bool key_support; + bool poly_support; + bool reverse_support; }; struct stm32_crc_list { @@ -106,13 +112,31 @@ static int stm32_crc_init(struct shash_desc *desc) } spin_unlock_bh(&crc_list.lock); - /* Reset, set key, poly and configure in bit reverse mode */ - writel(bitrev32(mctx->key), ctx->crc->regs + CRC_INIT); - writel(bitrev32(mctx->poly), ctx->crc->regs + CRC_POL); - writel(CRC_CR_RESET | CRC_CR_REVERSE, ctx->crc->regs + CRC_CR); + /* set key */ + if (ctx->crc->key_support) { + writel(bitrev32(mctx->key), ctx->crc->regs + CRC_INIT); + } else if (mctx->key != CRC_INIT_DEFAULT) { + dev_err(ctx->crc->dev, "Unsupported key value! Should be: 0x%x\n", + CRC_INIT_DEFAULT); + return -EINVAL; + } + + /* set poly */ + if (ctx->crc->poly_support) + writel(bitrev32(mctx->poly), ctx->crc->regs + CRC_POL); + + /* reset and configure in bit reverse mode if supported */ + if (ctx->crc->reverse_support) + writel(CRC_CR_RESET | CRC_CR_REVERSE, ctx->crc->regs + CRC_CR); + else + writel(CRC_CR_RESET, ctx->crc->regs + CRC_CR); + + /* store partial result */ + if (!ctx->crc->reverse_support) + ctx->partial = bitrev32(readl(crc->regs + CRC_DR)); + else + ctx->partial = readl(ctx->crc->regs + CRC_DR); - /* Store partial result */ - ctx->partial = readl(ctx->crc->regs + CRC_DR); ctx->crc->nb_pending_bytes = 0; return 0; @@ -135,7 +159,12 @@ static int stm32_crc_update(struct shash_desc *desc, const u8 *d8, if (crc->nb_pending_bytes == sizeof(u32)) { /* Process completed pending data */ - writel(*(u32 *)crc->pending_data, crc->regs + CRC_DR); + if (!ctx->crc->reverse_support) + writel(bitrev32(*(u32 *)crc->pending_data), + crc->regs + CRC_DR); + else + writel(*(u32 *)crc->pending_data, + crc->regs + CRC_DR); crc->nb_pending_bytes = 0; } } @@ -143,10 +172,16 @@ static int stm32_crc_update(struct shash_desc *desc, const u8 *d8, d32 = (u32 *)d8; for (i = 0; i < length >> 2; i++) /* Process 32 bits data */ - writel(*(d32++), crc->regs + CRC_DR); + if (!ctx->crc->reverse_support) + writel(bitrev32(*(d32++)), crc->regs + CRC_DR); + else + writel(*(d32++), crc->regs + CRC_DR); /* Store partial result */ - ctx->partial = readl(crc->regs + CRC_DR); + if (!ctx->crc->reverse_support) + ctx->partial = bitrev32(readl(crc->regs + CRC_DR)); + else + ctx->partial = readl(crc->regs + CRC_DR); /* Check for pending data (non 32 bits) */ length &= 3; @@ -192,7 +227,7 @@ static int stm32_crc_digest(struct shash_desc *desc, const u8 *data, return stm32_crc_init(desc) ?: stm32_crc_finup(desc, data, length, out); } -static struct shash_alg algs[] = { +static struct shash_alg algs_for_f7[] = { /* CRC-32 */ { .setkey = stm32_crc_setkey, @@ -237,12 +272,37 @@ static struct shash_alg algs[] = { } }; +static struct shash_alg algs_for_f4[] = { + /* CRC-32 */ + { + .setkey = stm32_crc_setkey, + .init = stm32_crc_init, + .update = stm32_crc_update, + .final = stm32_crc_final, + .finup = stm32_crc_finup, + .digest = stm32_crc_digest, + .descsize = sizeof(struct stm32_crc_desc_ctx), + .digestsize = CHKSUM_DIGEST_SIZE, + .base = { + .cra_name = "crc32", + .cra_driver_name = DRIVER_NAME, + .cra_priority = 200, + .cra_blocksize = CHKSUM_BLOCK_SIZE, + .cra_alignmask = 3, + .cra_ctxsize = sizeof(struct stm32_crc_ctx), + .cra_module = THIS_MODULE, + .cra_init = stm32_crc32_cra_init, + } + } +}; + static int stm32_crc_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct stm32_crc *crc; struct resource *res; int ret; + int algs_size; crc = devm_kzalloc(dev, sizeof(*crc), GFP_KERNEL); if (!crc) @@ -269,13 +329,29 @@ static int stm32_crc_probe(struct platform_device *pdev) return ret; } + /* set key, poly and reverse support if device is of F7 series */ + if (of_device_is_compatible(crc->dev->of_node, "st,stm32f7-crc")) { + crc->key_support = true; + crc->poly_support = true; + crc->reverse_support = true; + } + platform_set_drvdata(pdev, crc); spin_lock(&crc_list.lock); list_add(&crc->list, &crc_list.dev_list); spin_unlock(&crc_list.lock); - ret = crypto_register_shashes(algs, ARRAY_SIZE(algs)); + /* For F4 series only CRC32 algorithm will be used */ + if (of_device_is_compatible(crc->dev->of_node, "st,stm32f4-crc")) { + crc->algs = algs_for_f4; + algs_size = ARRAY_SIZE(algs_for_f4); + } else { + crc->algs = algs_for_f7; + algs_size = ARRAY_SIZE(algs_for_f7); + } + + ret = crypto_register_shashes(crc->algs, algs_size); if (ret) { dev_err(dev, "Failed to register\n"); clk_disable_unprepare(crc->clk); @@ -295,7 +371,7 @@ static int stm32_crc_remove(struct platform_device *pdev) list_del(&crc->list); spin_unlock(&crc_list.lock); - crypto_unregister_shash(algs); + crypto_unregister_shash(crc->algs); clk_disable_unprepare(crc->clk); @@ -304,6 +380,7 @@ static int stm32_crc_remove(struct platform_device *pdev) static const struct of_device_id stm32_dt_ids[] = { { .compatible = "st,stm32f7-crc", }, + { .compatible = "st,stm32f4-crc", }, {}, }; MODULE_DEVICE_TABLE(of, stm32_dt_ids);