nitrox_lib.c 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. // SPDX-License-Identifier: GPL-2.0
  2. #include <linux/cpumask.h>
  3. #include <linux/dma-mapping.h>
  4. #include <linux/dmapool.h>
  5. #include <linux/delay.h>
  6. #include <linux/gfp.h>
  7. #include <linux/kernel.h>
  8. #include <linux/module.h>
  9. #include <linux/pci_regs.h>
  10. #include <linux/vmalloc.h>
  11. #include <linux/pci.h>
  12. #include "nitrox_dev.h"
  13. #include "nitrox_common.h"
  14. #include "nitrox_req.h"
  15. #include "nitrox_csr.h"
  16. #define CRYPTO_CTX_SIZE 256
  17. /* packet inuput ring alignments */
  18. #define PKTIN_Q_ALIGN_BYTES 16
  19. static int nitrox_cmdq_init(struct nitrox_cmdq *cmdq, int align_bytes)
  20. {
  21. struct nitrox_device *ndev = cmdq->ndev;
  22. cmdq->qsize = (ndev->qlen * cmdq->instr_size) + align_bytes;
  23. cmdq->unalign_base = dma_zalloc_coherent(DEV(ndev), cmdq->qsize,
  24. &cmdq->unalign_dma,
  25. GFP_KERNEL);
  26. if (!cmdq->unalign_base)
  27. return -ENOMEM;
  28. cmdq->dma = PTR_ALIGN(cmdq->unalign_dma, align_bytes);
  29. cmdq->base = cmdq->unalign_base + (cmdq->dma - cmdq->unalign_dma);
  30. cmdq->write_idx = 0;
  31. spin_lock_init(&cmdq->cmd_qlock);
  32. spin_lock_init(&cmdq->resp_qlock);
  33. spin_lock_init(&cmdq->backlog_qlock);
  34. INIT_LIST_HEAD(&cmdq->response_head);
  35. INIT_LIST_HEAD(&cmdq->backlog_head);
  36. INIT_WORK(&cmdq->backlog_qflush, backlog_qflush_work);
  37. atomic_set(&cmdq->pending_count, 0);
  38. atomic_set(&cmdq->backlog_count, 0);
  39. return 0;
  40. }
  41. static void nitrox_cmdq_reset(struct nitrox_cmdq *cmdq)
  42. {
  43. cmdq->write_idx = 0;
  44. atomic_set(&cmdq->pending_count, 0);
  45. atomic_set(&cmdq->backlog_count, 0);
  46. }
  47. static void nitrox_cmdq_cleanup(struct nitrox_cmdq *cmdq)
  48. {
  49. struct nitrox_device *ndev = cmdq->ndev;
  50. if (!cmdq->unalign_base)
  51. return;
  52. cancel_work_sync(&cmdq->backlog_qflush);
  53. dma_free_coherent(DEV(ndev), cmdq->qsize,
  54. cmdq->unalign_base, cmdq->unalign_dma);
  55. nitrox_cmdq_reset(cmdq);
  56. cmdq->dbell_csr_addr = NULL;
  57. cmdq->compl_cnt_csr_addr = NULL;
  58. cmdq->unalign_base = NULL;
  59. cmdq->base = NULL;
  60. cmdq->unalign_dma = 0;
  61. cmdq->dma = 0;
  62. cmdq->qsize = 0;
  63. cmdq->instr_size = 0;
  64. }
  65. static void nitrox_free_pktin_queues(struct nitrox_device *ndev)
  66. {
  67. int i;
  68. for (i = 0; i < ndev->nr_queues; i++) {
  69. struct nitrox_cmdq *cmdq = &ndev->pkt_inq[i];
  70. nitrox_cmdq_cleanup(cmdq);
  71. }
  72. kfree(ndev->pkt_inq);
  73. ndev->pkt_inq = NULL;
  74. }
  75. static int nitrox_alloc_pktin_queues(struct nitrox_device *ndev)
  76. {
  77. int i, err;
  78. ndev->pkt_inq = kcalloc_node(ndev->nr_queues,
  79. sizeof(struct nitrox_cmdq),
  80. GFP_KERNEL, ndev->node);
  81. if (!ndev->pkt_inq)
  82. return -ENOMEM;
  83. for (i = 0; i < ndev->nr_queues; i++) {
  84. struct nitrox_cmdq *cmdq;
  85. u64 offset;
  86. cmdq = &ndev->pkt_inq[i];
  87. cmdq->ndev = ndev;
  88. cmdq->qno = i;
  89. cmdq->instr_size = sizeof(struct nps_pkt_instr);
  90. /* packet input ring doorbell address */
  91. offset = NPS_PKT_IN_INSTR_BAOFF_DBELLX(i);
  92. cmdq->dbell_csr_addr = NITROX_CSR_ADDR(ndev, offset);
  93. /* packet solicit port completion count address */
  94. offset = NPS_PKT_SLC_CNTSX(i);
  95. cmdq->compl_cnt_csr_addr = NITROX_CSR_ADDR(ndev, offset);
  96. err = nitrox_cmdq_init(cmdq, PKTIN_Q_ALIGN_BYTES);
  97. if (err)
  98. goto pktq_fail;
  99. }
  100. return 0;
  101. pktq_fail:
  102. nitrox_free_pktin_queues(ndev);
  103. return err;
  104. }
  105. static int create_crypto_dma_pool(struct nitrox_device *ndev)
  106. {
  107. size_t size;
  108. /* Crypto context pool, 16 byte aligned */
  109. size = CRYPTO_CTX_SIZE + sizeof(struct ctx_hdr);
  110. ndev->ctx_pool = dma_pool_create("nitrox-context",
  111. DEV(ndev), size, 16, 0);
  112. if (!ndev->ctx_pool)
  113. return -ENOMEM;
  114. return 0;
  115. }
  116. static void destroy_crypto_dma_pool(struct nitrox_device *ndev)
  117. {
  118. if (!ndev->ctx_pool)
  119. return;
  120. dma_pool_destroy(ndev->ctx_pool);
  121. ndev->ctx_pool = NULL;
  122. }
  123. /*
  124. * crypto_alloc_context - Allocate crypto context from pool
  125. * @ndev: NITROX Device
  126. */
  127. void *crypto_alloc_context(struct nitrox_device *ndev)
  128. {
  129. struct ctx_hdr *ctx;
  130. void *vaddr;
  131. dma_addr_t dma;
  132. vaddr = dma_pool_zalloc(ndev->ctx_pool, GFP_KERNEL, &dma);
  133. if (!vaddr)
  134. return NULL;
  135. /* fill meta data */
  136. ctx = vaddr;
  137. ctx->pool = ndev->ctx_pool;
  138. ctx->dma = dma;
  139. ctx->ctx_dma = dma + sizeof(struct ctx_hdr);
  140. return ((u8 *)vaddr + sizeof(struct ctx_hdr));
  141. }
  142. /**
  143. * crypto_free_context - Free crypto context to pool
  144. * @ctx: context to free
  145. */
  146. void crypto_free_context(void *ctx)
  147. {
  148. struct ctx_hdr *ctxp;
  149. if (!ctx)
  150. return;
  151. ctxp = (struct ctx_hdr *)((u8 *)ctx - sizeof(struct ctx_hdr));
  152. dma_pool_free(ctxp->pool, ctxp, ctxp->dma);
  153. }
  154. /**
  155. * nitrox_common_sw_init - allocate software resources.
  156. * @ndev: NITROX device
  157. *
  158. * Allocates crypto context pools and command queues etc.
  159. *
  160. * Return: 0 on success, or a negative error code on error.
  161. */
  162. int nitrox_common_sw_init(struct nitrox_device *ndev)
  163. {
  164. int err = 0;
  165. /* per device crypto context pool */
  166. err = create_crypto_dma_pool(ndev);
  167. if (err)
  168. return err;
  169. err = nitrox_alloc_pktin_queues(ndev);
  170. if (err)
  171. destroy_crypto_dma_pool(ndev);
  172. return err;
  173. }
  174. /**
  175. * nitrox_common_sw_cleanup - free software resources.
  176. * @ndev: NITROX device
  177. */
  178. void nitrox_common_sw_cleanup(struct nitrox_device *ndev)
  179. {
  180. nitrox_free_pktin_queues(ndev);
  181. destroy_crypto_dma_pool(ndev);
  182. }