2 * Hardware Random Number Generator support for Cavium, Inc.
3 * Thunder processor family.
5 * This file is subject to the terms and conditions of the GNU General Public
6 * License. See the file "COPYING" in the main directory of this archive
9 * Copyright (C) 2016 Cavium, Inc.
12 #include <linux/hw_random.h>
14 #include <linux/module.h>
15 #include <linux/pci.h>
16 #include <linux/pci_ids.h>
23 /* Read data from the RNG unit */
24 static int cavium_rng_read(struct hwrng
*rng
, void *dat
, size_t max
, bool wait
)
26 struct cavium_rng
*p
= container_of(rng
, struct cavium_rng
, ops
);
27 unsigned int size
= max
;
30 *((u64
*)dat
) = readq(p
->result
);
35 *((u8
*)dat
) = readb(p
->result
);
42 /* Map Cavium RNG to an HWRNG object */
43 static int cavium_rng_probe_vf(struct pci_dev
*pdev
,
44 const struct pci_device_id
*id
)
46 struct cavium_rng
*rng
;
49 rng
= devm_kzalloc(&pdev
->dev
, sizeof(*rng
), GFP_KERNEL
);
53 /* Map the RNG result */
54 rng
->result
= pcim_iomap(pdev
, 0, 0);
56 dev_err(&pdev
->dev
, "Error iomap failed retrieving result.\n");
60 rng
->ops
.name
= devm_kasprintf(&pdev
->dev
, GFP_KERNEL
,
61 "cavium-rng-%s", dev_name(&pdev
->dev
));
65 rng
->ops
.read
= cavium_rng_read
;
66 rng
->ops
.quality
= 1000;
68 pci_set_drvdata(pdev
, rng
);
70 ret
= hwrng_register(&rng
->ops
);
72 dev_err(&pdev
->dev
, "Error registering device as HWRNG.\n");
80 static void cavium_rng_remove_vf(struct pci_dev
*pdev
)
82 struct cavium_rng
*rng
;
84 rng
= pci_get_drvdata(pdev
);
85 hwrng_unregister(&rng
->ops
);
88 static const struct pci_device_id cavium_rng_vf_id_table
[] = {
89 { PCI_DEVICE(PCI_VENDOR_ID_CAVIUM
, 0xa033), 0, 0, 0},
92 MODULE_DEVICE_TABLE(pci
, cavium_rng_vf_id_table
);
94 static struct pci_driver cavium_rng_vf_driver
= {
95 .name
= "cavium_rng_vf",
96 .id_table
= cavium_rng_vf_id_table
,
97 .probe
= cavium_rng_probe_vf
,
98 .remove
= cavium_rng_remove_vf
,
100 module_pci_driver(cavium_rng_vf_driver
);
102 MODULE_AUTHOR("Omer Khaliq <okhaliq@caviumnetworks.com>");
103 MODULE_LICENSE("GPL");