Skip to contentSkip to conversation

New hardware RNG for Octeon SOCs.

PATCH In review David Daney 4 participants 9 messages Aug 10, 2009

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

cover New hardware RNG for Octeon SOCs.

Behold the Random Number Generator driver for Octeon!

The first patch adds some port definitions and the octeon_rng platform device. The second is the driver.

I am copying AKPM and Linus as there seems to be no hw_random maintainer.

Since Octeon is a mips port, we might want to merge both patches via Ralf's tree.

Comments?

David Daney (2):
MIPS: Octeon: Add hardware RNG platform device.
hw_random: Add hardware RNG for Octeon SOCs.

 arch/mips/cavium-octeon/setup.c              |   44 ++++++++
 arch/mips/include/asm/octeon/cvmx-rnm-defs.h |   86 +++++++++++++++
 drivers/char/hw_random/Kconfig               |   13 +++
 drivers/char/hw_random/Makefile              |    1 +
 drivers/char/hw_random/octeon-rng.c          |  146 
++++++++++++++++++++++++++
 5 files changed, 290 insertions(+), 0 deletions(-)
 create mode 100644 arch/mips/include/asm/octeon/cvmx-rnm-defs.h
 create mode 100644 drivers/char/hw_random/octeon-rng.c
#1 lore raw

PATCH 1/2 MIPS: Octeon: Add hardware RNG platform device.

Add a platform device for the Octeon Random Number Generator (RNG).

---
 arch/mips/cavium-octeon/setup.c              |   44 +++++++++++++
 arch/mips/include/asm/octeon/cvmx-rnm-defs.h |   86 ++++++++++++++++++++++++++
 2 files changed, 130 insertions(+), 0 deletions(-)
 create mode 100644 arch/mips/include/asm/octeon/cvmx-rnm-defs.h
arch/mips/cavium-octeon/setup.c +44 -0
index bc0c869..c67487a 100644
@@ -33,6 +33,7 @@
 #include <asm/time.h>
 
 #include <asm/octeon/octeon.h>
+#include <asm/octeon/cvmx-rnm-defs.h>
 
 #ifdef CONFIG_CAVIUM_DECODE_RSL
 extern void cvmx_interrupt_rsl_decode(void);
@@ -931,3 +932,46 @@ out:
 	return ret;
 }
 device_initcall(octeon_cf_device_init);
+
+/* Octeon Random Number Generator.  */
+static int __init octeon_rng_device_init(void)
+{
+	struct platform_device *pd;
+	struct resource rng_resources[2];
+	unsigned int res_count;
+	int ret = 0;
+
+	memset(rng_resources, 0, sizeof(rng_resources));
+	res_count = 0;
+	rng_resources[res_count].flags = IORESOURCE_MEM;
+	rng_resources[res_count].start = XKPHYS_TO_PHYS(CVMX_RNM_CTL_STATUS);
+	rng_resources[res_count].end = rng_resources[res_count].start + 0xf;
+	res_count++;
+
+	rng_resources[res_count].flags = IORESOURCE_MEM;
+	rng_resources[res_count].start = cvmx_build_io_address(8, 0);
+	rng_resources[res_count].end = rng_resources[res_count].start + 0x7;
+	res_count++;
+
+	pd = platform_device_alloc("octeon_rng", -1);
+	if (!pd) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	ret = platform_device_add_resources(pd, rng_resources, res_count);
+	if (ret)
+		goto fail;
+
+	ret = platform_device_add(pd);
+	if (ret)
+		goto fail;
+
+	return ret;
+fail:
+	platform_device_put(pd);
+
+out:
+	return ret;
+}
+device_initcall(octeon_rng_device_init);
arch/mips/include/asm/octeon/cvmx-rnm-defs.h new file +86 -0

86 lines not on this page · raw message

Signature · 1 line
1.6.0.6
#2 lore raw

Re: [PATCH 1/2] MIPS: Octeon: Add hardware RNG platform device.

Quoted 15 lines · On Mon, 10 Aug 2009 11:30:24 -0700 David Daney <[email protected]>…

Add a platform device for the Octeon Random Number Generator (RNG).

...

device_initcall(octeon_cf_device_init);

