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);
}
staticint 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);
}
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);
}
rc = devm_request_irq(&pdev->dev, ctx->irq, xgene_rng_irq_handler, 0,
dev_name(&pdev->dev), ctx); if (rc) return dev_err_probe(&pdev->dev, rc, "Could not request RNG alarm IRQ\n");
/* Enable IP clock */
clk = devm_clk_get_optional_enabled(&pdev->dev, NULL); if (IS_ERR(clk)) return dev_err_probe(&pdev->dev, PTR_ERR(clk), "Couldn't get the clock for RNG\n");
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.