summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/char/hw_random/Kconfig13
-rw-r--r--drivers/char/hw_random/Makefile1
-rw-r--r--drivers/char/hw_random/xgene-rng.c423
-rw-r--r--drivers/crypto/caam/caamhash.c28
-rw-r--r--drivers/crypto/caam/ctrl.c24
-rw-r--r--drivers/crypto/caam/regs.h13
-rw-r--r--drivers/crypto/caam/sg_sw_sec4.h54
-rw-r--r--drivers/crypto/mv_cesa.h1
-rw-r--r--drivers/crypto/qat/qat_common/adf_ctl_drv.c2
-rw-r--r--drivers/crypto/qat/qat_dh895xcc/adf_isr.c6
10 files changed, 492 insertions, 73 deletions
diff --git a/drivers/char/hw_random/Kconfig b/drivers/char/hw_random/Kconfig
index 836b061ced35..91a04ae8003c 100644
--- a/drivers/char/hw_random/Kconfig
+++ b/drivers/char/hw_random/Kconfig
@@ -333,6 +333,19 @@ config HW_RANDOM_MSM
If unsure, say Y.
+config HW_RANDOM_XGENE
+ tristate "APM X-Gene True Random Number Generator (TRNG) support"
+ depends on HW_RANDOM && ARCH_XGENE
+ default HW_RANDOM
+ ---help---
+ This driver provides kernel-side support for the Random Number
+ Generator hardware found on APM X-Gene SoC.
+
+ To compile this driver as a module, choose M here: the
+ module will be called xgene_rng.
+
+ If unsure, say Y.
+
endif # HW_RANDOM
config UML_RANDOM
diff --git a/drivers/char/hw_random/Makefile b/drivers/char/hw_random/Makefile
index 199ed283e149..0b4cd57f4e24 100644
--- a/drivers/char/hw_random/Makefile
+++ b/drivers/char/hw_random/Makefile
@@ -29,3 +29,4 @@ obj-$(CONFIG_HW_RANDOM_EXYNOS) += exynos-rng.o
obj-$(CONFIG_HW_RANDOM_TPM) += tpm-rng.o
obj-$(CONFIG_HW_RANDOM_BCM2835) += bcm2835-rng.o
obj-$(CONFIG_HW_RANDOM_MSM) += msm-rng.o
+obj-$(CONFIG_HW_RANDOM_XGENE) += xgene-rng.o
diff --git a/drivers/char/hw_random/xgene-rng.c b/drivers/char/hw_random/xgene-rng.c
new file mode 100644
index 000000000000..23caa05380a8
--- /dev/null
+++ b/drivers/char/hw_random/xgene-rng.c
@@ -0,0 +1,423 @@
+/*
+ * APM X-Gene SoC RNG Driver
+ *
+ * Copyright (c) 2014, Applied Micro Circuits Corporation
+ * Author: Rameshwar Prasad Sahu <rsahu@apm.com>
+ * Shamal Winchurkar <swinchurkar@apm.com>
+ * Feng Kan <fkan@apm.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/hw_random.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/of_platform.h>
+#include <linux/of_irq.h>
+#include <linux/of_address.h>
+#include <linux/timer.h>
+
+#define RNG_MAX_DATUM 4
+#define MAX_TRY 100
+#define XGENE_RNG_RETRY_COUNT 20
+#define XGENE_RNG_RETRY_INTERVAL 10
+
+/* RNG Registers */
+#define RNG_INOUT_0 0x00
+#define RNG_INTR_STS_ACK 0x10
+#define RNG_CONTROL 0x14
+#define RNG_CONFIG 0x18
+#define RNG_ALARMCNT 0x1c
+#define RNG_FROENABLE 0x20
+#define RNG_FRODETUNE 0x24
+#define RNG_ALARMMASK 0x28
+#define RNG_ALARMSTOP 0x2c
+#define RNG_OPTIONS 0x78
+#define RNG_EIP_REV 0x7c
+
+#define MONOBIT_FAIL_MASK BIT(7)
+#define POKER_FAIL_MASK BIT(6)
+#define LONG_RUN_FAIL_MASK BIT(5)
+#define RUN_FAIL_MASK BIT(4)
+#define NOISE_FAIL_MASK BIT(3)
+#define STUCK_OUT_MASK BIT(2)
+#define SHUTDOWN_OFLO_MASK BIT(1)
+#define READY_MASK BIT(0)
+
+#define MAJOR_HW_REV_RD(src) (((src) & 0x0f000000) >> 24)
+#define MINOR_HW_REV_RD(src) (((src) & 0x00f00000) >> 20)
+#define HW_PATCH_LEVEL_RD(src) (((src) & 0x000f0000) >> 16)
+#define MAX_REFILL_CYCLES_SET(dst, src) \
+ ((dst & ~0xffff0000) | (((u32)src << 16) & 0xffff0000))
+#define MIN_REFILL_CYCLES_SET(dst, src) \
+ ((dst & ~0x000000ff) | (((u32)src) & 0x000000ff))
+#define ALARM_THRESHOLD_SET(dst, src) \
+ ((dst & ~0x000000ff) | (((u32)src) & 0x000000ff))
+#define ENABLE_RNG_SET(dst, src) \
+ ((dst & ~BIT(10)) | (((u32)src << 10) & BIT(10)))
+#define REGSPEC_TEST_MODE_SET(dst, src) \
+ ((dst & ~BIT(8)) | (((u32)src << 8) & BIT(8)))
+#define MONOBIT_FAIL_MASK_SET(dst, src) \
+ ((dst & ~BIT(7)) | (((u32)src << 7) & BIT(7)))
+#define POKER_FAIL_MASK_SET(dst, src) \
+ ((dst & ~BIT(6)) | (((u32)src << 6) & BIT(6)))
+#define LONG_RUN_FAIL_MASK_SET(dst, src) \
+ ((dst & ~BIT(5)) | (((u32)src << 5) & BIT(5)))
+#define RUN_FAIL_MASK_SET(dst, src) \
+ ((dst & ~BIT(4)) | (((u32)src << 4) & BIT(4)))
+#define NOISE_FAIL_MASK_SET(dst, src) \
+ ((dst & ~BIT(3)) | (((u32)src << 3) & BIT(3)))
+#define STUCK_OUT_MASK_SET(dst, src) \
+ ((dst & ~BIT(2)) | (((u32)src << 2) & BIT(2)))
+#define SHUTDOWN_OFLO_MASK_SET(dst, src) \
+ ((dst & ~BIT(1)) | (((u32)src << 1) & BIT(1)))
+
+struct xgene_rng_dev {
+ u32 irq;
+ void __iomem *csr_base;
+ u32 revision;
+ u32 datum_size;
+ u32 failure_cnt; /* Failure count last minute */
+ unsigned long failure_ts;/* First failure timestamp */
+ struct timer_list failure_timer;
+ struct device *dev;
+ struct clk *clk;
+};
+
+static void xgene_rng_expired_timer(unsigned long arg)
+{
+ struct xgene_rng_dev *ctx = (struct xgene_rng_dev *) arg;
+
+ /* Clear failure counter as timer expired */
+ disable_irq(ctx->irq);
+ ctx->failure_cnt = 0;
+ del_timer(&ctx->failure_timer);
+ enable_irq(ctx->irq);
+}
+
+static void xgene_rng_start_timer(struct xgene_rng_dev *ctx)
+{
+ ctx->failure_timer.data = (unsigned long) ctx;
+ ctx->failure_timer.function = xgene_rng_expired_timer;
+ ctx->failure_timer.expires = jiffies + 120 * HZ;
+ add_timer(&ctx->failure_timer);
+}
+
+/*
+ * Initialize or reinit free running oscillators (FROs)
+ */
+static void xgene_rng_init_fro(struct xgene_rng_dev *ctx, u32 fro_val)
+{
+ writel(fro_val, ctx->csr_base + RNG_FRODETUNE);
+ writel(0x00000000, ctx->csr_base + RNG_ALARMMASK);
+ writel(0x00000000, ctx->csr_base + RNG_ALARMSTOP);
+ writel(0xFFFFFFFF, ctx->csr_base + RNG_FROENABLE);
+}
+
+static void xgene_rng_chk_overflow(struct xgene_rng_dev *ctx)
+{
+ u32 val;
+
+ val = readl(ctx->csr_base + RNG_INTR_STS_ACK);
+ if (val & MONOBIT_FAIL_MASK)
+ /*
+ * LFSR detected an out-of-bounds number of 1s after
+ * checking 20,000 bits (test T1 as specified in the
+ * AIS-31 standard)
+ */
+ dev_err(ctx->dev, "test monobit failure error 0x%08X\n", val);
+ if (val & POKER_FAIL_MASK)
+ /*
+ * LFSR detected an out-of-bounds value in at least one
+ * of the 16 poker_count_X counters or an out of bounds sum
+ * of squares value after checking 20,000 bits (test T2 as
+ * specified in the AIS-31 standard)
+ */
+ dev_err(ctx->dev, "test poker failure error 0x%08X\n", val);
+ if (val & LONG_RUN_FAIL_MASK)
+ /*
+ * LFSR detected a sequence of 34 identical bits
+ * (test T4 as specified in the AIS-31 standard)
+ */
+ dev_err(ctx->dev, "test long run failure error 0x%08X\n", val);
+ if (val & RUN_FAIL_MASK)
+ /*
+ * LFSR detected an outof-bounds value for at least one
+ * of the running counters after checking 20,000 bits
+ * (test T3 as specified in the AIS-31 standard)
+ */
+ dev_err(ctx->dev, "test run failure error 0x%08X\n", val);
+ if (val & NOISE_FAIL_MASK)
+ /* LFSR detected a sequence of 48 identical bits */
+ dev_err(ctx->dev, "noise failure error 0x%08X\n", val);
+ if (val & STUCK_OUT_MASK)
+ /*
+ * Detected output data registers generated same value twice
+ * in a row
+ */
+ dev_err(ctx->dev, "stuck out failure error 0x%08X\n", val);
+
+ if (val & SHUTDOWN_OFLO_MASK) {
+ u32 frostopped;
+
+ /* FROs shut down after a second error event. Try recover. */
+ if (++ctx->failure_cnt == 1) {
+ /* 1st time, just recover */
+ ctx->failure_ts = jiffies;
+ frostopped = readl(ctx->csr_base + RNG_ALARMSTOP);
+ xgene_rng_init_fro(ctx, frostopped);
+
+ /*
+ * We must start a timer to clear out this error
+ * in case the system timer wrap around
+ */
+ xgene_rng_start_timer(ctx);
+ } else {
+ /* 2nd time failure in lesser than 1 minute? */
+ if (time_after(ctx->failure_ts + 60 * HZ, jiffies)) {
+ dev_err(ctx->dev,
+ "FRO shutdown failure error 0x%08X\n",
+ val);
+ } else {
+ /* 2nd time failure after 1 minutes, recover */
+ ctx->failure_ts = jiffies;
+ ctx->failure_cnt = 1;
+ /*
+ * We must start a timer to clear out this
+ * error in case the system timer wrap
+ * around
+ */
+ xgene_rng_start_timer(ctx);
+ }
+ frostopped = readl(ctx->csr_base + RNG_ALARMSTOP);
+ xgene_rng_init_fro(ctx, frostopped);
+ }
+ }
+ /* Clear them all */
+ writel(val, ctx->csr_base + RNG_INTR_STS_ACK);
+}
+
+static irqreturn_t xgene_rng_irq_handler(int irq, void *id)
+{
+ struct xgene_rng_dev *ctx = (struct xgene_rng_dev *) id;
+
+ /* RNG Alarm Counter overflow */
+ xgene_rng_chk_overflow(ctx);
+
+ return IRQ_HANDLED;
+}
+
+static int xgene_rng_data_present(struct hwrng *rng, int wait)
+{
+ struct xgene_rng_dev *ctx = (struct xgene_rng_dev *) rng->priv;
+ u32 i, val = 0;
+
+ for (i = 0; i < XGENE_RNG_RETRY_COUNT; i++) {
+ val = readl(ctx->csr_base + RNG_INTR_STS_ACK);
+ if ((val & READY_MASK) || !wait)
+ break;
+ udelay(XGENE_RNG_RETRY_INTERVAL);
+ }
+
+ return (val & READY_MASK);
+}
+
+static int xgene_rng_data_read(struct hwrng *rng, u32 *data)
+{
+ struct xgene_rng_dev *ctx = (struct xgene_rng_dev *) rng->priv;
+ int i;
+
+ for (i = 0; i < ctx->datum_size; i++)
+ data[i] = readl(ctx->csr_base + RNG_INOUT_0 + i * 4);
+
+ /* Clear ready bit to start next transaction */
+ writel(READY_MASK, ctx->csr_base + RNG_INTR_STS_ACK);
+
+ return ctx->datum_size << 2;
+}
+
+static void xgene_rng_init_internal(struct xgene_rng_dev *ctx)
+{
+ u32 val;
+
+ writel(0x00000000, ctx->csr_base + RNG_CONTROL);
+
+ val = MAX_REFILL_CYCLES_SET(0, 10);
+ val = MIN_REFILL_CYCLES_SET(val, 10);
+ writel(val, ctx->csr_base + RNG_CONFIG);
+
+ val = ALARM_THRESHOLD_SET(0, 0xFF);
+ writel(val, ctx->csr_base + RNG_ALARMCNT);
+
+ xgene_rng_init_fro(ctx, 0);
+
+ writel(MONOBIT_FAIL_MASK |
+ POKER_FAIL_MASK |
+ LONG_RUN_FAIL_MASK |
+ RUN_FAIL_MASK |
+ NOISE_FAIL_MASK |
+ STUCK_OUT_MASK |
+ SHUTDOWN_OFLO_MASK |
+ READY_MASK, ctx->csr_base + RNG_INTR_STS_ACK);
+
+ val = ENABLE_RNG_SET(0, 1);
+ val = MONOBIT_FAIL_MASK_SET(val, 1);
+ val = POKER_FAIL_MASK_SET(val, 1);
+ val = LONG_RUN_FAIL_MASK_SET(val, 1);
+ val = RUN_FAIL_MASK_SET(val, 1);
+ val = NOISE_FAIL_MASK_SET(val, 1);
+ val = STUCK_OUT_MASK_SET(val, 1);
+ val = SHUTDOWN_OFLO_MASK_SET(val, 1);
+ writel(val, ctx->csr_base + RNG_CONTROL);
+}
+
+static int xgene_rng_init(struct hwrng *rng)
+{
+ struct xgene_rng_dev *ctx = (struct xgene_rng_dev *) rng->priv;
+
+ ctx->failure_cnt = 0;
+ init_timer(&ctx->failure_timer);
+
+ ctx->revision = readl(ctx->csr_base + RNG_EIP_REV);
+
+ dev_dbg(ctx->dev, "Rev %d.%d.%d\n",
+ MAJOR_HW_REV_RD(ctx->revision),
+ MINOR_HW_REV_RD(ctx->revision),
+ HW_PATCH_LEVEL_RD(ctx->revision));
+
+ dev_dbg(ctx->dev, "Options 0x%08X",
+ readl(ctx->csr_base + RNG_OPTIONS));
+
+ xgene_rng_init_internal(ctx);
+
+ ctx->datum_size = RNG_MAX_DATUM;
+
+ return 0;
+}
+
+static struct hwrng xgene_rng_func = {
+ .name = "xgene-rng",
+ .init = xgene_rng_init,
+ .data_present = xgene_rng_data_present,
+ .data_read = xgene_rng_data_read,
+};
+
+static int xgene_rng_probe(struct platform_device *pdev)
+{
+ struct resource *res;
+ struct xgene_rng_dev *ctx;
+ int rc = 0;
+
+ ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL);
+ if (!ctx)
+ return -ENOMEM;
+
+ ctx->dev = &pdev->dev;
+ platform_set_drvdata(pdev, ctx);
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ ctx->csr_base = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(ctx->csr_base))
+ return PTR_ERR(ctx->csr_base);
+
+ ctx->irq = platform_get_irq(pdev, 0);
+ if (ctx->irq < 0) {
+ dev_err(&pdev->dev, "No IRQ resource\n");
+ return ctx->irq;
+ }
+
+ dev_dbg(&pdev->dev, "APM X-Gene RNG BASE %p ALARM IRQ %d",
+ ctx->csr_base, ctx->irq);
+
+ rc = devm_request_irq(&pdev->dev, ctx->irq, xgene_rng_irq_handler, 0,
+ dev_name(&pdev->dev), ctx);
+ if (rc) {
+ dev_err(&pdev->dev, "Could not request RNG alarm IRQ\n");
+ return rc;
+ }
+
+ /* Enable IP clock */
+ ctx->clk = devm_clk_get(&pdev->dev, NULL);
+ if (IS_ERR(ctx->clk)) {
+ dev_warn(&pdev->dev, "Couldn't get the clock for RNG\n");
+ } else {
+ rc = clk_prepare_enable(ctx->clk);
+ if (rc) {
+ dev_warn(&pdev->dev,
+ "clock prepare enable failed for RNG");
+ return rc;
+ }
+ }
+
+ xgene_rng_func.priv = (unsigned long) ctx;
+
+ rc = hwrng_register(&xgene_rng_func);
+ if (rc) {
+ dev_err(&pdev->dev, "RNG registering failed error %d\n", rc);
+ if (!IS_ERR(ctx->clk))
+ clk_disable_unprepare(ctx->clk);
+ return rc;
+ }
+
+ rc = device_init_wakeup(&pdev->dev, 1);
+ if (rc) {
+ dev_err(&pdev->dev, "RNG device_init_wakeup failed error %d\n",
+ rc);
+ if (!IS_ERR(ctx->clk))
+ clk_disable_unprepare(ctx->clk);
+ hwrng_unregister(&xgene_rng_func);
+ return rc;
+ }
+
+ return 0;
+}
+
+static int xgene_rng_remove(struct platform_device *pdev)
+{
+ struct xgene_rng_dev *ctx = platform_get_drvdata(pdev);
+ int rc;
+
+ rc = device_init_wakeup(&pdev->dev, 0);
+ if (rc)
+ dev_err(&pdev->dev, "RNG init wakeup failed error %d\n", rc);
+ if (!IS_ERR(ctx->clk))
+ clk_disable_unprepare(ctx->clk);
+ hwrng_unregister(&xgene_rng_func);
+
+ return rc;
+}
+
+static const struct of_device_id xgene_rng_of_match[] = {
+ { .compatible = "apm,xgene-rng" },
+ { }
+};
+
+MODULE_DEVICE_TABLE(of, xgene_rng_of_match);
+
+static struct platform_driver xgene_rng_driver = {
+ .probe = xgene_rng_probe,
+ .remove = xgene_rng_remove,
+ .driver = {
+ .name = "xgene-rng",
+ .of_match_table = xgene_rng_of_match,
+ },
+};
+
+module_platform_driver(xgene_rng_driver);
+MODULE_DESCRIPTION("APM X-Gene RNG driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/crypto/caam/caamhash.c b/drivers/crypto/caam/caamhash.c
index b464d03ebf40..f347ab7eea95 100644
--- a/drivers/crypto/caam/caamhash.c
+++ b/drivers/crypto/caam/caamhash.c
@@ -836,8 +836,9 @@ static int ahash_update_ctx(struct ahash_request *req)
edesc->sec4_sg + sec4_sg_src_index,
chained);
if (*next_buflen) {
- sg_copy_part(next_buf, req->src, to_hash -
- *buflen, req->nbytes);
+ scatterwalk_map_and_copy(next_buf, req->src,
+ to_hash - *buflen,
+ *next_buflen, 0);
state->current_buf = !state->current_buf;
}
} else {
@@ -878,7 +879,8 @@ static int ahash_update_ctx(struct ahash_request *req)
kfree(edesc);
}
} else if (*next_buflen) {
- sg_copy(buf + *buflen, req->src, req->nbytes);
+ scatterwalk_map_and_copy(buf + *buflen, req->src, 0,
+ req->nbytes, 0);
*buflen = *next_buflen;
*next_buflen = last_buflen;
}
@@ -1262,8 +1264,9 @@ static int ahash_update_no_ctx(struct ahash_request *req)
src_map_to_sec4_sg(jrdev, req->src, src_nents,
edesc->sec4_sg + 1, chained);
if (*next_buflen) {
- sg_copy_part(next_buf, req->src, to_hash - *buflen,
- req->nbytes);
+ scatterwalk_map_and_copy(next_buf, req->src,
+ to_hash - *buflen,
+ *next_buflen, 0);
state->current_buf = !state->current_buf;
}
@@ -1304,7 +1307,8 @@ static int ahash_update_no_ctx(struct ahash_request *req)
kfree(edesc);
}
} else if (*next_buflen) {
- sg_copy(buf + *buflen, req->src, req->nbytes);
+ scatterwalk_map_and_copy(buf + *buflen, req->src, 0,
+ req->nbytes, 0);
*buflen = *next_buflen;
*next_buflen = 0;
}
@@ -1413,9 +1417,9 @@ static int ahash_update_first(struct ahash_request *req)
struct device *jrdev = ctx->jrdev;
gfp_t flags = (req->base.flags & (CRYPTO_TFM_REQ_MAY_BACKLOG |
CRYPTO_TFM_REQ_MAY_SLEEP)) ? GFP_KERNEL : GFP_ATOMIC;
- u8 *next_buf = state->buf_0 + state->current_buf *
- CAAM_MAX_HASH_BLOCK_SIZE;
- int *next_buflen = &state->buflen_0 + state->current_buf;
+ u8 *next_buf = state->current_buf ? state->buf_1 : state->buf_0;
+ int *next_buflen = state->current_buf ?
+ &state->buflen_1 : &state->buflen_0;
int to_hash;
u32 *sh_desc = ctx->sh_desc_update_first, *desc;
dma_addr_t ptr = ctx->sh_desc_update_first_dma;
@@ -1476,7 +1480,8 @@ static int ahash_update_first(struct ahash_request *req)
}
if (*next_buflen)
- sg_copy_part(next_buf, req->src, to_hash, req->nbytes);
+ scatterwalk_map_and_copy(next_buf, req->src, to_hash,
+ *next_buflen, 0);
sh_len = desc_len(sh_desc);
desc = edesc->hw_desc;
@@ -1511,7 +1516,8 @@ static int ahash_update_first(struct ahash_request *req)
state->update = ahash_update_no_ctx;
state->finup = ahash_finup_no_ctx;
state->final = ahash_final_no_ctx;
- sg_copy(next_buf, req->src, req->nbytes);
+ scatterwalk_map_and_copy(next_buf, req->src, 0,
+ req->nbytes, 0);
}
#ifdef DEBUG
print_hex_dump(KERN_ERR, "next buf@"__stringify(__LINE__)": ",
diff --git a/drivers/crypto/caam/ctrl.c b/drivers/crypto/caam/ctrl.c
index 3cade79ea41e..c6210373b1be 100644
--- a/drivers/crypto/caam/ctrl.c
+++ b/drivers/crypto/caam/ctrl.c
@@ -355,10 +355,19 @@ static void kick_trng(struct platform_device *pdev, int ent_delay)
wr_reg32(&r4tst->rtsdctl, val);
/* min. freq. count, equal to 1/4 of the entropy sample length */
wr_reg32(&r4tst->rtfrqmin, ent_delay >> 2);
- /* max. freq. count, equal to 8 times the entropy sample length */
- wr_reg32(&r4tst->rtfrqmax, ent_delay << 3);
+ /* disable maximum frequency count */
+ wr_reg32(&r4tst->rtfrqmax, RTFRQMAX_DISABLE);
+ /* read the control register */
+ val = rd_reg32(&r4tst->rtmctl);
+ /*
+ * select raw sampling in both entropy shifter
+ * and statistical checker
+ */
+ setbits32(&val, RTMCTL_SAMP_MODE_RAW_ES_SC);
/* put RNG4 into run mode */
- clrbits32(&r4tst->rtmctl, RTMCTL_PRGM);
+ clrbits32(&val, RTMCTL_PRGM);
+ /* write back the control register */
+ wr_reg32(&r4tst->rtmctl, val);
}
/**
@@ -544,6 +553,9 @@ static int caam_probe(struct platform_device *pdev)
* the TRNG parameters.
*/
if (!(ctrlpriv->rng4_sh_init || inst_handles)) {
+ dev_info(dev,
+ "Entropy delay = %u\n",
+ ent_delay);
kick_trng(pdev, ent_delay);
ent_delay += 400;
}
@@ -556,6 +568,12 @@ static int caam_probe(struct platform_device *pdev)
*/
ret = instantiate_rng(dev, inst_handles,
gen_sk);
+ if (ret == -EAGAIN)
+ /*
+ * if here, the loop will rerun,
+ * so don't hog the CPU
+ */
+ cpu_relax();
} while ((ret == -EAGAIN) && (ent_delay < RTSDCTL_ENT_DLY_MAX));
if (ret) {
dev_err(dev, "failed to instantiate RNG");
diff --git a/drivers/crypto/caam/regs.h b/drivers/crypto/caam/regs.h
index f48e344ffc39..bc9cd62b96e0 100644
--- a/drivers/crypto/caam/regs.h
+++ b/drivers/crypto/caam/regs.h
@@ -269,6 +269,16 @@ struct rngtst {
/* RNG4 TRNG test registers */
struct rng4tst {
#define RTMCTL_PRGM 0x00010000 /* 1 -> program mode, 0 -> run mode */
+#define RTMCTL_SAMP_MODE_VON_NEUMANN_ES_SC 0 /* use von Neumann data in
+ both entropy shifter and
+ statistical checker */
+#define RTMCTL_SAMP_MODE_RAW_ES_SC 1 /* use raw data in both
+ entropy shifter and
+ statistical checker */
+#define RTMCTL_SAMP_MODE_VON_NEUMANN_ES_RAW_SC 2 /* use von Neumann data in
+ entropy shifter, raw data
+ in statistical checker */
+#define RTMCTL_SAMP_MODE_INVALID 3 /* invalid combination */
u32 rtmctl; /* misc. control register */
u32 rtscmisc; /* statistical check misc. register */
u32 rtpkrrng; /* poker range register */
@@ -278,7 +288,7 @@ struct rng4tst {
};
#define RTSDCTL_ENT_DLY_SHIFT 16
#define RTSDCTL_ENT_DLY_MASK (0xffff << RTSDCTL_ENT_DLY_SHIFT)
-#define RTSDCTL_ENT_DLY_MIN 1200
+#define RTSDCTL_ENT_DLY_MIN 3200
#define RTSDCTL_ENT_DLY_MAX 12800
u32 rtsdctl; /* seed control register */
union {
@@ -286,6 +296,7 @@ struct rng4tst {
u32 rttotsam; /* PRGM=0: total samples register */
};
u32 rtfrqmin; /* frequency count min. limit register */
+#define RTFRQMAX_DISABLE (1 << 20)
union {
u32 rtfrqmax; /* PRGM=1: freq. count max. limit register */
u32 rtfrqcnt; /* PRGM=0: freq. count register */
diff --git a/drivers/crypto/caam/sg_sw_sec4.h b/drivers/crypto/caam/sg_sw_sec4.h
index b12ff85f4241..ce28a563effc 100644
--- a/drivers/crypto/caam/sg_sw_sec4.h
+++ b/drivers/crypto/caam/sg_sw_sec4.h
@@ -116,57 +116,3 @@ static int dma_unmap_sg_chained(struct device *dev, struct scatterlist *sg,
}
return nents;
}
-
-/* Map SG page in kernel virtual address space and copy */
-static inline void sg_map_copy(u8 *dest, struct scatterlist *sg,
- int len, int offset)
-{
- u8 *mapped_addr;
-
- /*
- * Page here can be user-space pinned using get_user_pages
- * Same must be kmapped before use and kunmapped subsequently
- */
- mapped_addr = kmap_atomic(sg_page(sg));
- memcpy(dest, mapped_addr + offset, len);
- kunmap_atomic(mapped_addr);
-}
-
-/* Copy from len bytes of sg to dest, starting from beginning */
-static inline void sg_copy(u8 *dest, struct scatterlist *sg, unsigned int len)
-{
- struct scatterlist *current_sg = sg;
- int cpy_index = 0, next_cpy_index = current_sg->length;
-
- while (next_cpy_index < len) {
- sg_map_copy(dest + cpy_index, current_sg, current_sg->length,
- current_sg->offset);
- current_sg = scatterwalk_sg_next(current_sg);
- cpy_index = next_cpy_index;
- next_cpy_index += current_sg->length;
- }
- if (cpy_index < len)
- sg_map_copy(dest + cpy_index, current_sg, len-cpy_index,
- current_sg->offset);
-}
-
-/* Copy sg data, from to_skip to end, to dest */
-static inline void sg_copy_part(u8 *dest, struct scatterlist *sg,
- int to_skip, unsigned int end)
-{
- struct scatterlist *current_sg = sg;
- int sg_index, cpy_index, offset;
-
- sg_index = current_sg->length;
- while (sg_index <= to_skip) {
- current_sg = scatterwalk_sg_next(current_sg);
- sg_index += current_sg->length;
- }
- cpy_index = sg_index - to_skip;
- offset = current_sg->offset + current_sg->length - cpy_index;
- sg_map_copy(dest, current_sg, cpy_index, offset);
- if (end - sg_index) {
- current_sg = scatterwalk_sg_next(current_sg);
- sg_copy(dest + cpy_index, current_sg, end - sg_index);
- }
-}
diff --git a/drivers/crypto/mv_cesa.h b/drivers/crypto/mv_cesa.h
index 08fcb1116d90..9249d3ed184b 100644
--- a/drivers/crypto/mv_cesa.h
+++ b/drivers/crypto/mv_cesa.h
@@ -1,4 +1,5 @@
#ifndef __MV_CRYPTO_H__
+#define __MV_CRYPTO_H__
#define DIGEST_INITIAL_VAL_A 0xdd00
#define DIGEST_INITIAL_VAL_B 0xdd04
diff --git a/drivers/crypto/qat/qat_common/adf_ctl_drv.c b/drivers/crypto/qat/qat_common/adf_ctl_drv.c
index d97069b8a8e4..6f7816e2c421 100644
--- a/drivers/crypto/qat/qat_common/adf_ctl_drv.c
+++ b/drivers/crypto/qat/qat_common/adf_ctl_drv.c
@@ -111,7 +111,7 @@ static int adf_chr_drv_create(void)
drv_device = device_create(adt_ctl_drv.drv_class, NULL,
MKDEV(adt_ctl_drv.major, 0),
NULL, DEVICE_NAME);
- if (!drv_device) {
+ if (IS_ERR(drv_device)) {
pr_err("QAT: failed to create device\n");
goto err_cdev_del;
}
diff --git a/drivers/crypto/qat/qat_dh895xcc/adf_isr.c b/drivers/crypto/qat/qat_dh895xcc/adf_isr.c
index d4172dedf775..1082e3b8a5d6 100644
--- a/drivers/crypto/qat/qat_dh895xcc/adf_isr.c
+++ b/drivers/crypto/qat/qat_dh895xcc/adf_isr.c
@@ -70,9 +70,9 @@ static int adf_enable_msix(struct adf_accel_dev *accel_dev)
for (i = 0; i < msix_num_entries; i++)
pci_dev_info->msix_entries.entries[i].entry = i;
- if (pci_enable_msix(pci_dev_info->pci_dev,
- pci_dev_info->msix_entries.entries,
- msix_num_entries)) {
+ if (pci_enable_msix_exact(pci_dev_info->pci_dev,
+ pci_dev_info->msix_entries.entries,
+ msix_num_entries)) {
pr_err("QAT: Failed to enable MSIX IRQ\n");
return -EFAULT;
}
OpenPOWER on IntegriCloud