arch/mips/cavium-octeon/setup.c +10 -0
+
+/* Octeon Random Number Generator.  */
+static int __init octeon_rng_device_init(void)
+{
+	struct platform_device *pd;
+	struct resource rng_resources[2];
+	unsigned int res_count;
+	int ret = 0;
+
+	memset(rng_resources, 0, sizeof(rng_resources));

arch/mips/cavium-octeon/setup.c out: · line 954

Quoted 10 lines
arch/mips/cavium-octeon/setup.c +10 -0
+	res_count = 0;
+	rng_resources[res_count].flags = IORESOURCE_MEM;
+	rng_resources[res_count].start = XKPHYS_TO_PHYS(CVMX_RNM_CTL_STATUS);
+	rng_resources[res_count].end = rng_resources[res_count].start + 0xf;
+	res_count++;
+
+	rng_resources[res_count].flags = IORESOURCE_MEM;
+	rng_resources[res_count].start = cvmx_build_io_address(8, 0);
+	rng_resources[res_count].end = rng_resources[res_count].start + 0x7;
+	res_count++;

You could do

	strut resource rng_resources[2] = {
		{
			.flags = IORESOURCE_MEM,
			.start = XKPHYS_TO_PHYS(CVMX_RNM_CTL_STATUS),
	{etc}

here.

arch/mips/cavium-octeon/setup.c out: · line 962

Quoted 7 lines
arch/mips/cavium-octeon/setup.c +7 -0
+	pd = platform_device_alloc("octeon_rng", -1);
+	if (!pd) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	ret = platform_device_add_resources(pd, rng_resources, res_count);

use ARRAY_SIZE() here.

Quoted 4 lines
arch/mips/cavium-octeon/setup.c +4 -0
+	if (ret)
+		goto fail;
+
+	ret = platform_device_add(pd);

arch/mips/cavium-octeon/setup.c out: · line 976

Quoted 10 lines
arch/mips/cavium-octeon/setup.c +10 -0
+	if (ret)
+		goto fail;
+
+	return ret;
+fail:
+	platform_device_put(pd);
+
+out:
+	return ret;
+}

Or not bother ;) It doesn't make any difference.

arch/mips/include/asm/octeon/cvmx-rnm-defs.h

Quoted 9 lines
arch/mips/include/asm/octeon/cvmx-rnm-defs.h new file +1 -0
 
...
 
+	uint64_t u64;
 
...

This file should include types.h (at least).

#3 lore raw

PATCH 2/2 hw_random: Add hardware RNG for Octeon SOCs.

In reply to David Daney
---
 drivers/char/hw_random/Kconfig      |   13 +++
 drivers/char/hw_random/Makefile     |    1 +
 drivers/char/hw_random/octeon-rng.c |  146 +++++++++++++++++++++++++++++++++++
 3 files changed, 160 insertions(+), 0 deletions(-)
 create mode 100644 drivers/char/hw_random/octeon-rng.c
drivers/char/hw_random/Kconfig +13 -0
index ce66a70..121b782 100644
@@ -126,6 +126,19 @@ config HW_RANDOM_OMAP
 
  	  If unsure, say Y.
 
+config HW_RANDOM_OCTEON
+	tristate "Octeon Random Number Generator support"
+	depends on HW_RANDOM && CPU_CAVIUM_OCTEON
+	default HW_RANDOM
+ 	---help---
+ 	  This driver provides kernel-side support for the Random Number
+	  Generator hardware found on Octeon processors.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called octeon-rng.
+
+ 	  If unsure, say Y.
+
 config HW_RANDOM_PASEMI
 	tristate "PA Semi HW Random Number Generator support"
 	depends on HW_RANDOM && PPC_PASEMI
drivers/char/hw_random/Makefile +1 -0
index 676828b..5eeb130 100644
@@ -17,3 +17,4 @@ obj-$(CONFIG_HW_RANDOM_PASEMI) += pasemi-rng.o
 obj-$(CONFIG_HW_RANDOM_VIRTIO) += virtio-rng.o
 obj-$(CONFIG_HW_RANDOM_TX4939) += tx4939-rng.o
 obj-$(CONFIG_HW_RANDOM_MXC_RNGA) += mxc-rnga.o
+obj-$(CONFIG_HW_RANDOM_OCTEON) += octeon-rng.o
drivers/char/hw_random/octeon-rng.c new file +146 -0

146 lines not on this page · raw message

Signature · 1 line
1.6.0.6
#4 lore raw

Re: [PATCH 2/2] hw_random: Add hardware RNG for Octeon SOCs.

Quoted 1 line · On Mon, 10 Aug 2009 11:30:25 -0700 David Daney <[email protected]>…

Now what's going on with all this typecasting?

Quoted 25 lines
drivers/char/hw_random/octeon-rng.c new file +19 -0
new file mode 100644
index 0000000..84d33a7
@@ -0,0 +1,146 @@
+/*
+ * Hardware Random Number Generator support for Cavium Networks
+ * Octeon processor family.
+ *
+ * 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.
+ *
+ * Copyright (C) 2009 Cavium Networks
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/device.h>
+#include <linux/hw_random.h>
+#include <linux/io.h>
+
+#include <asm/octeon/octeon.h>

drivers/char/hw_random/octeon-rng.c line 29

Quoted 10 lines
drivers/char/hw_random/octeon-rng.c new file +10 -0
+#include <asm/octeon/cvmx-rnm-defs.h>
+
+struct octeon_rng {
+	u64 control_status;
+	u64 result;
+};
+
+static int octeon_rng_init(struct hwrng *rng)
+{
+	struct octeon_rng *p = (struct octeon_rng *)rng->priv;

Here it's unavoidable because some bad person went and made hwrng.priv an `unsigned long'. I haven't checked, but I bet it should have been a void*.

Quoted 47 lines
drivers/char/hw_random/octeon-rng.c new file +47 -0
+	union cvmx_rnm_ctl_status ctl;
+
+	ctl.u64 = 0;
+	ctl.s.ent_en = 1; /* Enable the entropy source.  */
+	ctl.s.rng_en = 1; /* Enable the RNG hardware.  */
+	cvmx_write_csr(p->control_status, ctl.u64);
+	return 0;
+}
+
+static void octeon_rng_cleanup(struct hwrng *rng)
+{
+	struct octeon_rng *p = (struct octeon_rng *)rng->priv;
+	union cvmx_rnm_ctl_status ctl;
+
+	ctl.u64 = 0;
+	/* Disable everything.  */
+	cvmx_write_csr(p->control_status, ctl.u64);
+}
+
+static int octeon_rng_data_read(struct hwrng *rng, u32 *data)
+{
+	struct octeon_rng *p = (struct octeon_rng *)rng->priv;
+
+	*data = cvmx_read64_uint32(p->result);
+	return sizeof(u32);
+}
+
+static struct hwrng octeon_rng_ops = {
+	.name		= "octeon",
+	.init		= octeon_rng_init,
+	.cleanup	= octeon_rng_cleanup,
+	.data_read	= octeon_rng_data_read
+};
+
+static int __devinit octeon_rng_probe(struct platform_device *pdev)
+{
+	struct resource *res_ports;
+	struct resource *res_result;
+	struct octeon_rng *p;
+	int ret;
+
+	p = devm_kzalloc(&pdev->dev, sizeof(*p), GFP_KERNEL);
+	if (!p)
+		return -ENOMEM;
+
+	res_ports = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res_ports)

