cavium-rng.c 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Hardware Random Number Generator support.
  4. * Cavium Thunder, Marvell OcteonTx/Tx2 processor families.
  5. *
  6. * Copyright (C) 2016 Cavium, Inc.
  7. */
  8. #include <linux/hw_random.h>
  9. #include <linux/io.h>
  10. #include <linux/module.h>
  11. #include <linux/pci.h>
  12. #include <linux/pci_ids.h>
  13. #define THUNDERX_RNM_ENT_EN 0x1
  14. #define THUNDERX_RNM_RNG_EN 0x2
  15. struct cavium_rng_pf {
  16. void __iomem *control_status;
  17. };
  18. /* Enable the RNG hardware and activate the VF */
  19. static int cavium_rng_probe(struct pci_dev *pdev,
  20. const struct pci_device_id *id)
  21. {
  22. struct cavium_rng_pf *rng;
  23. int iov_err;
  24. rng = devm_kzalloc(&pdev->dev, sizeof(*rng), GFP_KERNEL);
  25. if (!rng)
  26. return -ENOMEM;
  27. /*Map the RNG control */
  28. rng->control_status = pcim_iomap(pdev, 0, 0);
  29. if (!rng->control_status) {
  30. dev_err(&pdev->dev,
  31. "Error iomap failed retrieving control_status.\n");
  32. return -ENOMEM;
  33. }
  34. /* Enable the RNG hardware and entropy source */
  35. writeq(THUNDERX_RNM_RNG_EN | THUNDERX_RNM_ENT_EN,
  36. rng->control_status);
  37. pci_set_drvdata(pdev, rng);
  38. /* Enable the Cavium RNG as a VF */
  39. iov_err = pci_enable_sriov(pdev, 1);
  40. if (iov_err != 0) {
  41. /* Disable the RNG hardware and entropy source */
  42. writeq(0, rng->control_status);
  43. dev_err(&pdev->dev,
  44. "Error initializing RNG virtual function,(%i).\n",
  45. iov_err);
  46. return iov_err;
  47. }
  48. return 0;
  49. }
  50. /* Disable VF and RNG Hardware */
  51. static void cavium_rng_remove(struct pci_dev *pdev)
  52. {
  53. struct cavium_rng_pf *rng;
  54. rng = pci_get_drvdata(pdev);
  55. /* Remove the VF */
  56. pci_disable_sriov(pdev);
  57. /* Disable the RNG hardware and entropy source */
  58. writeq(0, rng->control_status);
  59. }
  60. static const struct pci_device_id cavium_rng_pf_id_table[] = {
  61. { PCI_DEVICE(PCI_VENDOR_ID_CAVIUM, 0xa018), 0, 0, 0}, /* Thunder RNM */
  62. {0,},
  63. };
  64. MODULE_DEVICE_TABLE(pci, cavium_rng_pf_id_table);
  65. static struct pci_driver cavium_rng_pf_driver = {
  66. .name = "cavium_rng_pf",
  67. .id_table = cavium_rng_pf_id_table,
  68. .probe = cavium_rng_probe,
  69. .remove = cavium_rng_remove,
  70. };
  71. module_pci_driver(cavium_rng_pf_driver);
  72. MODULE_AUTHOR("Omer Khaliq <[email protected]>");
  73. MODULE_LICENSE("GPL v2");