From b22da3d8526a935aa31e086e63f60ff3246cb61c Mon Sep 17 00:00:00 2001 From: hc <hc@nodka.com> Date: Sat, 09 Dec 2023 07:24:11 +0000 Subject: [PATCH] add stmac read mac form eeprom --- kernel/drivers/char/hw_random/rockchip-rng.c | 157 +++++++++++++++++++++++++++++++++++++++------------- 1 files changed, 118 insertions(+), 39 deletions(-) diff --git a/kernel/drivers/char/hw_random/rockchip-rng.c b/kernel/drivers/char/hw_random/rockchip-rng.c index 08ad081..f7a3a7f 100644 --- a/kernel/drivers/char/hw_random/rockchip-rng.c +++ b/kernel/drivers/char/hw_random/rockchip-rng.c @@ -87,6 +87,27 @@ #define TRNG_v1_VERSION_CODE 0x46bc /* end of TRNG_V1 register define */ +/* start of RKRNG register define */ +#define RKRNG_CTRL 0x0010 +#define RKRNG_CTRL_INST_REQ BIT(0) +#define RKRNG_CTRL_RESEED_REQ BIT(1) +#define RKRNG_CTRL_TEST_REQ BIT(2) +#define RKRNG_CTRL_SW_DRNG_REQ BIT(3) +#define RKRNG_CTRL_SW_TRNG_REQ BIT(4) + +#define RKRNG_STATE 0x0014 +#define RKRNG_STATE_INST_ACK BIT(0) +#define RKRNG_STATE_RESEED_ACK BIT(1) +#define RKRNG_STATE_TEST_ACK BIT(2) +#define RKRNG_STATE_SW_DRNG_ACK BIT(3) +#define RKRNG_STATE_SW_TRNG_ACK BIT(4) + +/* DRNG_DATA_0 ~ DNG_DATA_7 */ +#define RKRNG_DRNG_DATA_0 0x0070 +#define RKRNG_DRNG_DATA_7 0x008C + +/* end of RKRNG register define */ + struct rk_rng_soc_data { u32 default_offset; @@ -178,7 +199,7 @@ *(u32 *)(buf + i) = be32_to_cpu(rk_rng_readl(rng, offset + i)); } -static int rk_crypto_v1_read(struct hwrng *rng, void *buf, size_t max, bool wait) +static int crypto_v1_read(struct hwrng *rng, void *buf, size_t max, bool wait) { int ret = 0; u32 reg_ctrl = 0; @@ -192,10 +213,12 @@ rk_rng_writel(rk_rng, reg_ctrl, CRYPTO_V1_CTRL); - ret = readl_poll_timeout(rk_rng->mem + CRYPTO_V1_CTRL, reg_ctrl, - !(reg_ctrl & CRYPTO_V1_RNG_START), - ROCKCHIP_POLL_PERIOD_US, - ROCKCHIP_POLL_TIMEOUT_US); + ret = read_poll_timeout(rk_rng_readl, reg_ctrl, + !(reg_ctrl & CRYPTO_V1_RNG_START), + ROCKCHIP_POLL_PERIOD_US, + ROCKCHIP_POLL_TIMEOUT_US, false, + rk_rng, CRYPTO_V1_CTRL); + if (ret < 0) goto out; @@ -211,7 +234,7 @@ return ret; } -static int rk_crypto_v2_read(struct hwrng *rng, void *buf, size_t max, bool wait) +static int crypto_v2_read(struct hwrng *rng, void *buf, size_t max, bool wait) { int ret = 0; u32 reg_ctrl = 0; @@ -228,10 +251,11 @@ rk_rng_writel(rk_rng, HIWORD_UPDATE(reg_ctrl, 0xffff, 0), CRYPTO_V2_RNG_CTL); - ret = readl_poll_timeout(rk_rng->mem + CRYPTO_V2_RNG_CTL, reg_ctrl, - !(reg_ctrl & CRYPTO_V2_RNG_START), - ROCKCHIP_POLL_PERIOD_US, - ROCKCHIP_POLL_TIMEOUT_US); + ret = read_poll_timeout(rk_rng_readl, reg_ctrl, + !(reg_ctrl & CRYPTO_V2_RNG_START), + ROCKCHIP_POLL_PERIOD_US, + ROCKCHIP_POLL_TIMEOUT_US, false, + rk_rng, CRYPTO_V2_RNG_CTL); if (ret < 0) goto out; @@ -246,18 +270,12 @@ return ret; } -static int rk_trng_v1_init(struct hwrng *rng) +static int trng_v1_init(struct hwrng *rng) { int ret; uint32_t auto_reseed_cnt = 1000; uint32_t reg_ctrl, status, version; struct rk_rng *rk_rng = container_of(rng, struct rk_rng, rng); - - ret = pm_runtime_get_sync(rk_rng->dev); - if (ret < 0) { - pm_runtime_put_noidle(rk_rng->dev); - return ret; - } version = rk_rng_readl(rk_rng, TRNG_V1_VERSION); if (version != TRNG_v1_VERSION_CODE) { @@ -281,10 +299,11 @@ udelay(10); /* wait for GENERATING and RESEEDING flag to clear */ - readl_poll_timeout(rk_rng->mem + TRNG_V1_STAT, reg_ctrl, - (reg_ctrl & mask) == TRNG_V1_STAT_SEEDED, - ROCKCHIP_POLL_PERIOD_US, - ROCKCHIP_POLL_TIMEOUT_US); + read_poll_timeout(rk_rng_readl, reg_ctrl, + (reg_ctrl & mask) == TRNG_V1_STAT_SEEDED, + ROCKCHIP_POLL_PERIOD_US, + ROCKCHIP_POLL_TIMEOUT_US, false, + rk_rng, TRNG_V1_STAT); } /* clear ISTAT flag because trng may auto reseeding when power on */ @@ -296,13 +315,11 @@ ret = 0; exit: - pm_runtime_mark_last_busy(rk_rng->dev); - pm_runtime_put_sync_autosuspend(rk_rng->dev); return ret; } -static int rk_trng_v1_read(struct hwrng *rng, void *buf, size_t max, bool wait) +static int trng_v1_read(struct hwrng *rng, void *buf, size_t max, bool wait) { int ret = 0; u32 reg_ctrl = 0; @@ -324,10 +341,11 @@ reg_ctrl = rk_rng_readl(rk_rng, TRNG_V1_ISTAT); if (!(reg_ctrl & TRNG_V1_ISTAT_RAND_RDY)) { /* wait RAND_RDY triggered */ - ret = readl_poll_timeout(rk_rng->mem + TRNG_V1_ISTAT, reg_ctrl, - (reg_ctrl & TRNG_V1_ISTAT_RAND_RDY), - ROCKCHIP_POLL_PERIOD_US, - ROCKCHIP_POLL_TIMEOUT_US); + ret = read_poll_timeout(rk_rng_readl, reg_ctrl, + (reg_ctrl & TRNG_V1_ISTAT_RAND_RDY), + ROCKCHIP_POLL_PERIOD_US, + ROCKCHIP_POLL_TIMEOUT_US, false, + rk_rng, TRNG_V1_ISTAT); if (ret < 0) goto out; } @@ -345,37 +363,92 @@ return ret; } -static const struct rk_rng_soc_data rk_crypto_v1_soc_data = { +static int rkrng_init(struct hwrng *rng) +{ + struct rk_rng *rk_rng = container_of(rng, struct rk_rng, rng); + u32 reg = 0; + + rk_rng_writel(rk_rng, HIWORD_UPDATE(0, 0xffff, 0), RKRNG_CTRL); + + reg = rk_rng_readl(rk_rng, RKRNG_STATE); + rk_rng_writel(rk_rng, reg, RKRNG_STATE); + + return 0; +} + +static int rkrng_read(struct hwrng *rng, void *buf, size_t max, bool wait) +{ + struct rk_rng *rk_rng = container_of(rng, struct rk_rng, rng); + u32 reg_ctrl = 0; + int ret; + + reg_ctrl = RKRNG_CTRL_SW_DRNG_REQ; + + rk_rng_writel(rk_rng, HIWORD_UPDATE(reg_ctrl, 0xffff, 0), RKRNG_CTRL); + + ret = readl_poll_timeout(rk_rng->mem + RKRNG_STATE, reg_ctrl, + (reg_ctrl & RKRNG_STATE_SW_DRNG_ACK), + ROCKCHIP_POLL_PERIOD_US, + ROCKCHIP_POLL_TIMEOUT_US); + + if (ret) + goto exit; + + rk_rng_writel(rk_rng, reg_ctrl, RKRNG_STATE); + + ret = min_t(size_t, max, RK_MAX_RNG_BYTE); + + rk_rng_read_regs(rk_rng, RKRNG_DRNG_DATA_0, buf, ret); + +exit: + /* close TRNG */ + rk_rng_writel(rk_rng, HIWORD_UPDATE(0, 0xffff, 0), RKRNG_CTRL); + + return ret; +} + +static const struct rk_rng_soc_data crypto_v1_soc_data = { .default_offset = 0, - .rk_rng_read = rk_crypto_v1_read, + .rk_rng_read = crypto_v1_read, }; -static const struct rk_rng_soc_data rk_crypto_v2_soc_data = { +static const struct rk_rng_soc_data crypto_v2_soc_data = { .default_offset = CRYPTO_V2_RNG_DEFAULT_OFFSET, - .rk_rng_read = rk_crypto_v2_read, + .rk_rng_read = crypto_v2_read, }; -static const struct rk_rng_soc_data rk_trng_v1_soc_data = { +static const struct rk_rng_soc_data trng_v1_soc_data = { .default_offset = 0, - .rk_rng_init = rk_trng_v1_init, - .rk_rng_read = rk_trng_v1_read, + .rk_rng_init = trng_v1_init, + .rk_rng_read = trng_v1_read, +}; + +static const struct rk_rng_soc_data rkrng_soc_data = { + .default_offset = 0, + + .rk_rng_init = rkrng_init, + .rk_rng_read = rkrng_read, }; static const struct of_device_id rk_rng_dt_match[] = { { .compatible = "rockchip,cryptov1-rng", - .data = (void *)&rk_crypto_v1_soc_data, + .data = (void *)&crypto_v1_soc_data, }, { .compatible = "rockchip,cryptov2-rng", - .data = (void *)&rk_crypto_v2_soc_data, + .data = (void *)&crypto_v2_soc_data, }, { .compatible = "rockchip,trngv1", - .data = (void *)&rk_trng_v1_soc_data, + .data = (void *)&trng_v1_soc_data, + }, + { + .compatible = "rockchip,rkrng", + .data = (void *)&rkrng_soc_data, }, { }, }; @@ -445,9 +518,15 @@ } /* for some platform need hardware operation when probe */ - if (rk_rng->soc_data->rk_rng_init) + if (rk_rng->soc_data->rk_rng_init) { + pm_runtime_get_sync(rk_rng->dev); + ret = rk_rng->soc_data->rk_rng_init(&rk_rng->rng); + pm_runtime_mark_last_busy(rk_rng->dev); + pm_runtime_put_sync_autosuspend(rk_rng->dev); + } + return ret; } -- Gitblit v1.6.2