drivers/char/hw_random/octeon-rng.c line 86

Quoted 10 lines
drivers/char/hw_random/octeon-rng.c new file +10 -0
+		goto err_ports;
+
+	res_result = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+	if (!res_result)
+		goto err_ports;
+
+
+	p->control_status = (u64)devm_ioremap_nocache(&pdev->dev,
+						      res_ports->start,
+						      sizeof(u64));

devm_ioremap_nocache() returns a void __iomem *'. Hence we should be recording that value in a field of type void __iomem *'. Instead, we're wedging it into a u64.

Something went wrong!

drivers/char/hw_random/octeon-rng.c line 92

Quoted 6 lines
drivers/char/hw_random/octeon-rng.c new file +6 -0
+	if (!p->control_status)
+		goto err_ports;
+
+	p->result = (u64)devm_ioremap_nocache(&pdev->dev,
+					      res_result->start,
+					      sizeof(u64));

Ditto.

drivers/char/hw_random/octeon-rng.c line 95

Quoted 3 lines
drivers/char/hw_random/octeon-rng.c new file +3 -0
+	if (!p->result)
+		goto err_r;
+	octeon_rng_ops.priv = (unsigned long)p;

The hwrng.priv problem again.

Quoted 40 lines
drivers/char/hw_random/octeon-rng.c new file +40 -0
+	dev_set_drvdata(&pdev->dev, &octeon_rng_ops);
+	ret = hwrng_register(&octeon_rng_ops);
+	if (ret)
+		goto err;
+
+	dev_info(&pdev->dev, "Octeon Random Number Generator\n");
+
+	return 0;
+err:
+	devm_iounmap(&pdev->dev, (void *)p->control_status);
+err_r:
+	devm_iounmap(&pdev->dev, (void *)p->result);
+err_ports:
+	devm_kfree(&pdev->dev, p);
+	return -ENOENT;
+}
+
+static int __exit octeon_rng_remove(struct platform_device *pdev)
+{
+	struct hwrng *rng = dev_get_drvdata(&pdev->dev);
+
+	hwrng_unregister(rng);
+
+	return 0;
+}
+
+static struct platform_driver octeon_rng_driver = {
+	.driver = {
+		.name		= "octeon_rng",
+		.owner		= THIS_MODULE,
+	},
+	.probe		= octeon_rng_probe,
+	.remove		= __exit_p(octeon_rng_remove),
+};
+
+static int __init octeon_rng_mod_init(void)
+{
+	return platform_driver_register(&octeon_rng_driver);
+}
+

