hwrng: ks-sa - Add minimum sleep time before ready-polling
Current polling timeout is 25 us. The hardware is currently configured to harvest the entropy for 81920 us. This leads to timeouts even during blocking read (wait=1). Log snippet: [ 5.727589] [<c040ffcc>] (ks_sa_rng_probe) from [<c04181e8>] (platform_drv_probe+0x58/0xb4) ... [ 5.727805] hwrng: no data available ... [ 13.157016] random: systemd: uninitialized urandom read (16 bytes read) [ 13.157033] systemd[1]: Initializing machine ID from random generator. ... [ 15.848770] random: fast init done ... [ 15.848807] random: crng init done After the patch: [ 6.223534] random: systemd: uninitialized urandom read (16 bytes read) [ 6.223551] systemd[1]: Initializing machine ID from random generator. ... [ 6.876075] random: fast init done ... [ 6.954200] random: systemd: uninitialized urandom read (16 bytes read) [ 6.955244] random: systemd: uninitialized urandom read (16 bytes read) ... [ 7.121948] random: crng init done Signed-off-by: Alexander Sverdlin <alexander.sverdlin@nokia.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
This commit is contained in:
parent
698b22273e
commit
6d01d8511d
|
@ -21,6 +21,7 @@
|
|||
#include <linux/of.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/timekeeping.h>
|
||||
|
||||
#define SA_CMD_STATUS_OFS 0x8
|
||||
|
||||
|
@ -85,13 +86,36 @@ struct ks_sa_rng {
|
|||
struct clk *clk;
|
||||
struct regmap *regmap_cfg;
|
||||
struct trng_regs __iomem *reg_rng;
|
||||
u64 ready_ts;
|
||||
unsigned int refill_delay_ns;
|
||||
};
|
||||
|
||||
static unsigned int cycles_to_ns(unsigned long clk_rate, unsigned int cycles)
|
||||
{
|
||||
return DIV_ROUND_UP_ULL((TRNG_DEF_CLK_DIV_CYCLES + 1) * 1000000000ull *
|
||||
cycles, clk_rate);
|
||||
}
|
||||
|
||||
static unsigned int startup_delay_ns(unsigned long clk_rate)
|
||||
{
|
||||
if (!TRNG_DEF_STARTUP_CYCLES)
|
||||
return cycles_to_ns(clk_rate, BIT(24));
|
||||
return cycles_to_ns(clk_rate, 256 * TRNG_DEF_STARTUP_CYCLES);
|
||||
}
|
||||
|
||||
static unsigned int refill_delay_ns(unsigned long clk_rate)
|
||||
{
|
||||
if (!TRNG_DEF_MAX_REFILL_CYCLES)
|
||||
return cycles_to_ns(clk_rate, BIT(24));
|
||||
return cycles_to_ns(clk_rate, 256 * TRNG_DEF_MAX_REFILL_CYCLES);
|
||||
}
|
||||
|
||||
static int ks_sa_rng_init(struct hwrng *rng)
|
||||
{
|
||||
u32 value;
|
||||
struct device *dev = (struct device *)rng->priv;
|
||||
struct ks_sa_rng *ks_sa_rng = dev_get_drvdata(dev);
|
||||
unsigned long clk_rate = clk_get_rate(ks_sa_rng->clk);
|
||||
|
||||
/* Enable RNG module */
|
||||
regmap_write_bits(ks_sa_rng->regmap_cfg, SA_CMD_STATUS_OFS,
|
||||
|
@ -120,6 +144,10 @@ static int ks_sa_rng_init(struct hwrng *rng)
|
|||
value |= TRNG_CNTL_REG_TRNG_ENABLE;
|
||||
writel(value, &ks_sa_rng->reg_rng->control);
|
||||
|
||||
ks_sa_rng->refill_delay_ns = refill_delay_ns(clk_rate);
|
||||
ks_sa_rng->ready_ts = ktime_get_ns() +
|
||||
startup_delay_ns(clk_rate);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -144,6 +172,7 @@ static int ks_sa_rng_data_read(struct hwrng *rng, u32 *data)
|
|||
data[1] = readl(&ks_sa_rng->reg_rng->output_h);
|
||||
|
||||
writel(TRNG_INTACK_REG_READY, &ks_sa_rng->reg_rng->intack);
|
||||
ks_sa_rng->ready_ts = ktime_get_ns() + ks_sa_rng->refill_delay_ns;
|
||||
|
||||
return sizeof(u32) * 2;
|
||||
}
|
||||
|
@ -152,10 +181,19 @@ static int ks_sa_rng_data_present(struct hwrng *rng, int wait)
|
|||
{
|
||||
struct device *dev = (struct device *)rng->priv;
|
||||
struct ks_sa_rng *ks_sa_rng = dev_get_drvdata(dev);
|
||||
u64 now = ktime_get_ns();
|
||||
|
||||
u32 ready;
|
||||
int j;
|
||||
|
||||
if (wait && now < ks_sa_rng->ready_ts) {
|
||||
/* Max delay expected here is 81920000 ns */
|
||||
unsigned long min_delay =
|
||||
DIV_ROUND_UP((u32)(ks_sa_rng->ready_ts - now), 1000);
|
||||
|
||||
usleep_range(min_delay, min_delay + SA_RNG_DATA_RETRY_DELAY);
|
||||
}
|
||||
|
||||
for (j = 0; j < SA_MAX_RNG_DATA_RETRIES; j++) {
|
||||
ready = readl(&ks_sa_rng->reg_rng->status);
|
||||
ready &= TRNG_STATUS_REG_READY;
|
||||
|
|
Loading…
Reference in New Issue