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>
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>
13 #include "nitrox_dev.h"
14 #include "nitrox_common.h"
15 #include "nitrox_req.h"
16 #include "nitrox_csr.h"
18 #define CRYPTO_CTX_SIZE 256
20 /* packet inuput ring alignments */
21 #define PKTIN_Q_ALIGN_BYTES 16
23 static int nitrox_cmdq_init(struct nitrox_cmdq *cmdq, int align_bytes)
25 struct nitrox_device *ndev = cmdq->ndev;
27 cmdq->qsize = (ndev->qlen * cmdq->instr_size) + align_bytes;
28 cmdq->unalign_base = dma_alloc_coherent(DEV(ndev), cmdq->qsize,
31 if (!cmdq->unalign_base)
34 cmdq->dma = PTR_ALIGN(cmdq->unalign_dma, align_bytes);
35 cmdq->base = cmdq->unalign_base + (cmdq->dma - cmdq->unalign_dma);
38 spin_lock_init(&cmdq->cmd_qlock);
39 spin_lock_init(&cmdq->resp_qlock);
40 spin_lock_init(&cmdq->backlog_qlock);
42 INIT_LIST_HEAD(&cmdq->response_head);
43 INIT_LIST_HEAD(&cmdq->backlog_head);
44 INIT_WORK(&cmdq->backlog_qflush, backlog_qflush_work);
46 atomic_set(&cmdq->pending_count, 0);
47 atomic_set(&cmdq->backlog_count, 0);
51 static void nitrox_cmdq_reset(struct nitrox_cmdq *cmdq)
54 atomic_set(&cmdq->pending_count, 0);
55 atomic_set(&cmdq->backlog_count, 0);
58 static void nitrox_cmdq_cleanup(struct nitrox_cmdq *cmdq)
60 struct nitrox_device *ndev = cmdq->ndev;
62 if (!cmdq->unalign_base)
65 cancel_work_sync(&cmdq->backlog_qflush);
67 dma_free_coherent(DEV(ndev), cmdq->qsize,
68 cmdq->unalign_base, cmdq->unalign_dma);
69 nitrox_cmdq_reset(cmdq);
71 cmdq->dbell_csr_addr = NULL;
72 cmdq->compl_cnt_csr_addr = NULL;
73 cmdq->unalign_base = NULL;
75 cmdq->unalign_dma = 0;
81 static void nitrox_free_pktin_queues(struct nitrox_device *ndev)
85 for (i = 0; i < ndev->nr_queues; i++) {
86 struct nitrox_cmdq *cmdq = &ndev->pkt_inq[i];
88 nitrox_cmdq_cleanup(cmdq);
94 static int nitrox_alloc_pktin_queues(struct nitrox_device *ndev)
98 ndev->pkt_inq = kcalloc_node(ndev->nr_queues,
99 sizeof(struct nitrox_cmdq),
100 GFP_KERNEL, ndev->node);
104 for (i = 0; i < ndev->nr_queues; i++) {
105 struct nitrox_cmdq *cmdq;
108 cmdq = &ndev->pkt_inq[i];
111 cmdq->instr_size = sizeof(struct nps_pkt_instr);
113 /* packet input ring doorbell address */
114 offset = NPS_PKT_IN_INSTR_BAOFF_DBELLX(i);
115 cmdq->dbell_csr_addr = NITROX_CSR_ADDR(ndev, offset);
116 /* packet solicit port completion count address */
117 offset = NPS_PKT_SLC_CNTSX(i);
118 cmdq->compl_cnt_csr_addr = NITROX_CSR_ADDR(ndev, offset);
120 err = nitrox_cmdq_init(cmdq, PKTIN_Q_ALIGN_BYTES);
127 nitrox_free_pktin_queues(ndev);
131 static int create_crypto_dma_pool(struct nitrox_device *ndev)
135 /* Crypto context pool, 16 byte aligned */
136 size = CRYPTO_CTX_SIZE + sizeof(struct ctx_hdr);
137 ndev->ctx_pool = dma_pool_create("nitrox-context",
138 DEV(ndev), size, 16, 0);
145 static void destroy_crypto_dma_pool(struct nitrox_device *ndev)
150 dma_pool_destroy(ndev->ctx_pool);
151 ndev->ctx_pool = NULL;
155 * crypto_alloc_context - Allocate crypto context from pool
156 * @ndev: NITROX Device
158 void *crypto_alloc_context(struct nitrox_device *ndev)
161 struct crypto_ctx_hdr *chdr;
165 chdr = kmalloc(sizeof(*chdr), GFP_KERNEL);
169 vaddr = dma_pool_zalloc(ndev->ctx_pool, GFP_KERNEL, &dma);
177 ctx->pool = ndev->ctx_pool;
179 ctx->ctx_dma = dma + sizeof(struct ctx_hdr);
181 chdr->pool = ndev->ctx_pool;
189 * crypto_free_context - Free crypto context to pool
190 * @ctx: context to free
192 void crypto_free_context(void *ctx)
194 struct crypto_ctx_hdr *ctxp;
200 dma_pool_free(ctxp->pool, ctxp->vaddr, ctxp->dma);
205 * nitrox_common_sw_init - allocate software resources.
206 * @ndev: NITROX device
208 * Allocates crypto context pools and command queues etc.
210 * Return: 0 on success, or a negative error code on error.
212 int nitrox_common_sw_init(struct nitrox_device *ndev)
216 /* per device crypto context pool */
217 err = create_crypto_dma_pool(ndev);
221 err = nitrox_alloc_pktin_queues(ndev);
223 destroy_crypto_dma_pool(ndev);
229 * nitrox_common_sw_cleanup - free software resources.
230 * @ndev: NITROX device
232 void nitrox_common_sw_cleanup(struct nitrox_device *ndev)
234 nitrox_free_pktin_queues(ndev);
235 destroy_crypto_dma_pool(ndev);