drivers/char/hw_random/octeon-rng.c line 146

Quoted 10 lines
drivers/char/hw_random/octeon-rng.c new file +10 -0
+static void __exit octeon_rng_mod_exit(void)
+{
+	platform_driver_unregister(&octeon_rng_driver);
+}
+
+module_init(octeon_rng_mod_init);
+module_exit(octeon_rng_mod_exit);
+
+MODULE_AUTHOR("David Daney");
+MODULE_LICENSE("GPL");

Please take another look and check that the selection of types was as good as it could possibly be?

Also, let's all send rude emails to Herbert over the type of hwrng.priv ;)

#5 lore raw
In reply to David Daney
Quoted 6 lines · David Daney

Behold the Random Number Generator driver for Octeon!

The first patch adds some port definitions and the octeon_rng platform device. The second is the driver.

I am copying AKPM and Linus as there seems to be no hw_random maintainer.

These now go through Herbert Xu and I.

Signature · 1 line
http://selenic.com : development and support for Mercurial and Linux
#6 lore raw
Quoted 9 lines · Matt Mackall
Quoted 6 lines · David Daney

Behold the Random Number Generator driver for Octeon!

The first patch adds some port definitions and the octeon_rng platform device. The second is the driver.

I am copying AKPM and Linus as there seems to be no hw_random maintainer.

These now go through Herbert Xu and I.

I had been advised of this after I sent the messages. Perhaps an entry in MAINTAINERS is in order.

David Daney

#7 lore raw

PATCH 1/1 MAINTAINERS: Add Matt Mackall and Herbert Xu to HARDWARE RANDOM NUMBER GENERATOR

In reply to Matt Mackall
Quoted 3 lines · Matt Mackall
Quoted 1 line · David Daney

I am copying AKPM and Linus as there seems to be no hw_random maintainer.

These now go through Herbert Xu and I.

Perhaps this then:

MAINTAINERS +3 -1
index b1114cf..9a27822 100644
@@ -2260,7 +2260,9 @@ S:	Orphan
 F:	drivers/hwmon/
 
 HARDWARE RANDOM NUMBER GENERATOR CORE
-S:	Orphan
+M:	Matt Mackall <[email protected]>
+M:	Herbert Xu <[email protected]>
+S:	Odd fixes
 F:	Documentation/hw_random.txt
 F:	drivers/char/hw_random/
 F:	include/linux/hw_random.h
#8 lore raw
In reply to David Daney
Quoted 1 line · On Mon, 10 Aug 2009 11:21:29 -0700 David Daney <[email protected]>…

Behold the Random Number Generator driver for Octeon!

Hail!

Quoted 9 lines

The first patch adds some port definitions and the octeon_rng platform device. The second is the driver.

I am copying AKPM and Linus as there seems to be no hw_random maintainer.

Since Octeon is a mips port, we might want to merge both patches via Ralf's tree.

Comments?

Looks OK to me - I had a couple of minor comments. Please send the patches to Herbert and Ralf - I'd normally expect one of those two gents to be the merge path for this work.