* [PATCH] hwrng: Add TX4939 RNG driver
@ 2009-05-26 15:02 Atsushi Nemoto
2009-05-29 23:29 ` Andrew Morton
0 siblings, 1 reply; 8+ messages in thread
From: Atsushi Nemoto @ 2009-05-26 15:02 UTC (permalink / raw)
To: linux-mips; +Cc: ralf, linux-kernel
This patch adds support for the integrated RNG of the TX4939 SoC.
Signed-off-by: Atsushi Nemoto <anemo@mba.ocn.ne.jp>
---
drivers/char/hw_random/Kconfig | 13 +++
drivers/char/hw_random/Makefile | 1 +
drivers/char/hw_random/tx4939-rng.c | 157 +++++++++++++++++++++++++++++++++++
3 files changed, 171 insertions(+), 0 deletions(-)
create mode 100644 drivers/char/hw_random/tx4939-rng.c
diff --git a/drivers/char/hw_random/Kconfig b/drivers/char/hw_random/Kconfig
index 5fab647..9d321cc 100644
--- a/drivers/char/hw_random/Kconfig
+++ b/drivers/char/hw_random/Kconfig
@@ -148,3 +148,16 @@ config HW_RANDOM_VIRTIO
To compile this driver as a module, choose M here: the
module will be called virtio-rng. If unsure, say N.
+
+config HW_RANDOM_TX4939
+ tristate "TX4939 Random Number Generator support"
+ depends on HW_RANDOM && SOC_TX4939
+ default HW_RANDOM
+ ---help---
+ This driver provides kernel-side support for the Random Number
+ Generator hardware found on TX4939 SoC.
+
+ To compile this driver as a module, choose M here: the
+ module will be called tx4939-rng.
+
+ If unsure, say Y.
diff --git a/drivers/char/hw_random/Makefile b/drivers/char/hw_random/Makefile
index e81d21a..936d388 100644
--- a/drivers/char/hw_random/Makefile
+++ b/drivers/char/hw_random/Makefile
@@ -15,3 +15,4 @@ obj-$(CONFIG_HW_RANDOM_IXP4XX) += ixp4xx-rng.o
obj-$(CONFIG_HW_RANDOM_OMAP) += omap-rng.o
obj-$(CONFIG_HW_RANDOM_PASEMI) += pasemi-rng.o
obj-$(CONFIG_HW_RANDOM_VIRTIO) += virtio-rng.o
+obj-$(CONFIG_HW_RANDOM_TX4939) += tx4939-rng.o
diff --git a/drivers/char/hw_random/tx4939-rng.c b/drivers/char/hw_random/tx4939-rng.c
new file mode 100644
index 0000000..27aed22
--- /dev/null
+++ b/drivers/char/hw_random/tx4939-rng.c
@@ -0,0 +1,157 @@
+/*
+ * RNG driver for TX4939 Random Number Generators (RNG)
+ *
+ * Copyright (C) 2009 Atsushi Nemoto <anemo@mba.ocn.ne.jp>
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+#include <linux/hw_random.h>
+
+#define TX4939_RNG_RCSR 0x00000000
+#define TX4939_RNG_ROR(n) (0x00000018 + (n) * 8)
+
+#define TX4939_RNG_RCSR_INTE 0x00000008
+#define TX4939_RNG_RCSR_RST 0x00000004
+#define TX4939_RNG_RCSR_FIN 0x00000002
+#define TX4939_RNG_RCSR_ST 0x00000001
+
+struct tx4939_rng {
+ struct hwrng rng;
+ void __iomem *base;
+ u64 databuf[3];
+ unsigned int data_avail;
+};
+
+static u64 read_rng(void __iomem *base, unsigned int offset)
+{
+ /* Caller must disable interrupts */
+ return ____raw_readq(base + offset);
+}
+
+static void write_rng(u64 val, void __iomem *base, unsigned int offset)
+{
+ return ____raw_writeq(val, base + offset);
+}
+
+static int tx4939_rng_data_present(struct hwrng *rng, int wait)
+{
+ struct tx4939_rng *rngdev = container_of(rng, struct tx4939_rng, rng);
+ int i;
+
+ if (rngdev->data_avail)
+ return rngdev->data_avail;
+ for (i = 0; i < 20; i++) {
+ local_irq_disable();
+ if (!(read_rng(rngdev->base, TX4939_RNG_RCSR)
+ & TX4939_RNG_RCSR_ST)) {
+ rngdev->databuf[0] =
+ read_rng(rngdev->base, TX4939_RNG_ROR(0));
+ rngdev->databuf[1] =
+ read_rng(rngdev->base, TX4939_RNG_ROR(1));
+ rngdev->databuf[2] =
+ read_rng(rngdev->base, TX4939_RNG_ROR(2));
+ rngdev->data_avail =
+ sizeof(rngdev->databuf) / sizeof(u32);
+ /* Start RNG */
+ write_rng(TX4939_RNG_RCSR_ST,
+ rngdev->base, TX4939_RNG_RCSR);
+ wait = 0;
+ }
+ local_irq_enable();
+ if (!wait)
+ break;
+ udelay(1);
+ }
+ return rngdev->data_avail;
+}
+
+static int tx4939_rng_data_read(struct hwrng *rng, u32 *buffer)
+{
+ struct tx4939_rng *rngdev = container_of(rng, struct tx4939_rng, rng);
+
+ rngdev->data_avail--;
+ *buffer = *((u32 *)&rngdev->databuf + rngdev->data_avail);
+ return sizeof(u32);
+}
+
+static int __init tx4939_rng_probe(struct platform_device *dev)
+{
+ struct tx4939_rng *rngdev;
+ struct resource *r;
+ int i;
+
+ r = platform_get_resource(dev, IORESOURCE_MEM, 0);
+ if (!r)
+ return -EBUSY;
+ rngdev = devm_kzalloc(&dev->dev, sizeof(*rngdev), GFP_KERNEL);
+ if (!rngdev)
+ return -ENOMEM;
+ if (!devm_request_mem_region(&dev->dev, r->start, resource_size(r),
+ dev_name(&dev->dev)))
+ return -EBUSY;
+ rngdev->base = devm_ioremap(&dev->dev, r->start, resource_size(r));
+ if (!rngdev->base)
+ return -EBUSY;
+
+ rngdev->rng.name = dev_name(&dev->dev);
+ rngdev->rng.data_present = tx4939_rng_data_present;
+ rngdev->rng.data_read = tx4939_rng_data_read;
+
+ local_irq_disable();
+ /* Reset RNG */
+ write_rng(TX4939_RNG_RCSR_RST, rngdev->base, TX4939_RNG_RCSR);
+ write_rng(0, rngdev->base, TX4939_RNG_RCSR);
+ /* Start RNG */
+ write_rng(TX4939_RNG_RCSR_ST, rngdev->base, TX4939_RNG_RCSR);
+ local_irq_enable();
+ /* drop first two results */
+ for (i = 0; i < 2; i++) {
+ rngdev->data_avail = 0;
+ if (!tx4939_rng_data_present(&rngdev->rng, 1))
+ return -EIO;
+ }
+
+ platform_set_drvdata(dev, rngdev);
+ return hwrng_register(&rngdev->rng);
+}
+
+static int __exit tx4939_rng_remove(struct platform_device *dev)
+{
+ struct tx4939_rng *rngdev = platform_get_drvdata(dev);
+
+ hwrng_unregister(&rngdev->rng);
+ platform_set_drvdata(dev, NULL);
+ return 0;
+}
+
+static struct platform_driver tx4939_rng_driver = {
+ .driver = {
+ .name = "tx4939-rng",
+ .owner = THIS_MODULE,
+ },
+ .remove = tx4939_rng_remove,
+};
+
+static int __init tx4939_rng_init(void)
+{
+ return platform_driver_probe(&tx4939_rng_driver, tx4939_rng_probe);
+}
+
+static void __exit tx4939_rng_exit(void)
+{
+ platform_driver_unregister(&tx4939_rng_driver);
+}
+
+module_init(tx4939_rng_init);
+module_exit(tx4939_rng_exit);
+
+MODULE_DESCRIPTION("H/W Random Number Generator (RNG) driver for TX4939");
+MODULE_LICENSE("GPL");
--
1.5.6.5
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH] hwrng: Add TX4939 RNG driver
2009-05-26 15:02 [PATCH] hwrng: Add TX4939 RNG driver Atsushi Nemoto
@ 2009-05-29 23:29 ` Andrew Morton
2009-05-31 1:30 ` Herbert Xu
` (2 more replies)
0 siblings, 3 replies; 8+ messages in thread
From: Andrew Morton @ 2009-05-29 23:29 UTC (permalink / raw)
To: Atsushi Nemoto; +Cc: linux-mips, ralf, linux-kernel, Herbert Xu
On Wed, 27 May 2009 00:02:20 +0900
Atsushi Nemoto <anemo@mba.ocn.ne.jp> wrote:
> This patch adds support for the integrated RNG of the TX4939 SoC.
>
I think Herbert handles hwrng patches?
I assume that the MIPS patch "[PATCH] TXx9: Add TX4939 RNG support"
depends upon this patch?
> create mode 100644 drivers/char/hw_random/tx4939-rng.c
>
> diff --git a/drivers/char/hw_random/Kconfig b/drivers/char/hw_random/Kconfig
> index 5fab647..9d321cc 100644
> --- a/drivers/char/hw_random/Kconfig
> +++ b/drivers/char/hw_random/Kconfig
> @@ -148,3 +148,16 @@ config HW_RANDOM_VIRTIO
>
> To compile this driver as a module, choose M here: the
> module will be called virtio-rng. If unsure, say N.
> +
> +config HW_RANDOM_TX4939
> + tristate "TX4939 Random Number Generator support"
> + depends on HW_RANDOM && SOC_TX4939
> + default HW_RANDOM
> + ---help---
> + This driver provides kernel-side support for the Random Number
> + Generator hardware found on TX4939 SoC.
> +
> + To compile this driver as a module, choose M here: the
> + module will be called tx4939-rng.
> +
> + If unsure, say Y.
> diff --git a/drivers/char/hw_random/Makefile b/drivers/char/hw_random/Makefile
> index e81d21a..936d388 100644
> --- a/drivers/char/hw_random/Makefile
> +++ b/drivers/char/hw_random/Makefile
> @@ -15,3 +15,4 @@ obj-$(CONFIG_HW_RANDOM_IXP4XX) += ixp4xx-rng.o
> obj-$(CONFIG_HW_RANDOM_OMAP) += omap-rng.o
> obj-$(CONFIG_HW_RANDOM_PASEMI) += pasemi-rng.o
> obj-$(CONFIG_HW_RANDOM_VIRTIO) += virtio-rng.o
> +obj-$(CONFIG_HW_RANDOM_TX4939) += tx4939-rng.o
> diff --git a/drivers/char/hw_random/tx4939-rng.c b/drivers/char/hw_random/tx4939-rng.c
> new file mode 100644
> index 0000000..27aed22
> --- /dev/null
> +++ b/drivers/char/hw_random/tx4939-rng.c
> @@ -0,0 +1,157 @@
> +/*
> + * RNG driver for TX4939 Random Number Generators (RNG)
> + *
> + * Copyright (C) 2009 Atsushi Nemoto <anemo@mba.ocn.ne.jp>
> + *
> + * This file is subject to the terms and conditions of the GNU General Public
> + * License. See the file "COPYING" in the main directory of this archive
> + * for more details.
> + */
> +#include <linux/module.h>
> +#include <linux/kernel.h>
> +#include <linux/init.h>
> +#include <linux/delay.h>
> +#include <linux/io.h>
> +#include <linux/platform_device.h>
> +#include <linux/hw_random.h>
> +
> +#define TX4939_RNG_RCSR 0x00000000
> +#define TX4939_RNG_ROR(n) (0x00000018 + (n) * 8)
> +
> +#define TX4939_RNG_RCSR_INTE 0x00000008
> +#define TX4939_RNG_RCSR_RST 0x00000004
> +#define TX4939_RNG_RCSR_FIN 0x00000002
> +#define TX4939_RNG_RCSR_ST 0x00000001
> +
> +struct tx4939_rng {
> + struct hwrng rng;
> + void __iomem *base;
> + u64 databuf[3];
> + unsigned int data_avail;
> +};
> +
> +static u64 read_rng(void __iomem *base, unsigned int offset)
> +{
> + /* Caller must disable interrupts */
> + return ____raw_readq(base + offset);
> +}
What is the reasoning behind the local_irq_disable() requirement?
Because I'm wondering whether this is safe on SMP?
> +static void write_rng(u64 val, void __iomem *base, unsigned int offset)
> +{
> + return ____raw_writeq(val, base + offset);
> +}
> +
> +static int tx4939_rng_data_present(struct hwrng *rng, int wait)
> +{
> + struct tx4939_rng *rngdev = container_of(rng, struct tx4939_rng, rng);
> + int i;
> +
> + if (rngdev->data_avail)
> + return rngdev->data_avail;
> + for (i = 0; i < 20; i++) {
> + local_irq_disable();
> + if (!(read_rng(rngdev->base, TX4939_RNG_RCSR)
> + & TX4939_RNG_RCSR_ST)) {
> + rngdev->databuf[0] =
> + read_rng(rngdev->base, TX4939_RNG_ROR(0));
> + rngdev->databuf[1] =
> + read_rng(rngdev->base, TX4939_RNG_ROR(1));
> + rngdev->databuf[2] =
> + read_rng(rngdev->base, TX4939_RNG_ROR(2));
> + rngdev->data_avail =
> + sizeof(rngdev->databuf) / sizeof(u32);
> + /* Start RNG */
> + write_rng(TX4939_RNG_RCSR_ST,
> + rngdev->base, TX4939_RNG_RCSR);
> + wait = 0;
> + }
> + local_irq_enable();
> + if (!wait)
> + break;
> + udelay(1);
> + }
> + return rngdev->data_avail;
> +}
The mysterious udelay() needs a comment, because there is no way in
which the reader can otherwise work out why it is there.
> +static int tx4939_rng_data_read(struct hwrng *rng, u32 *buffer)
> +{
> + struct tx4939_rng *rngdev = container_of(rng, struct tx4939_rng, rng);
> +
> + rngdev->data_avail--;
> + *buffer = *((u32 *)&rngdev->databuf + rngdev->data_avail);
> + return sizeof(u32);
> +}
Concurrent callers can corrupt rngdev->data_avail ?
> +static int __init tx4939_rng_probe(struct platform_device *dev)
> +{
> + struct tx4939_rng *rngdev;
> + struct resource *r;
> + int i;
> +
> + r = platform_get_resource(dev, IORESOURCE_MEM, 0);
> + if (!r)
> + return -EBUSY;
> + rngdev = devm_kzalloc(&dev->dev, sizeof(*rngdev), GFP_KERNEL);
> + if (!rngdev)
> + return -ENOMEM;
> + if (!devm_request_mem_region(&dev->dev, r->start, resource_size(r),
> + dev_name(&dev->dev)))
> + return -EBUSY;
> + rngdev->base = devm_ioremap(&dev->dev, r->start, resource_size(r));
> + if (!rngdev->base)
> + return -EBUSY;
> +
> + rngdev->rng.name = dev_name(&dev->dev);
> + rngdev->rng.data_present = tx4939_rng_data_present;
> + rngdev->rng.data_read = tx4939_rng_data_read;
> +
> + local_irq_disable();
> + /* Reset RNG */
> + write_rng(TX4939_RNG_RCSR_RST, rngdev->base, TX4939_RNG_RCSR);
> + write_rng(0, rngdev->base, TX4939_RNG_RCSR);
> + /* Start RNG */
> + write_rng(TX4939_RNG_RCSR_ST, rngdev->base, TX4939_RNG_RCSR);
> + local_irq_enable();
> + /* drop first two results */
The comment doesn't provide the reason for doing this?
> + for (i = 0; i < 2; i++) {
> + rngdev->data_avail = 0;
> + if (!tx4939_rng_data_present(&rngdev->rng, 1))
> + return -EIO;
> + }
> +
> + platform_set_drvdata(dev, rngdev);
> + return hwrng_register(&rngdev->rng);
> +}
> +
> +static int __exit tx4939_rng_remove(struct platform_device *dev)
> +{
> + struct tx4939_rng *rngdev = platform_get_drvdata(dev);
> +
> + hwrng_unregister(&rngdev->rng);
> + platform_set_drvdata(dev, NULL);
> + return 0;
> +}
> +
> +static struct platform_driver tx4939_rng_driver = {
> + .driver = {
> + .name = "tx4939-rng",
> + .owner = THIS_MODULE,
> + },
> + .remove = tx4939_rng_remove,
> +};
> +
> +static int __init tx4939_rng_init(void)
> +{
> + return platform_driver_probe(&tx4939_rng_driver, tx4939_rng_probe);
> +}
> +
> +static void __exit tx4939_rng_exit(void)
> +{
> + platform_driver_unregister(&tx4939_rng_driver);
> +}
> +
> +module_init(tx4939_rng_init);
> +module_exit(tx4939_rng_exit);
> +
> +MODULE_DESCRIPTION("H/W Random Number Generator (RNG) driver for TX4939");
> +MODULE_LICENSE("GPL");
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] hwrng: Add TX4939 RNG driver
2009-05-29 23:29 ` Andrew Morton
@ 2009-05-31 1:30 ` Herbert Xu
2009-05-31 16:18 ` Ralf Baechle
2009-05-31 16:45 ` Atsushi Nemoto
2 siblings, 0 replies; 8+ messages in thread
From: Herbert Xu @ 2009-05-31 1:30 UTC (permalink / raw)
To: Andrew Morton; +Cc: Atsushi Nemoto, linux-mips, ralf, linux-kernel
On Fri, May 29, 2009 at 04:29:07PM -0700, Andrew Morton wrote:
>
> > +static u64 read_rng(void __iomem *base, unsigned int offset)
> > +{
> > + /* Caller must disable interrupts */
> > + return ____raw_readq(base + offset);
> > +}
>
> What is the reasoning behind the local_irq_disable() requirement?
>
> Because I'm wondering whether this is safe on SMP?
Yes I'd like to see this fixed before adding this patch.
Thanks,
--
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] hwrng: Add TX4939 RNG driver
2009-05-29 23:29 ` Andrew Morton
2009-05-31 1:30 ` Herbert Xu
@ 2009-05-31 16:18 ` Ralf Baechle
2009-05-31 16:45 ` Atsushi Nemoto
2 siblings, 0 replies; 8+ messages in thread
From: Ralf Baechle @ 2009-05-31 16:18 UTC (permalink / raw)
To: Andrew Morton; +Cc: Atsushi Nemoto, linux-mips, linux-kernel, Herbert Xu
On Fri, May 29, 2009 at 04:29:07PM -0700, Andrew Morton wrote:
> > +static u64 read_rng(void __iomem *base, unsigned int offset)
> > +{
> > + /* Caller must disable interrupts */
> > + return ____raw_readq(base + offset);
> > +}
>
> What is the reasoning behind the local_irq_disable() requirement?
>
> Because I'm wondering whether this is safe on SMP?
The problem are interrupts, not SMP. readq is reading a 64-bit register
using a 64-bit load. On a 32-bit kernel however interrupts or any
other processor exception would clobber the upper 32-bit of the processor
register so interrupts need to be disabled. The "normal" readq
functions disable interrupts as necessary on a platform. This code does
multiple read accesses so for efficiency sake it relies on the caller
handling interrupts explicitly.
Also this platform does not do SMP.
Ralf
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] hwrng: Add TX4939 RNG driver
2009-05-29 23:29 ` Andrew Morton
2009-05-31 1:30 ` Herbert Xu
2009-05-31 16:18 ` Ralf Baechle
@ 2009-05-31 16:45 ` Atsushi Nemoto
2009-05-31 17:00 ` Matt Mackall
2009-06-02 3:53 ` Herbert Xu
2 siblings, 2 replies; 8+ messages in thread
From: Atsushi Nemoto @ 2009-05-31 16:45 UTC (permalink / raw)
To: akpm; +Cc: linux-mips, ralf, linux-kernel, herbert, mpm
On Fri, 29 May 2009 16:29:07 -0700, Andrew Morton <akpm@linux-foundation.org> wrote:
> I assume that the MIPS patch "[PATCH] TXx9: Add TX4939 RNG support"
> depends upon this patch?
To build kernel or driver, no dependencies. To use this device
actually, both patches are needed.
> > +static u64 read_rng(void __iomem *base, unsigned int offset)
> > +{
> > + /* Caller must disable interrupts */
> > + return ____raw_readq(base + offset);
> > +}
>
> What is the reasoning behind the local_irq_disable() requirement?
>
> Because I'm wondering whether this is safe on SMP?
As Ralf replied, These local_irq_disable stuff are just for 64-bit
access on 32-bit kernel. Maybe something like this is preferred?
static void ____raw_io_start(void)
{
#ifndef CONFIG_64BIT
/* some comments... */
local_irq_enable();
#endif
}
static void ____raw_io_end(void)
{
#ifndef CONFIG_64BIT
/* see above */
local_irq_disable();
#endif
}
For SMP concurrent access, these rountines are protected by mutex in
rng-core. Also this SoC does not support SMP. There should be no
problem here.
> > + for (i = 0; i < 20; i++) {
...
> > + udelay(1);
> > + }
> > + return rngdev->data_avail;
> > +}
>
> The mysterious udelay() needs a comment, because there is no way in
> which the reader can otherwise work out why it is there.
Well, this comments can be applied most RNG drivers ;)
Anyway, I will add some comment here. I take this loop (20 loops with
udelay) from other drivers and changed to udelay(1) because the
datasheed states "90 bus clock cycles by default" for generation
(typically 450ns for this SoC).
> > +static int tx4939_rng_data_read(struct hwrng *rng, u32 *buffer)
> > +{
> > + struct tx4939_rng *rngdev = container_of(rng, struct tx4939_rng, rng);
> > +
> > + rngdev->data_avail--;
> > + *buffer = *((u32 *)&rngdev->databuf + rngdev->data_avail);
> > + return sizeof(u32);
> > +}
>
> Concurrent callers can corrupt rngdev->data_avail ?
This is protected by rng_mutex in rng-core.
> > + /* Start RNG */
> > + write_rng(TX4939_RNG_RCSR_ST, rngdev->base, TX4939_RNG_RCSR);
> > + local_irq_enable();
> > + /* drop first two results */
>
> The comment doesn't provide the reason for doing this?
>From the datasheet:
The quality of the random numbers generated immediately after
reset can be insufficient. Therefore, do not use random
numbers obtained from the first and second generations; use
the ones from the third or subsequent generation.
I will put this comment in the driver.
---
Atsushi Nemoto
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] hwrng: Add TX4939 RNG driver
2009-05-31 16:45 ` Atsushi Nemoto
@ 2009-05-31 17:00 ` Matt Mackall
2009-05-31 17:18 ` Atsushi Nemoto
2009-06-02 3:53 ` Herbert Xu
1 sibling, 1 reply; 8+ messages in thread
From: Matt Mackall @ 2009-05-31 17:00 UTC (permalink / raw)
To: Atsushi Nemoto; +Cc: akpm, linux-mips, ralf, linux-kernel, herbert
On Mon, 2009-06-01 at 01:45 +0900, Atsushi Nemoto wrote:
> On Fri, 29 May 2009 16:29:07 -0700, Andrew Morton <akpm@linux-foundation.org> wrote:
> > I assume that the MIPS patch "[PATCH] TXx9: Add TX4939 RNG support"
> > depends upon this patch?
>
> To build kernel or driver, no dependencies. To use this device
> actually, both patches are needed.
>
> > > +static u64 read_rng(void __iomem *base, unsigned int offset)
> > > +{
> > > + /* Caller must disable interrupts */
> > > + return ____raw_readq(base + offset);
> > > +}
> >
> > What is the reasoning behind the local_irq_disable() requirement?
> >
> > Because I'm wondering whether this is safe on SMP?
>
> As Ralf replied, These local_irq_disable stuff are just for 64-bit
> access on 32-bit kernel. Maybe something like this is preferred?
>
> static void ____raw_io_start(void)
> {
> #ifndef CONFIG_64BIT
> /* some comments... */
> local_irq_enable();
> #endif
> }
>
> static void ____raw_io_end(void)
> {
> #ifndef CONFIG_64BIT
> /* see above */
> local_irq_disable();
> #endif
> }
>
> For SMP concurrent access, these rountines are protected by mutex in
> rng-core. Also this SoC does not support SMP. There should be no
> problem here.
>
> > > + for (i = 0; i < 20; i++) {
> ...
> > > + udelay(1);
> > > + }
> > > + return rngdev->data_avail;
> > > +}
> >
> > The mysterious udelay() needs a comment, because there is no way in
> > which the reader can otherwise work out why it is there.
>
> Well, this comments can be applied most RNG drivers ;)
>
> Anyway, I will add some comment here. I take this loop (20 loops with
> udelay) from other drivers and changed to udelay(1) because the
> datasheed states "90 bus clock cycles by default" for generation
> (typically 450ns for this SoC).
>
> > > +static int tx4939_rng_data_read(struct hwrng *rng, u32 *buffer)
> > > +{
> > > + struct tx4939_rng *rngdev = container_of(rng, struct tx4939_rng, rng);
> > > +
> > > + rngdev->data_avail--;
> > > + *buffer = *((u32 *)&rngdev->databuf + rngdev->data_avail);
> > > + return sizeof(u32);
> > > +}
> >
> > Concurrent callers can corrupt rngdev->data_avail ?
>
> This is protected by rng_mutex in rng-core.
>
> > > + /* Start RNG */
> > > + write_rng(TX4939_RNG_RCSR_ST, rngdev->base, TX4939_RNG_RCSR);
> > > + local_irq_enable();
> > > + /* drop first two results */
> >
> > The comment doesn't provide the reason for doing this?
>
> >From the datasheet:
>
> The quality of the random numbers generated immediately after
> reset can be insufficient. Therefore, do not use random
> numbers obtained from the first and second generations; use
> the ones from the third or subsequent generation.
Does the datasheet say anything about -how- the random numbers are
produced? Most physical sources that I'm aware of don't have this sort
of issue. But some pseudo-RNGs do. So this looks a little worrisome.
--
http://selenic.com : development and support for Mercurial and Linux
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] hwrng: Add TX4939 RNG driver
2009-05-31 17:00 ` Matt Mackall
@ 2009-05-31 17:18 ` Atsushi Nemoto
0 siblings, 0 replies; 8+ messages in thread
From: Atsushi Nemoto @ 2009-05-31 17:18 UTC (permalink / raw)
To: mpm; +Cc: akpm, linux-mips, ralf, linux-kernel, herbert
On Sun, 31 May 2009 12:00:09 -0500, Matt Mackall <mpm@selenic.com> wrote:
> > >From the datasheet:
> >
> > The quality of the random numbers generated immediately after
> > reset can be insufficient. Therefore, do not use random
> > numbers obtained from the first and second generations; use
> > the ones from the third or subsequent generation.
>
> Does the datasheet say anything about -how- the random numbers are
> produced? Most physical sources that I'm aware of don't have this sort
> of issue. But some pseudo-RNGs do. So this looks a little worrisome.
Nothing for "how". If a RNG was actually a pseudo-RNG, does anything
a driver should do? Any future plan to select one RNG from multiple
sources based on randomness grade?
---
Atsushi Nemoto
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] hwrng: Add TX4939 RNG driver
2009-05-31 16:45 ` Atsushi Nemoto
2009-05-31 17:00 ` Matt Mackall
@ 2009-06-02 3:53 ` Herbert Xu
1 sibling, 0 replies; 8+ messages in thread
From: Herbert Xu @ 2009-06-02 3:53 UTC (permalink / raw)
To: Atsushi Nemoto; +Cc: akpm, linux-mips, ralf, linux-kernel, mpm
On Mon, Jun 01, 2009 at 01:45:17AM +0900, Atsushi Nemoto wrote:
>
> >From the datasheet:
>
> The quality of the random numbers generated immediately after
> reset can be insufficient. Therefore, do not use random
> numbers obtained from the first and second generations; use
> the ones from the third or subsequent generation.
>
> I will put this comment in the driver.
OK, I think you've resolved all my concerns. Please cc me when
you resubmit.
Thanks!
--
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2009-06-02 3:53 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-05-26 15:02 [PATCH] hwrng: Add TX4939 RNG driver Atsushi Nemoto
2009-05-29 23:29 ` Andrew Morton
2009-05-31 1:30 ` Herbert Xu
2009-05-31 16:18 ` Ralf Baechle
2009-05-31 16:45 ` Atsushi Nemoto
2009-05-31 17:00 ` Matt Mackall
2009-05-31 17:18 ` Atsushi Nemoto
2009-06-02 3:53 ` Herbert Xu
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox