提交 bdd39050 编写于 作者: Y Yu'an Wang 提交者: Yang Yingliang

hwrng: add data_mode to support rand data with post process

driver inclusion
category: Feature
bugzilla: NA
CVE: NA

In this patch, provide data_mode para to support rand data with post
process, such as sm3 and poker test.
Signed-off-by: NYu'an Wang <wangyuan46@huawei.com>
Reviewed-by: NWeili Qian <qianweili@huawei.com>
Signed-off-by: NYang Yingliang <yangyingliang@huawei.com>
上级 6fe37e8d
...@@ -10,18 +10,79 @@ ...@@ -10,18 +10,79 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/random.h> #include <linux/random.h>
#include <linux/arm-smccc.h>
#define HISI_TRNG_SMC_CMD 0x83000109
#define HISI_TRNG_SMC_BYTES 32
#define HISI_TRNG_REG 0x00F0 #define HISI_TRNG_REG 0x00F0
#define HISI_TRNG_BYTES 4 #define HISI_TRNG_BYTES 4
#define HISI_TRNG_QUALITY 512 #define HISI_TRNG_QUALITY 512
#define SLEEP_US 10 #define SLEEP_US 10
#define TIMEOUT_US 10000 #define TIMEOUT_US 10000
#define RAND_DATA_NORMAL 0
#define RAND_DATA_POSTPRO 1
struct hisi_trng { struct hisi_trng {
void __iomem *base; void __iomem *base;
struct hwrng rng; struct hwrng rng;
void *va;
phys_addr_t pa;
}; };
static int data_mode_set(const char *val, const struct kernel_param *kp)
{
u32 n;
int ret;
if (!val)
return -EINVAL;
ret = kstrtou32(val, 10, &n);
if (ret < 0 || (n != RAND_DATA_NORMAL && n != RAND_DATA_POSTPRO))
return -EINVAL;
return param_set_int(val, kp);
}
static const struct kernel_param_ops data_mode_ops = {
.set = data_mode_set,
.get = param_get_int,
};
static int data_mode = RAND_DATA_NORMAL;
module_param_cb(data_mode, &data_mode_ops, &data_mode, 0444);
MODULE_PARM_DESC(data_mode, "Rand data with post process or not, 0(default), 1");
static int hisi_trng_read_v2(struct hwrng *rng, void *buf, size_t max,
bool wait)
{
struct arm_smccc_res res = {0};
struct hisi_trng *trng;
int currsize = 0;
trng = container_of(rng, struct hisi_trng, rng);
do {
arm_smccc_smc(HISI_TRNG_SMC_CMD, trng->pa, 0, 0, 0, 0, 0, 0,
&res);
if (res.a0)
return currsize;
if (max - currsize >= HISI_TRNG_SMC_BYTES) {
memcpy(buf + currsize, trng->va, HISI_TRNG_SMC_BYTES);
currsize += HISI_TRNG_SMC_BYTES;
if (currsize == max)
return currsize;
continue;
}
memcpy(buf + currsize, trng->va, max - currsize);
currsize = max;
} while (currsize < max);
return currsize;
}
static int hisi_trng_read(struct hwrng *rng, void *buf, size_t max, bool wait) static int hisi_trng_read(struct hwrng *rng, void *buf, size_t max, bool wait)
{ {
struct hisi_trng *trng; struct hisi_trng *trng;
...@@ -69,9 +130,19 @@ static int hisi_trng_probe(struct platform_device *pdev) ...@@ -69,9 +130,19 @@ static int hisi_trng_probe(struct platform_device *pdev)
return PTR_ERR(trng->base); return PTR_ERR(trng->base);
trng->rng.name = pdev->name; trng->rng.name = pdev->name;
trng->rng.read = hisi_trng_read;
trng->rng.quality = HISI_TRNG_QUALITY; trng->rng.quality = HISI_TRNG_QUALITY;
if (data_mode) {
trng->rng.read = hisi_trng_read_v2;
trng->va = devm_kzalloc(&pdev->dev, HISI_TRNG_SMC_BYTES,
GFP_KERNEL);
if (!trng->va)
return -ENOMEM;
trng->pa = virt_to_phys(trng->va);
} else
trng->rng.read = hisi_trng_read;
ret = devm_hwrng_register(&pdev->dev, &trng->rng); ret = devm_hwrng_register(&pdev->dev, &trng->rng);
if (ret) if (ret)
dev_err(&pdev->dev, "failed to register hwrng!\n"); dev_err(&pdev->dev, "failed to register hwrng!\n");
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册