]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blame - drivers/crypto/cavium/nitrox/nitrox_lib.c
License cleanup: add SPDX GPL-2.0 license identifier to files with no license
[mirror_ubuntu-bionic-kernel.git] / drivers / crypto / cavium / nitrox / nitrox_lib.c
CommitLineData
b2441318 1// SPDX-License-Identifier: GPL-2.0
14fa93cd
SJ
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
13#include "nitrox_dev.h"
14#include "nitrox_common.h"
15#include "nitrox_req.h"
16#include "nitrox_csr.h"
17
18#define CRYPTO_CTX_SIZE 256
19
20/* command queue alignments */
21#define PKT_IN_ALIGN 16
22
23static int cmdq_common_init(struct nitrox_cmdq *cmdq)
24{
25 struct nitrox_device *ndev = cmdq->ndev;
26 u32 qsize;
27
28 qsize = (ndev->qlen) * cmdq->instr_size;
29 cmdq->head_unaligned = dma_zalloc_coherent(DEV(ndev),
30 (qsize + PKT_IN_ALIGN),
31 &cmdq->dma_unaligned,
32 GFP_KERNEL);
33 if (!cmdq->head_unaligned)
34 return -ENOMEM;
35
36 cmdq->head = PTR_ALIGN(cmdq->head_unaligned, PKT_IN_ALIGN);
37 cmdq->dma = PTR_ALIGN(cmdq->dma_unaligned, PKT_IN_ALIGN);
38 cmdq->qsize = (qsize + PKT_IN_ALIGN);
39
40 spin_lock_init(&cmdq->response_lock);
41 spin_lock_init(&cmdq->cmdq_lock);
42 spin_lock_init(&cmdq->backlog_lock);
43
44 INIT_LIST_HEAD(&cmdq->response_head);
45 INIT_LIST_HEAD(&cmdq->backlog_head);
46 INIT_WORK(&cmdq->backlog_qflush, backlog_qflush_work);
47
48 atomic_set(&cmdq->pending_count, 0);
49 atomic_set(&cmdq->backlog_count, 0);
50 return 0;
51}
52
53static void cmdq_common_cleanup(struct nitrox_cmdq *cmdq)
54{
55 struct nitrox_device *ndev = cmdq->ndev;
56
57 cancel_work_sync(&cmdq->backlog_qflush);
58
59 dma_free_coherent(DEV(ndev), cmdq->qsize,
60 cmdq->head_unaligned, cmdq->dma_unaligned);
61
62 atomic_set(&cmdq->pending_count, 0);
63 atomic_set(&cmdq->backlog_count, 0);
64
65 cmdq->dbell_csr_addr = NULL;
66 cmdq->head = NULL;
67 cmdq->dma = 0;
68 cmdq->qsize = 0;
69 cmdq->instr_size = 0;
70}
71
72static void nitrox_cleanup_pkt_cmdqs(struct nitrox_device *ndev)
73{
74 int i;
75
76 for (i = 0; i < ndev->nr_queues; i++) {
77 struct nitrox_cmdq *cmdq = &ndev->pkt_cmdqs[i];
78
79 cmdq_common_cleanup(cmdq);
80 }
81 kfree(ndev->pkt_cmdqs);
82 ndev->pkt_cmdqs = NULL;
83}
84
85static int nitrox_init_pkt_cmdqs(struct nitrox_device *ndev)
86{
87 int i, err, size;
88
89 size = ndev->nr_queues * sizeof(struct nitrox_cmdq);
90 ndev->pkt_cmdqs = kzalloc(size, GFP_KERNEL);
91 if (!ndev->pkt_cmdqs)
92 return -ENOMEM;
93
94 for (i = 0; i < ndev->nr_queues; i++) {
95 struct nitrox_cmdq *cmdq;
96 u64 offset;
97
98 cmdq = &ndev->pkt_cmdqs[i];
99 cmdq->ndev = ndev;
100 cmdq->qno = i;
101 cmdq->instr_size = sizeof(struct nps_pkt_instr);
102
103 offset = NPS_PKT_IN_INSTR_BAOFF_DBELLX(i);
104 /* SE ring doorbell address for this queue */
105 cmdq->dbell_csr_addr = NITROX_CSR_ADDR(ndev, offset);
106
107 err = cmdq_common_init(cmdq);
108 if (err)
109 goto pkt_cmdq_fail;
110 }
111 return 0;
112
113pkt_cmdq_fail:
114 nitrox_cleanup_pkt_cmdqs(ndev);
115 return err;
116}
117
118static int create_crypto_dma_pool(struct nitrox_device *ndev)
119{
120 size_t size;
121
122 /* Crypto context pool, 16 byte aligned */
123 size = CRYPTO_CTX_SIZE + sizeof(struct ctx_hdr);
124 ndev->ctx_pool = dma_pool_create("crypto-context",
125 DEV(ndev), size, 16, 0);
126 if (!ndev->ctx_pool)
127 return -ENOMEM;
128
129 return 0;
130}
131
132static void destroy_crypto_dma_pool(struct nitrox_device *ndev)
133{
134 if (!ndev->ctx_pool)
135 return;
136
137 dma_pool_destroy(ndev->ctx_pool);
138 ndev->ctx_pool = NULL;
139}
140
f2663872
SJ
141/*
142 * crypto_alloc_context - Allocate crypto context from pool
143 * @ndev: NITROX Device
144 */
145void *crypto_alloc_context(struct nitrox_device *ndev)
146{
147 struct ctx_hdr *ctx;
148 void *vaddr;
149 dma_addr_t dma;
150
151 vaddr = dma_pool_alloc(ndev->ctx_pool, (GFP_ATOMIC | __GFP_ZERO), &dma);
152 if (!vaddr)
153 return NULL;
154
155 /* fill meta data */
156 ctx = vaddr;
157 ctx->pool = ndev->ctx_pool;
158 ctx->dma = dma;
159 ctx->ctx_dma = dma + sizeof(struct ctx_hdr);
160
161 return ((u8 *)vaddr + sizeof(struct ctx_hdr));
162}
163
164/**
165 * crypto_free_context - Free crypto context to pool
166 * @ctx: context to free
167 */
168void crypto_free_context(void *ctx)
169{
170 struct ctx_hdr *ctxp;
171
172 if (!ctx)
173 return;
174
175 ctxp = (struct ctx_hdr *)((u8 *)ctx - sizeof(struct ctx_hdr));
176 dma_pool_free(ctxp->pool, ctxp, ctxp->dma);
177}
178
14fa93cd
SJ
179/**
180 * nitrox_common_sw_init - allocate software resources.
181 * @ndev: NITROX device
182 *
183 * Allocates crypto context pools and command queues etc.
184 *
185 * Return: 0 on success, or a negative error code on error.
186 */
187int nitrox_common_sw_init(struct nitrox_device *ndev)
188{
189 int err = 0;
190
191 /* per device crypto context pool */
192 err = create_crypto_dma_pool(ndev);
193 if (err)
194 return err;
195
196 err = nitrox_init_pkt_cmdqs(ndev);
197 if (err)
198 destroy_crypto_dma_pool(ndev);
199
200 return err;
201}
202
203/**
204 * nitrox_common_sw_cleanup - free software resources.
205 * @ndev: NITROX device
206 */
207void nitrox_common_sw_cleanup(struct nitrox_device *ndev)
208{
209 nitrox_cleanup_pkt_cmdqs(ndev);
210 destroy_crypto_dma_pool(ndev);
211}