e4727509484004e37598ec83f32836b40e2596b3
[dpdk.git] / drivers / crypto / nitrox / nitrox_sym_reqmgr.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(C) 2019 Marvell International Ltd.
3  */
4
5 #include <rte_crypto.h>
6 #include <rte_cryptodev.h>
7 #include <rte_cycles.h>
8 #include <rte_errno.h>
9
10 #include "nitrox_sym_reqmgr.h"
11 #include "nitrox_logs.h"
12
13 #define PENDING_SIG 0xFFFFFFFFFFFFFFFFUL
14 #define CMD_TIMEOUT 2
15
16 union pkt_instr_hdr {
17         uint64_t value;
18         struct {
19 #if RTE_BYTE_ORDER == RTE_BIG_ENDIAN
20                 uint64_t raz_48_63 : 16;
21                 uint64_t g : 1;
22                 uint64_t gsz : 7;
23                 uint64_t ihi : 1;
24                 uint64_t ssz : 7;
25                 uint64_t raz_30_31 : 2;
26                 uint64_t fsz : 6;
27                 uint64_t raz_16_23 : 8;
28                 uint64_t tlen : 16;
29 #else
30                 uint64_t tlen : 16;
31                 uint64_t raz_16_23 : 8;
32                 uint64_t fsz : 6;
33                 uint64_t raz_30_31 : 2;
34                 uint64_t ssz : 7;
35                 uint64_t ihi : 1;
36                 uint64_t gsz : 7;
37                 uint64_t g : 1;
38                 uint64_t raz_48_63 : 16;
39 #endif
40         } s;
41 };
42
43 union pkt_hdr {
44         uint64_t value[2];
45         struct {
46 #if RTE_BYTE_ORDER == RTE_BIG_ENDIAN
47                 uint64_t opcode : 8;
48                 uint64_t arg : 8;
49                 uint64_t ctxc : 2;
50                 uint64_t unca : 1;
51                 uint64_t raz_44 : 1;
52                 uint64_t info : 3;
53                 uint64_t destport : 9;
54                 uint64_t unc : 8;
55                 uint64_t raz_19_23 : 5;
56                 uint64_t grp : 3;
57                 uint64_t raz_15 : 1;
58                 uint64_t ctxl : 7;
59                 uint64_t uddl : 8;
60 #else
61                 uint64_t uddl : 8;
62                 uint64_t ctxl : 7;
63                 uint64_t raz_15 : 1;
64                 uint64_t grp : 3;
65                 uint64_t raz_19_23 : 5;
66                 uint64_t unc : 8;
67                 uint64_t destport : 9;
68                 uint64_t info : 3;
69                 uint64_t raz_44 : 1;
70                 uint64_t unca : 1;
71                 uint64_t ctxc : 2;
72                 uint64_t arg : 8;
73                 uint64_t opcode : 8;
74 #endif
75                 uint64_t ctxp;
76         } s;
77 };
78
79 union slc_store_info {
80         uint64_t value[2];
81         struct {
82 #if RTE_BYTE_ORDER == RTE_BIG_ENDIAN
83                 uint64_t raz_39_63 : 25;
84                 uint64_t ssz : 7;
85                 uint64_t raz_0_31 : 32;
86 #else
87                 uint64_t raz_0_31 : 32;
88                 uint64_t ssz : 7;
89                 uint64_t raz_39_63 : 25;
90 #endif
91                 uint64_t rptr;
92         } s;
93 };
94
95 struct nps_pkt_instr {
96         uint64_t dptr0;
97         union pkt_instr_hdr ih;
98         union pkt_hdr irh;
99         union slc_store_info slc;
100         uint64_t fdata[2];
101 };
102
103 struct resp_hdr {
104         uint64_t orh;
105         uint64_t completion;
106 };
107
108 struct nitrox_softreq {
109         struct nitrox_crypto_ctx *ctx;
110         struct rte_crypto_op *op;
111         struct nps_pkt_instr instr;
112         struct resp_hdr resp;
113         uint64_t timeout;
114         rte_iova_t iova;
115 };
116
117 static void
118 softreq_init(struct nitrox_softreq *sr, rte_iova_t iova)
119 {
120         memset(sr, 0, sizeof(*sr));
121         sr->iova = iova;
122 }
123
124 static int
125 process_cipher_auth_data(struct nitrox_softreq *sr)
126 {
127         RTE_SET_USED(sr);
128         return 0;
129 }
130
131 static int
132 process_softreq(struct nitrox_softreq *sr)
133 {
134         struct nitrox_crypto_ctx *ctx = sr->ctx;
135         int err = 0;
136
137         switch (ctx->nitrox_chain) {
138         case NITROX_CHAIN_CIPHER_AUTH:
139         case NITROX_CHAIN_AUTH_CIPHER:
140                 err = process_cipher_auth_data(sr);
141                 break;
142         default:
143                 err = -EINVAL;
144                 break;
145         }
146
147         return err;
148 }
149
150 int
151 nitrox_process_se_req(uint16_t qno, struct rte_crypto_op *op,
152                       struct nitrox_crypto_ctx *ctx,
153                       struct nitrox_softreq *sr)
154 {
155         RTE_SET_USED(qno);
156         softreq_init(sr, sr->iova);
157         sr->ctx = ctx;
158         sr->op = op;
159         process_softreq(sr);
160         sr->timeout = rte_get_timer_cycles() + CMD_TIMEOUT * rte_get_timer_hz();
161         return 0;
162 }
163
164 int
165 nitrox_check_se_req(struct nitrox_softreq *sr, struct rte_crypto_op **op)
166 {
167         uint64_t cc;
168         uint64_t orh;
169         int err;
170
171         cc = *(volatile uint64_t *)(&sr->resp.completion);
172         orh = *(volatile uint64_t *)(&sr->resp.orh);
173         if (cc != PENDING_SIG)
174                 err = 0;
175         else if ((orh != PENDING_SIG) && (orh & 0xff))
176                 err = orh & 0xff;
177         else if (rte_get_timer_cycles() >= sr->timeout)
178                 err = 0xff;
179         else
180                 return -EAGAIN;
181
182         if (unlikely(err))
183                 NITROX_LOG(ERR, "Request err 0x%x, orh 0x%"PRIx64"\n", err,
184                            sr->resp.orh);
185
186         *op = sr->op;
187         return err;
188 }
189
190 void *
191 nitrox_sym_instr_addr(struct nitrox_softreq *sr)
192 {
193         return &sr->instr;
194 }
195
196 static void
197 req_pool_obj_init(__rte_unused struct rte_mempool *mp,
198                   __rte_unused void *opaque, void *obj,
199                   __rte_unused unsigned int obj_idx)
200 {
201         softreq_init(obj, rte_mempool_virt2iova(obj));
202 }
203
204 struct rte_mempool *
205 nitrox_sym_req_pool_create(struct rte_cryptodev *cdev, uint32_t nobjs,
206                            uint16_t qp_id, int socket_id)
207 {
208         char softreq_pool_name[RTE_RING_NAMESIZE];
209         struct rte_mempool *mp;
210
211         snprintf(softreq_pool_name, RTE_RING_NAMESIZE, "%s_sr_%d",
212                  cdev->data->name, qp_id);
213         mp = rte_mempool_create(softreq_pool_name,
214                                 RTE_ALIGN_MUL_CEIL(nobjs, 64),
215                                 sizeof(struct nitrox_softreq),
216                                 64, 0, NULL, NULL, req_pool_obj_init, NULL,
217                                 socket_id, 0);
218         if (unlikely(!mp))
219                 NITROX_LOG(ERR, "Failed to create req pool, qid %d, err %d\n",
220                            qp_id, rte_errno);
221
222         return mp;
223 }
224
225 void
226 nitrox_sym_req_pool_free(struct rte_mempool *mp)
227 {
228         rte_mempool_free(mp);
229 }