]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/dev/safexcel/safexcel.c
Merge bmake-20210206
[FreeBSD/FreeBSD.git] / sys / dev / safexcel / safexcel.c
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3  *
4  * Copyright (c) 2020, 2021 Rubicon Communications, LLC (Netgate)
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  */
26
27 #include <sys/cdefs.h>
28 __FBSDID("$FreeBSD$");
29
30 #include <sys/param.h>
31 #include <sys/bus.h>
32 #include <sys/counter.h>
33 #include <sys/endian.h>
34 #include <sys/kernel.h>
35 #include <sys/lock.h>
36 #include <sys/malloc.h>
37 #include <sys/module.h>
38 #include <sys/mutex.h>
39 #include <sys/rman.h>
40 #include <sys/smp.h>
41 #include <sys/sglist.h>
42 #include <sys/sysctl.h>
43
44 #include <machine/atomic.h>
45 #include <machine/bus.h>
46
47 #include <crypto/rijndael/rijndael.h>
48 #include <opencrypto/cryptodev.h>
49 #include <opencrypto/xform.h>
50
51 #include <dev/ofw/ofw_bus.h>
52 #include <dev/ofw/ofw_bus_subr.h>
53
54 #include "cryptodev_if.h"
55
56 #include "safexcel_reg.h"
57 #include "safexcel_var.h"
58
59 /*
60  * We only support the EIP97 for now.
61  */
62 static struct ofw_compat_data safexcel_compat[] = {
63         { "inside-secure,safexcel-eip97ies",    (uintptr_t)97 },
64         { "inside-secure,safexcel-eip97",       (uintptr_t)97 },
65         { NULL,                                 0 }
66 };
67
68 const struct safexcel_reg_offsets eip97_regs_offset = {
69         .hia_aic        = SAFEXCEL_EIP97_HIA_AIC_BASE,
70         .hia_aic_g      = SAFEXCEL_EIP97_HIA_AIC_G_BASE,
71         .hia_aic_r      = SAFEXCEL_EIP97_HIA_AIC_R_BASE,
72         .hia_aic_xdr    = SAFEXCEL_EIP97_HIA_AIC_xDR_BASE,
73         .hia_dfe        = SAFEXCEL_EIP97_HIA_DFE_BASE,
74         .hia_dfe_thr    = SAFEXCEL_EIP97_HIA_DFE_THR_BASE,
75         .hia_dse        = SAFEXCEL_EIP97_HIA_DSE_BASE,
76         .hia_dse_thr    = SAFEXCEL_EIP97_HIA_DSE_THR_BASE,
77         .hia_gen_cfg    = SAFEXCEL_EIP97_HIA_GEN_CFG_BASE,
78         .pe             = SAFEXCEL_EIP97_PE_BASE,
79 };
80
81 const struct safexcel_reg_offsets eip197_regs_offset = {
82         .hia_aic        = SAFEXCEL_EIP197_HIA_AIC_BASE,
83         .hia_aic_g      = SAFEXCEL_EIP197_HIA_AIC_G_BASE,
84         .hia_aic_r      = SAFEXCEL_EIP197_HIA_AIC_R_BASE,
85         .hia_aic_xdr    = SAFEXCEL_EIP197_HIA_AIC_xDR_BASE,
86         .hia_dfe        = SAFEXCEL_EIP197_HIA_DFE_BASE,
87         .hia_dfe_thr    = SAFEXCEL_EIP197_HIA_DFE_THR_BASE,
88         .hia_dse        = SAFEXCEL_EIP197_HIA_DSE_BASE,
89         .hia_dse_thr    = SAFEXCEL_EIP197_HIA_DSE_THR_BASE,
90         .hia_gen_cfg    = SAFEXCEL_EIP197_HIA_GEN_CFG_BASE,
91         .pe             = SAFEXCEL_EIP197_PE_BASE,
92 };
93
94 static struct safexcel_request *
95 safexcel_next_request(struct safexcel_ring *ring)
96 {
97         int i;
98
99         i = ring->cdr.read;
100         KASSERT(i >= 0 && i < SAFEXCEL_RING_SIZE,
101             ("%s: out of bounds request index %d", __func__, i));
102         return (&ring->requests[i]);
103 }
104
105 static struct safexcel_cmd_descr *
106 safexcel_cmd_descr_next(struct safexcel_cmd_descr_ring *ring)
107 {
108         struct safexcel_cmd_descr *cdesc;
109
110         if (ring->write == ring->read)
111                 return (NULL);
112         cdesc = &ring->desc[ring->read];
113         ring->read = (ring->read + 1) % SAFEXCEL_RING_SIZE;
114         return (cdesc);
115 }
116
117 static struct safexcel_res_descr *
118 safexcel_res_descr_next(struct safexcel_res_descr_ring *ring)
119 {
120         struct safexcel_res_descr *rdesc;
121
122         if (ring->write == ring->read)
123                 return (NULL);
124         rdesc = &ring->desc[ring->read];
125         ring->read = (ring->read + 1) % SAFEXCEL_RING_SIZE;
126         return (rdesc);
127 }
128
129 static struct safexcel_request *
130 safexcel_alloc_request(struct safexcel_softc *sc, struct safexcel_ring *ring)
131 {
132         int i;
133
134         mtx_assert(&ring->mtx, MA_OWNED);
135
136         i = ring->cdr.write;
137         if ((i + 1) % SAFEXCEL_RING_SIZE == ring->cdr.read)
138                 return (NULL);
139         return (&ring->requests[i]);
140 }
141
142 static void
143 safexcel_free_request(struct safexcel_ring *ring, struct safexcel_request *req)
144 {
145         struct safexcel_context_record *ctx;
146
147         mtx_assert(&ring->mtx, MA_OWNED);
148
149         if (req->dmap_loaded) {
150                 bus_dmamap_unload(ring->data_dtag, req->dmap);
151                 req->dmap_loaded = false;
152         }
153         ctx = (struct safexcel_context_record *)req->ctx.vaddr;
154         explicit_bzero(ctx->data, sizeof(ctx->data));
155         explicit_bzero(req->iv, sizeof(req->iv));
156 }
157
158 static void
159 safexcel_rdr_intr(struct safexcel_softc *sc, int ringidx)
160 {
161         TAILQ_HEAD(, cryptop) cq;
162         struct cryptop *crp, *tmp;
163         struct safexcel_cmd_descr *cdesc;
164         struct safexcel_res_descr *rdesc;
165         struct safexcel_request *req;
166         struct safexcel_ring *ring;
167         uint32_t blocked, error, i, ncdescs, nrdescs, nreqs;
168
169         blocked = 0;
170         ring = &sc->sc_ring[ringidx];
171
172         nreqs = SAFEXCEL_READ(sc,
173             SAFEXCEL_HIA_RDR(sc, ringidx) + SAFEXCEL_HIA_xDR_PROC_COUNT);
174         nreqs >>= SAFEXCEL_xDR_PROC_xD_PKT_OFFSET;
175         nreqs &= SAFEXCEL_xDR_PROC_xD_PKT_MASK;
176         if (nreqs == 0) {
177                 SAFEXCEL_DPRINTF(sc, 1,
178                     "zero pending requests on ring %d\n", ringidx);
179                 mtx_lock(&ring->mtx);
180                 goto out;
181         }
182
183         TAILQ_INIT(&cq);
184
185         ring = &sc->sc_ring[ringidx];
186         bus_dmamap_sync(ring->rdr.dma.tag, ring->rdr.dma.map,
187             BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
188         bus_dmamap_sync(ring->cdr.dma.tag, ring->cdr.dma.map,
189             BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
190         bus_dmamap_sync(ring->dma_atok.tag, ring->dma_atok.map,
191             BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
192
193         ncdescs = nrdescs = 0;
194         for (i = 0; i < nreqs; i++) {
195                 req = safexcel_next_request(ring);
196
197                 bus_dmamap_sync(req->ctx.tag, req->ctx.map,
198                     BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
199                 bus_dmamap_sync(ring->data_dtag, req->dmap,
200                     BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
201
202                 ncdescs += req->cdescs;
203                 while (req->cdescs-- > 0) {
204                         cdesc = safexcel_cmd_descr_next(&ring->cdr);
205                         KASSERT(cdesc != NULL,
206                             ("%s: missing control descriptor", __func__));
207                         if (req->cdescs == 0)
208                                 KASSERT(cdesc->last_seg,
209                                     ("%s: chain is not terminated", __func__));
210                 }
211                 nrdescs += req->rdescs;
212                 while (req->rdescs-- > 0) {
213                         rdesc = safexcel_res_descr_next(&ring->rdr);
214                         error = rdesc->result_data.error_code;
215                         if (error != 0) {
216                                 if (error == SAFEXCEL_RESULT_ERR_AUTH_FAILED &&
217                                     req->crp->crp_etype == 0) {
218                                         req->crp->crp_etype = EBADMSG;
219                                 } else {
220                                         SAFEXCEL_DPRINTF(sc, 1,
221                                             "error code %#x\n", error);
222                                         req->crp->crp_etype = EIO;
223                                 }
224                         }
225                 }
226
227                 TAILQ_INSERT_TAIL(&cq, req->crp, crp_next);
228         }
229
230         mtx_lock(&ring->mtx);
231         if (nreqs != 0) {
232                 KASSERT(ring->queued >= nreqs,
233                     ("%s: request count underflow, %d queued %d completed",
234                     __func__, ring->queued, nreqs));
235                 ring->queued -= nreqs;
236
237                 SAFEXCEL_WRITE(sc,
238                     SAFEXCEL_HIA_RDR(sc, ringidx) + SAFEXCEL_HIA_xDR_PROC_COUNT,
239                     SAFEXCEL_xDR_PROC_xD_PKT(nreqs) |
240                     (sc->sc_config.rd_offset * nrdescs * sizeof(uint32_t)));
241                 blocked = ring->blocked;
242                 ring->blocked = 0;
243         }
244 out:
245         if (ring->queued != 0) {
246                 SAFEXCEL_WRITE(sc,
247                     SAFEXCEL_HIA_RDR(sc, ringidx) + SAFEXCEL_HIA_xDR_THRESH,
248                     SAFEXCEL_HIA_CDR_THRESH_PKT_MODE | imin(ring->queued, 16));
249         }
250         mtx_unlock(&ring->mtx);
251
252         if (blocked)
253                 crypto_unblock(sc->sc_cid, blocked);
254
255         TAILQ_FOREACH_SAFE(crp, &cq, crp_next, tmp)
256                 crypto_done(crp);
257 }
258
259 static void
260 safexcel_ring_intr(void *arg)
261 {
262         struct safexcel_softc *sc;
263         struct safexcel_intr_handle *ih;
264         uint32_t status, stat;
265         int ring;
266         bool rdrpending;
267
268         ih = arg;
269         sc = ih->sc;
270         ring = ih->ring;
271
272         status = SAFEXCEL_READ(sc, SAFEXCEL_HIA_AIC_R(sc) +
273             SAFEXCEL_HIA_AIC_R_ENABLED_STAT(ring));
274         /* CDR interrupts */
275         if (status & SAFEXCEL_CDR_IRQ(ring)) {
276                 stat = SAFEXCEL_READ(sc,
277                     SAFEXCEL_HIA_CDR(sc, ring) + SAFEXCEL_HIA_xDR_STAT);
278                 SAFEXCEL_WRITE(sc,
279                     SAFEXCEL_HIA_CDR(sc, ring) + SAFEXCEL_HIA_xDR_STAT,
280                     stat & SAFEXCEL_CDR_INTR_MASK);
281         }
282         /* RDR interrupts */
283         rdrpending = false;
284         if (status & SAFEXCEL_RDR_IRQ(ring)) {
285                 stat = SAFEXCEL_READ(sc,
286                     SAFEXCEL_HIA_RDR(sc, ring) + SAFEXCEL_HIA_xDR_STAT);
287                 if ((stat & SAFEXCEL_xDR_ERR) == 0)
288                         rdrpending = true;
289                 SAFEXCEL_WRITE(sc,
290                     SAFEXCEL_HIA_RDR(sc, ring) + SAFEXCEL_HIA_xDR_STAT,
291                     stat & SAFEXCEL_RDR_INTR_MASK);
292         }
293         SAFEXCEL_WRITE(sc,
294             SAFEXCEL_HIA_AIC_R(sc) + SAFEXCEL_HIA_AIC_R_ACK(ring),
295             status);
296
297         if (rdrpending)
298                 safexcel_rdr_intr(sc, ring);
299 }
300
301 static int
302 safexcel_configure(struct safexcel_softc *sc)
303 {
304         uint32_t i, mask, pemask, reg;
305         device_t dev;
306
307         if (sc->sc_type == 197) {
308                 sc->sc_offsets = eip197_regs_offset;
309                 pemask = SAFEXCEL_N_PES_MASK;
310         } else {
311                 sc->sc_offsets = eip97_regs_offset;
312                 pemask = EIP97_N_PES_MASK;
313         }
314
315         dev = sc->sc_dev;
316
317         /* Scan for valid ring interrupt controllers. */
318         for (i = 0; i < SAFEXCEL_MAX_RING_AIC; i++) {
319                 reg = SAFEXCEL_READ(sc, SAFEXCEL_HIA_AIC_R(sc) +
320                     SAFEXCEL_HIA_AIC_R_VERSION(i));
321                 if (SAFEXCEL_REG_LO16(reg) != EIP201_VERSION_LE)
322                         break;
323         }
324         sc->sc_config.aic_rings = i;
325         if (sc->sc_config.aic_rings == 0)
326                 return (-1);
327
328         reg = SAFEXCEL_READ(sc, SAFEXCEL_HIA_AIC_G(sc) + SAFEXCEL_HIA_OPTIONS);
329         /* Check for 64bit addressing. */
330         if ((reg & SAFEXCEL_OPT_ADDR_64) == 0)
331                 return (-1);
332         /* Check alignment constraints (which we do not support). */
333         if (((reg & SAFEXCEL_OPT_TGT_ALIGN_MASK) >>
334             SAFEXCEL_OPT_TGT_ALIGN_OFFSET) != 0)
335                 return (-1);
336
337         sc->sc_config.hdw =
338             (reg & SAFEXCEL_xDR_HDW_MASK) >> SAFEXCEL_xDR_HDW_OFFSET;
339         mask = (1 << sc->sc_config.hdw) - 1;
340
341         sc->sc_config.rings = reg & SAFEXCEL_N_RINGS_MASK;
342         /* Limit the number of rings to the number of the AIC Rings. */
343         sc->sc_config.rings = MIN(sc->sc_config.rings, sc->sc_config.aic_rings);
344
345         sc->sc_config.pes = (reg & pemask) >> SAFEXCEL_N_PES_OFFSET;
346
347         sc->sc_config.cd_size =
348             sizeof(struct safexcel_cmd_descr) / sizeof(uint32_t);
349         sc->sc_config.cd_offset = (sc->sc_config.cd_size + mask) & ~mask;
350
351         sc->sc_config.rd_size =
352             sizeof(struct safexcel_res_descr) / sizeof(uint32_t);
353         sc->sc_config.rd_offset = (sc->sc_config.rd_size + mask) & ~mask;
354
355         sc->sc_config.atok_offset =
356             (SAFEXCEL_MAX_ATOKENS * sizeof(struct safexcel_instr) + mask) &
357             ~mask;
358
359         return (0);
360 }
361
362 static void
363 safexcel_init_hia_bus_access(struct safexcel_softc *sc)
364 {
365         uint32_t version, val;
366
367         /* Determine endianness and configure byte swap. */
368         version = SAFEXCEL_READ(sc,
369             SAFEXCEL_HIA_AIC(sc) + SAFEXCEL_HIA_VERSION);
370         val = SAFEXCEL_READ(sc, SAFEXCEL_HIA_AIC(sc) + SAFEXCEL_HIA_MST_CTRL);
371         if (SAFEXCEL_REG_HI16(version) == SAFEXCEL_HIA_VERSION_BE) {
372                 val = SAFEXCEL_READ(sc,
373                     SAFEXCEL_HIA_AIC(sc) + SAFEXCEL_HIA_MST_CTRL);
374                 val = val ^ (SAFEXCEL_MST_CTRL_NO_BYTE_SWAP >> 24);
375                 SAFEXCEL_WRITE(sc,
376                     SAFEXCEL_HIA_AIC(sc) + SAFEXCEL_HIA_MST_CTRL,
377                     val);
378         }
379
380         /* Configure wr/rd cache values. */
381         SAFEXCEL_WRITE(sc, SAFEXCEL_HIA_GEN_CFG(sc) + SAFEXCEL_HIA_MST_CTRL,
382             SAFEXCEL_MST_CTRL_RD_CACHE(RD_CACHE_4BITS) |
383             SAFEXCEL_MST_CTRL_WD_CACHE(WR_CACHE_4BITS));
384 }
385
386 static void
387 safexcel_disable_global_interrupts(struct safexcel_softc *sc)
388 {
389         /* Disable and clear pending interrupts. */
390         SAFEXCEL_WRITE(sc,
391             SAFEXCEL_HIA_AIC_G(sc) + SAFEXCEL_HIA_AIC_G_ENABLE_CTRL, 0);
392         SAFEXCEL_WRITE(sc,
393             SAFEXCEL_HIA_AIC_G(sc) + SAFEXCEL_HIA_AIC_G_ACK,
394             SAFEXCEL_AIC_G_ACK_ALL_MASK);
395 }
396
397 /*
398  * Configure the data fetch engine.  This component parses command descriptors
399  * and sets up DMA transfers from host memory to the corresponding processing
400  * engine.
401  */
402 static void
403 safexcel_configure_dfe_engine(struct safexcel_softc *sc, int pe)
404 {
405         /* Reset all DFE threads. */
406         SAFEXCEL_WRITE(sc,
407             SAFEXCEL_HIA_DFE_THR(sc) + SAFEXCEL_HIA_DFE_THR_CTRL(pe),
408             SAFEXCEL_DxE_THR_CTRL_RESET_PE);
409
410         /* Deassert the DFE reset. */
411         SAFEXCEL_WRITE(sc,
412             SAFEXCEL_HIA_DFE_THR(sc) + SAFEXCEL_HIA_DFE_THR_CTRL(pe), 0);
413
414         /* DMA transfer size to use. */
415         SAFEXCEL_WRITE(sc, SAFEXCEL_HIA_DFE(sc) + SAFEXCEL_HIA_DFE_CFG(pe),
416             SAFEXCEL_HIA_DFE_CFG_DIS_DEBUG |
417             SAFEXCEL_HIA_DxE_CFG_MIN_DATA_SIZE(6) |
418             SAFEXCEL_HIA_DxE_CFG_MAX_DATA_SIZE(9) |
419             SAFEXCEL_HIA_DxE_CFG_MIN_CTRL_SIZE(6) |
420             SAFEXCEL_HIA_DxE_CFG_MAX_CTRL_SIZE(7) |
421             SAFEXCEL_HIA_DxE_CFG_DATA_CACHE_CTRL(RD_CACHE_3BITS) |
422             SAFEXCEL_HIA_DxE_CFG_CTRL_CACHE_CTRL(RD_CACHE_3BITS));
423
424         /* Configure the PE DMA transfer thresholds. */
425         SAFEXCEL_WRITE(sc, SAFEXCEL_PE(sc) + SAFEXCEL_PE_IN_DBUF_THRES(pe),
426             SAFEXCEL_PE_IN_xBUF_THRES_MIN(6) |
427             SAFEXCEL_PE_IN_xBUF_THRES_MAX(9));
428         SAFEXCEL_WRITE(sc, SAFEXCEL_PE(sc) + SAFEXCEL_PE_IN_TBUF_THRES(pe),
429             SAFEXCEL_PE_IN_xBUF_THRES_MIN(6) |
430             SAFEXCEL_PE_IN_xBUF_THRES_MAX(7));
431 }
432
433 /*
434  * Configure the data store engine.  This component parses result descriptors
435  * and sets up DMA transfers from the processing engine to host memory.
436  */
437 static int
438 safexcel_configure_dse(struct safexcel_softc *sc, int pe)
439 {
440         uint32_t val;
441         int count;
442
443         /* Disable and reset all DSE threads. */
444         SAFEXCEL_WRITE(sc,
445             SAFEXCEL_HIA_DSE_THR(sc) + SAFEXCEL_HIA_DSE_THR_CTRL(pe),
446             SAFEXCEL_DxE_THR_CTRL_RESET_PE);
447
448         /* Wait for a second for threads to go idle. */
449         for (count = 0;;) {
450                 val = SAFEXCEL_READ(sc,
451                     SAFEXCEL_HIA_DSE_THR(sc) + SAFEXCEL_HIA_DSE_THR_STAT(pe));
452                 if ((val & SAFEXCEL_DSE_THR_RDR_ID_MASK) ==
453                     SAFEXCEL_DSE_THR_RDR_ID_MASK)
454                         break;
455                 if (count++ > 10000) {
456                         device_printf(sc->sc_dev, "DSE reset timeout\n");
457                         return (-1);
458                 }
459                 DELAY(100);
460         }
461
462         /* Exit the reset state. */
463         SAFEXCEL_WRITE(sc,
464             SAFEXCEL_HIA_DSE_THR(sc) + SAFEXCEL_HIA_DSE_THR_CTRL(pe), 0);
465
466         /* DMA transfer size to use */
467         SAFEXCEL_WRITE(sc, SAFEXCEL_HIA_DSE(sc) + SAFEXCEL_HIA_DSE_CFG(pe),
468             SAFEXCEL_HIA_DSE_CFG_DIS_DEBUG |
469             SAFEXCEL_HIA_DxE_CFG_MIN_DATA_SIZE(7) |
470             SAFEXCEL_HIA_DxE_CFG_MAX_DATA_SIZE(8) |
471             SAFEXCEL_HIA_DxE_CFG_DATA_CACHE_CTRL(WR_CACHE_3BITS) |
472             SAFEXCEL_HIA_DSE_CFG_ALLWAYS_BUFFERABLE);
473
474         /* Configure the procesing engine thresholds */
475         SAFEXCEL_WRITE(sc,
476             SAFEXCEL_PE(sc) + SAFEXCEL_PE_OUT_DBUF_THRES(pe),
477             SAFEXCEL_PE_OUT_DBUF_THRES_MIN(7) |
478             SAFEXCEL_PE_OUT_DBUF_THRES_MAX(8));
479
480         return (0);
481 }
482
483 static void
484 safexcel_hw_prepare_rings(struct safexcel_softc *sc)
485 {
486         int i;
487
488         for (i = 0; i < sc->sc_config.rings; i++) {
489                 /*
490                  * Command descriptors.
491                  */
492
493                 /* Clear interrupts for this ring. */
494                 SAFEXCEL_WRITE(sc,
495                     SAFEXCEL_HIA_AIC_R(sc) + SAFEXCEL_HIA_AIC_R_ENABLE_CLR(i),
496                     SAFEXCEL_HIA_AIC_R_ENABLE_CLR_ALL_MASK);
497
498                 /* Disable external triggering. */
499                 SAFEXCEL_WRITE(sc,
500                     SAFEXCEL_HIA_CDR(sc, i) + SAFEXCEL_HIA_xDR_CFG, 0);
501
502                 /* Clear the pending prepared counter. */
503                 SAFEXCEL_WRITE(sc,
504                     SAFEXCEL_HIA_CDR(sc, i) + SAFEXCEL_HIA_xDR_PREP_COUNT,
505                     SAFEXCEL_xDR_PREP_CLR_COUNT);
506
507                 /* Clear the pending processed counter. */
508                 SAFEXCEL_WRITE(sc,
509                     SAFEXCEL_HIA_CDR(sc, i) + SAFEXCEL_HIA_xDR_PROC_COUNT,
510                     SAFEXCEL_xDR_PROC_CLR_COUNT);
511
512                 SAFEXCEL_WRITE(sc,
513                     SAFEXCEL_HIA_CDR(sc, i) + SAFEXCEL_HIA_xDR_PREP_PNTR, 0);
514                 SAFEXCEL_WRITE(sc,
515                     SAFEXCEL_HIA_CDR(sc, i) + SAFEXCEL_HIA_xDR_PROC_PNTR, 0);
516
517                 SAFEXCEL_WRITE(sc,
518                     SAFEXCEL_HIA_CDR(sc, i) + SAFEXCEL_HIA_xDR_RING_SIZE,
519                     SAFEXCEL_RING_SIZE * sc->sc_config.cd_offset *
520                     sizeof(uint32_t));
521
522                 /*
523                  * Result descriptors.
524                  */
525
526                 /* Disable external triggering. */
527                 SAFEXCEL_WRITE(sc,
528                     SAFEXCEL_HIA_RDR(sc, i) + SAFEXCEL_HIA_xDR_CFG, 0);
529
530                 /* Clear the pending prepared counter. */
531                 SAFEXCEL_WRITE(sc,
532                     SAFEXCEL_HIA_RDR(sc, i) + SAFEXCEL_HIA_xDR_PREP_COUNT,
533                     SAFEXCEL_xDR_PREP_CLR_COUNT);
534
535                 /* Clear the pending processed counter. */
536                 SAFEXCEL_WRITE(sc,
537                     SAFEXCEL_HIA_RDR(sc, i) + SAFEXCEL_HIA_xDR_PROC_COUNT,
538                     SAFEXCEL_xDR_PROC_CLR_COUNT);
539
540                 SAFEXCEL_WRITE(sc,
541                     SAFEXCEL_HIA_RDR(sc, i) + SAFEXCEL_HIA_xDR_PREP_PNTR, 0);
542                 SAFEXCEL_WRITE(sc,
543                     SAFEXCEL_HIA_RDR(sc, i) + SAFEXCEL_HIA_xDR_PROC_PNTR, 0);
544
545                 /* Ring size. */
546                 SAFEXCEL_WRITE(sc,
547                     SAFEXCEL_HIA_RDR(sc, i) + SAFEXCEL_HIA_xDR_RING_SIZE,
548                     SAFEXCEL_RING_SIZE * sc->sc_config.rd_offset *
549                     sizeof(uint32_t));
550         }
551 }
552
553 static void
554 safexcel_hw_setup_rings(struct safexcel_softc *sc)
555 {
556         struct safexcel_ring *ring;
557         uint32_t cd_size_rnd, mask, rd_size_rnd, val;
558         int i;
559
560         mask = (1 << sc->sc_config.hdw) - 1;
561         cd_size_rnd = (sc->sc_config.cd_size + mask) >> sc->sc_config.hdw;
562         val = (sizeof(struct safexcel_res_descr) -
563             sizeof(struct safexcel_res_data)) / sizeof(uint32_t);
564         rd_size_rnd = (val + mask) >> sc->sc_config.hdw;
565
566         for (i = 0; i < sc->sc_config.rings; i++) {
567                 ring = &sc->sc_ring[i];
568
569                 /*
570                  * Command descriptors.
571                  */
572
573                 /* Ring base address. */
574                 SAFEXCEL_WRITE(sc, SAFEXCEL_HIA_CDR(sc, i) +
575                     SAFEXCEL_HIA_xDR_RING_BASE_ADDR_LO,
576                     SAFEXCEL_ADDR_LO(ring->cdr.dma.paddr));
577                 SAFEXCEL_WRITE(sc, SAFEXCEL_HIA_CDR(sc, i) +
578                     SAFEXCEL_HIA_xDR_RING_BASE_ADDR_HI,
579                     SAFEXCEL_ADDR_HI(ring->cdr.dma.paddr));
580
581                 SAFEXCEL_WRITE(sc,
582                     SAFEXCEL_HIA_CDR(sc, i) + SAFEXCEL_HIA_xDR_DESC_SIZE,
583                     SAFEXCEL_xDR_DESC_MODE_64BIT | SAFEXCEL_CDR_DESC_MODE_ADCP |
584                     (sc->sc_config.cd_offset << SAFEXCEL_xDR_DESC_xD_OFFSET) |
585                     sc->sc_config.cd_size);
586
587                 SAFEXCEL_WRITE(sc,
588                     SAFEXCEL_HIA_CDR(sc, i) + SAFEXCEL_HIA_xDR_CFG,
589                     ((SAFEXCEL_FETCH_COUNT * (cd_size_rnd << sc->sc_config.hdw)) <<
590                       SAFEXCEL_xDR_xD_FETCH_THRESH) |
591                     (SAFEXCEL_FETCH_COUNT * sc->sc_config.cd_offset));
592
593                 /* Configure DMA tx control. */
594                 SAFEXCEL_WRITE(sc,
595                     SAFEXCEL_HIA_CDR(sc, i) + SAFEXCEL_HIA_xDR_DMA_CFG,
596                     SAFEXCEL_HIA_xDR_CFG_WR_CACHE(WR_CACHE_3BITS) |
597                     SAFEXCEL_HIA_xDR_CFG_RD_CACHE(RD_CACHE_3BITS));
598
599                 /* Clear any pending interrupt. */
600                 SAFEXCEL_WRITE(sc,
601                     SAFEXCEL_HIA_CDR(sc, i) + SAFEXCEL_HIA_xDR_STAT,
602                     SAFEXCEL_CDR_INTR_MASK);
603
604                 /*
605                  * Result descriptors.
606                  */
607
608                 /* Ring base address. */
609                 SAFEXCEL_WRITE(sc, SAFEXCEL_HIA_RDR(sc, i) +
610                     SAFEXCEL_HIA_xDR_RING_BASE_ADDR_LO,
611                     SAFEXCEL_ADDR_LO(ring->rdr.dma.paddr));
612                 SAFEXCEL_WRITE(sc, SAFEXCEL_HIA_RDR(sc, i) +
613                     SAFEXCEL_HIA_xDR_RING_BASE_ADDR_HI,
614                     SAFEXCEL_ADDR_HI(ring->rdr.dma.paddr));
615
616                 SAFEXCEL_WRITE(sc,
617                     SAFEXCEL_HIA_RDR(sc, i) + SAFEXCEL_HIA_xDR_DESC_SIZE,
618                     SAFEXCEL_xDR_DESC_MODE_64BIT |
619                     (sc->sc_config.rd_offset << SAFEXCEL_xDR_DESC_xD_OFFSET) |
620                     sc->sc_config.rd_size);
621
622                 SAFEXCEL_WRITE(sc,
623                     SAFEXCEL_HIA_RDR(sc, i) + SAFEXCEL_HIA_xDR_CFG,
624                     ((SAFEXCEL_FETCH_COUNT * (rd_size_rnd << sc->sc_config.hdw)) <<
625                     SAFEXCEL_xDR_xD_FETCH_THRESH) |
626                     (SAFEXCEL_FETCH_COUNT * sc->sc_config.rd_offset));
627
628                 /* Configure DMA tx control. */
629                 SAFEXCEL_WRITE(sc,
630                     SAFEXCEL_HIA_RDR(sc, i) + SAFEXCEL_HIA_xDR_DMA_CFG,
631                     SAFEXCEL_HIA_xDR_CFG_WR_CACHE(WR_CACHE_3BITS) |
632                     SAFEXCEL_HIA_xDR_CFG_RD_CACHE(RD_CACHE_3BITS) |
633                     SAFEXCEL_HIA_xDR_WR_RES_BUF | SAFEXCEL_HIA_xDR_WR_CTRL_BUF);
634
635                 /* Clear any pending interrupt. */
636                 SAFEXCEL_WRITE(sc,
637                     SAFEXCEL_HIA_RDR(sc, i) + SAFEXCEL_HIA_xDR_STAT,
638                     SAFEXCEL_RDR_INTR_MASK);
639
640                 /* Enable ring interrupt. */
641                 SAFEXCEL_WRITE(sc,
642                     SAFEXCEL_HIA_AIC_R(sc) + SAFEXCEL_HIA_AIC_R_ENABLE_CTRL(i),
643                     SAFEXCEL_RDR_IRQ(i));
644         }
645 }
646
647 /* Reset the command and result descriptor rings. */
648 static void
649 safexcel_hw_reset_rings(struct safexcel_softc *sc)
650 {
651         int i;
652
653         for (i = 0; i < sc->sc_config.rings; i++) {
654                 /*
655                  * Result descriptor ring operations.
656                  */
657
658                 /* Reset ring base address. */
659                 SAFEXCEL_WRITE(sc, SAFEXCEL_HIA_RDR(sc, i) +
660                     SAFEXCEL_HIA_xDR_RING_BASE_ADDR_LO, 0);
661                 SAFEXCEL_WRITE(sc, SAFEXCEL_HIA_RDR(sc, i) +
662                     SAFEXCEL_HIA_xDR_RING_BASE_ADDR_HI, 0);
663
664                 /* Clear the pending prepared counter. */
665                 SAFEXCEL_WRITE(sc,
666                     SAFEXCEL_HIA_RDR(sc, i) + SAFEXCEL_HIA_xDR_PREP_COUNT,
667                     SAFEXCEL_xDR_PREP_CLR_COUNT);
668
669                 /* Clear the pending processed counter. */
670                 SAFEXCEL_WRITE(sc,
671                     SAFEXCEL_HIA_RDR(sc, i) + SAFEXCEL_HIA_xDR_PROC_COUNT,
672                     SAFEXCEL_xDR_PROC_CLR_COUNT);
673
674                 SAFEXCEL_WRITE(sc,
675                     SAFEXCEL_HIA_RDR(sc, i) + SAFEXCEL_HIA_xDR_PREP_PNTR, 0);
676                 SAFEXCEL_WRITE(sc,
677                     SAFEXCEL_HIA_RDR(sc, i) + SAFEXCEL_HIA_xDR_PROC_PNTR, 0);
678
679                 SAFEXCEL_WRITE(sc,
680                     SAFEXCEL_HIA_RDR(sc, i) + SAFEXCEL_HIA_xDR_RING_SIZE, 0);
681
682                 /* Clear any pending interrupt. */
683                 SAFEXCEL_WRITE(sc,
684                     SAFEXCEL_HIA_RDR(sc, i) + SAFEXCEL_HIA_xDR_STAT,
685                     SAFEXCEL_RDR_INTR_MASK);
686
687                 /* Disable ring interrupt. */
688                 SAFEXCEL_WRITE(sc,
689                     SAFEXCEL_HIA_AIC_R(sc) + SAFEXCEL_HIA_AIC_R_ENABLE_CLR(i),
690                     SAFEXCEL_RDR_IRQ(i));
691
692                 /*
693                  * Command descriptor ring operations.
694                  */
695
696                 /* Reset ring base address. */
697                 SAFEXCEL_WRITE(sc, SAFEXCEL_HIA_CDR(sc, i) +
698                     SAFEXCEL_HIA_xDR_RING_BASE_ADDR_LO, 0);
699                 SAFEXCEL_WRITE(sc, SAFEXCEL_HIA_CDR(sc, i) +
700                     SAFEXCEL_HIA_xDR_RING_BASE_ADDR_HI, 0);
701
702                 /* Clear the pending prepared counter. */
703                 SAFEXCEL_WRITE(sc,
704                     SAFEXCEL_HIA_CDR(sc, i) + SAFEXCEL_HIA_xDR_PREP_COUNT,
705                     SAFEXCEL_xDR_PREP_CLR_COUNT);
706
707                 /* Clear the pending processed counter. */
708                 SAFEXCEL_WRITE(sc,
709                     SAFEXCEL_HIA_CDR(sc, i) + SAFEXCEL_HIA_xDR_PROC_COUNT,
710                     SAFEXCEL_xDR_PROC_CLR_COUNT);
711
712                 SAFEXCEL_WRITE(sc,
713                     SAFEXCEL_HIA_CDR(sc, i) + SAFEXCEL_HIA_xDR_PREP_PNTR, 0);
714                 SAFEXCEL_WRITE(sc,
715                     SAFEXCEL_HIA_CDR(sc, i) + SAFEXCEL_HIA_xDR_PROC_PNTR, 0);
716
717                 SAFEXCEL_WRITE(sc,
718                     SAFEXCEL_HIA_CDR(sc, i) + SAFEXCEL_HIA_xDR_RING_SIZE, 0);
719
720                 /* Clear any pending interrupt. */
721                 SAFEXCEL_WRITE(sc,
722                     SAFEXCEL_HIA_CDR(sc, i) + SAFEXCEL_HIA_xDR_STAT,
723                     SAFEXCEL_CDR_INTR_MASK);
724         }
725 }
726
727 static void
728 safexcel_enable_pe_engine(struct safexcel_softc *sc, int pe)
729 {
730         int i, ring_mask;
731
732         for (ring_mask = 0, i = 0; i < sc->sc_config.rings; i++) {
733                 ring_mask <<= 1;
734                 ring_mask |= 1;
735         }
736
737         /* Enable command descriptor rings. */
738         SAFEXCEL_WRITE(sc, SAFEXCEL_HIA_DFE_THR(sc) + SAFEXCEL_HIA_DFE_THR_CTRL(pe),
739             SAFEXCEL_DxE_THR_CTRL_EN | ring_mask);
740
741         /* Enable result descriptor rings. */
742         SAFEXCEL_WRITE(sc, SAFEXCEL_HIA_DSE_THR(sc) + SAFEXCEL_HIA_DSE_THR_CTRL(pe),
743             SAFEXCEL_DxE_THR_CTRL_EN | ring_mask);
744
745         /* Clear any HIA interrupt. */
746         SAFEXCEL_WRITE(sc, SAFEXCEL_HIA_AIC_G(sc) + SAFEXCEL_HIA_AIC_G_ACK,
747             SAFEXCEL_AIC_G_ACK_HIA_MASK);
748 }
749
750 static void
751 safexcel_execute(struct safexcel_softc *sc, struct safexcel_ring *ring,
752     struct safexcel_request *req, int hint)
753 {
754         int ringidx, ncdesc, nrdesc;
755         bool busy;
756
757         mtx_assert(&ring->mtx, MA_OWNED);
758
759         if ((hint & CRYPTO_HINT_MORE) != 0) {
760                 ring->pending++;
761                 ring->pending_cdesc += req->cdescs;
762                 ring->pending_rdesc += req->rdescs;
763                 return;
764         }
765
766         ringidx = req->ringidx;
767
768         busy = ring->queued != 0;
769         ncdesc = ring->pending_cdesc + req->cdescs;
770         nrdesc = ring->pending_rdesc + req->rdescs;
771         ring->queued += ring->pending + 1;
772
773         if (!busy) {
774                 SAFEXCEL_WRITE(sc,
775                     SAFEXCEL_HIA_RDR(sc, ringidx) + SAFEXCEL_HIA_xDR_THRESH,
776                     SAFEXCEL_HIA_CDR_THRESH_PKT_MODE | ring->queued);
777         }
778         SAFEXCEL_WRITE(sc,
779             SAFEXCEL_HIA_RDR(sc, ringidx) + SAFEXCEL_HIA_xDR_PREP_COUNT,
780             nrdesc * sc->sc_config.rd_offset * sizeof(uint32_t));
781         SAFEXCEL_WRITE(sc,
782             SAFEXCEL_HIA_CDR(sc, ringidx) + SAFEXCEL_HIA_xDR_PREP_COUNT,
783             ncdesc * sc->sc_config.cd_offset * sizeof(uint32_t));
784
785         ring->pending = ring->pending_cdesc = ring->pending_rdesc = 0;
786 }
787
788 static void
789 safexcel_init_rings(struct safexcel_softc *sc)
790 {
791         struct safexcel_cmd_descr *cdesc;
792         struct safexcel_ring *ring;
793         uint64_t atok;
794         int i, j;
795
796         for (i = 0; i < sc->sc_config.rings; i++) {
797                 ring = &sc->sc_ring[i];
798
799                 snprintf(ring->lockname, sizeof(ring->lockname),
800                     "safexcel_ring%d", i);
801                 mtx_init(&ring->mtx, ring->lockname, NULL, MTX_DEF);
802
803                 ring->pending = ring->pending_cdesc = ring->pending_rdesc = 0;
804                 ring->queued = 0;
805                 ring->cdr.read = ring->cdr.write = 0;
806                 ring->rdr.read = ring->rdr.write = 0;
807                 for (j = 0; j < SAFEXCEL_RING_SIZE; j++) {
808                         cdesc = &ring->cdr.desc[j];
809                         atok = ring->dma_atok.paddr +
810                             sc->sc_config.atok_offset * j;
811                         cdesc->atok_lo = SAFEXCEL_ADDR_LO(atok);
812                         cdesc->atok_hi = SAFEXCEL_ADDR_HI(atok);
813                 }
814         }
815 }
816
817 static void
818 safexcel_dma_alloc_mem_cb(void *arg, bus_dma_segment_t *segs, int nseg,
819     int error)
820 {
821         struct safexcel_dma_mem *sdm;
822
823         if (error != 0)
824                 return;
825
826         KASSERT(nseg == 1, ("%s: nsegs is %d", __func__, nseg));
827         sdm = arg;
828         sdm->paddr = segs->ds_addr;
829 }
830
831 static int
832 safexcel_dma_alloc_mem(struct safexcel_softc *sc, struct safexcel_dma_mem *sdm,
833     bus_size_t size)
834 {
835         int error;
836
837         KASSERT(sdm->vaddr == NULL,
838             ("%s: DMA memory descriptor in use.", __func__));
839
840         error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), /* parent */
841             PAGE_SIZE, 0,               /* alignment, boundary */
842             BUS_SPACE_MAXADDR_32BIT,    /* lowaddr */
843             BUS_SPACE_MAXADDR,          /* highaddr */
844             NULL, NULL,                 /* filtfunc, filtfuncarg */
845             size, 1,                    /* maxsize, nsegments */
846             size, BUS_DMA_COHERENT,     /* maxsegsz, flags */
847             NULL, NULL,                 /* lockfunc, lockfuncarg */
848             &sdm->tag);                 /* dmat */
849         if (error != 0) {
850                 device_printf(sc->sc_dev,
851                     "failed to allocate busdma tag, error %d\n", error);
852                 goto err1;
853         }
854
855         error = bus_dmamem_alloc(sdm->tag, (void **)&sdm->vaddr,
856             BUS_DMA_WAITOK | BUS_DMA_ZERO | BUS_DMA_COHERENT, &sdm->map);
857         if (error != 0) {
858                 device_printf(sc->sc_dev,
859                     "failed to allocate DMA safe memory, error %d\n", error);
860                 goto err2;
861         }
862
863         error = bus_dmamap_load(sdm->tag, sdm->map, sdm->vaddr, size,
864             safexcel_dma_alloc_mem_cb, sdm, BUS_DMA_NOWAIT);
865         if (error != 0) {
866                 device_printf(sc->sc_dev,
867                     "cannot get address of the DMA memory, error %d\n", error);
868                 goto err3;
869         }
870
871         return (0);
872 err3:
873         bus_dmamem_free(sdm->tag, sdm->vaddr, sdm->map);
874 err2:
875         bus_dma_tag_destroy(sdm->tag);
876 err1:
877         sdm->vaddr = NULL;
878
879         return (error);
880 }
881
882 static void
883 safexcel_dma_free_mem(struct safexcel_dma_mem *sdm)
884 {
885         bus_dmamap_unload(sdm->tag, sdm->map);
886         bus_dmamem_free(sdm->tag, sdm->vaddr, sdm->map);
887         bus_dma_tag_destroy(sdm->tag);
888 }
889
890 static void
891 safexcel_dma_free_rings(struct safexcel_softc *sc)
892 {
893         struct safexcel_ring *ring;
894         int i;
895
896         for (i = 0; i < sc->sc_config.rings; i++) {
897                 ring = &sc->sc_ring[i];
898                 safexcel_dma_free_mem(&ring->cdr.dma);
899                 safexcel_dma_free_mem(&ring->dma_atok);
900                 safexcel_dma_free_mem(&ring->rdr.dma);
901                 bus_dma_tag_destroy(ring->data_dtag);
902                 mtx_destroy(&ring->mtx);
903         }
904 }
905
906 static int
907 safexcel_dma_init(struct safexcel_softc *sc)
908 {
909         struct safexcel_ring *ring;
910         bus_size_t size;
911         int error, i;
912
913         for (i = 0; i < sc->sc_config.rings; i++) {
914                 ring = &sc->sc_ring[i];
915
916                 error = bus_dma_tag_create(
917                     bus_get_dma_tag(sc->sc_dev),/* parent */
918                     1, 0,                       /* alignment, boundary */
919                     BUS_SPACE_MAXADDR_32BIT,    /* lowaddr */
920                     BUS_SPACE_MAXADDR,          /* highaddr */
921                     NULL, NULL,                 /* filtfunc, filtfuncarg */
922                     SAFEXCEL_MAX_REQUEST_SIZE,  /* maxsize */
923                     SAFEXCEL_MAX_FRAGMENTS,     /* nsegments */
924                     SAFEXCEL_MAX_REQUEST_SIZE,  /* maxsegsz */
925                     BUS_DMA_COHERENT,           /* flags */
926                     NULL, NULL,                 /* lockfunc, lockfuncarg */
927                     &ring->data_dtag);          /* dmat */
928                 if (error != 0) {
929                         device_printf(sc->sc_dev,
930                             "bus_dma_tag_create main failed; error %d\n", error);
931                         return (error);
932                 }
933
934                 size = sizeof(uint32_t) * sc->sc_config.cd_offset *
935                     SAFEXCEL_RING_SIZE;
936                 error = safexcel_dma_alloc_mem(sc, &ring->cdr.dma, size);
937                 if (error != 0) {
938                         device_printf(sc->sc_dev,
939                             "failed to allocate CDR DMA memory, error %d\n",
940                             error);
941                         goto err;
942                 }
943                 ring->cdr.desc =
944                     (struct safexcel_cmd_descr *)ring->cdr.dma.vaddr;
945
946                 /* Allocate additional CDR token memory. */
947                 size = (bus_size_t)sc->sc_config.atok_offset *
948                     SAFEXCEL_RING_SIZE;
949                 error = safexcel_dma_alloc_mem(sc, &ring->dma_atok, size);
950                 if (error != 0) {
951                         device_printf(sc->sc_dev,
952                             "failed to allocate atoken DMA memory, error %d\n",
953                             error);
954                         goto err;
955                 }
956
957                 size = sizeof(uint32_t) * sc->sc_config.rd_offset *
958                     SAFEXCEL_RING_SIZE;
959                 error = safexcel_dma_alloc_mem(sc, &ring->rdr.dma, size);
960                 if (error) {
961                         device_printf(sc->sc_dev,
962                             "failed to allocate RDR DMA memory, error %d\n",
963                             error);
964                         goto err;
965                 }
966                 ring->rdr.desc =
967                     (struct safexcel_res_descr *)ring->rdr.dma.vaddr;
968         }
969
970         return (0);
971 err:
972         safexcel_dma_free_rings(sc);
973         return (error);
974 }
975
976 static void
977 safexcel_deinit_hw(struct safexcel_softc *sc)
978 {
979         safexcel_hw_reset_rings(sc);
980         safexcel_dma_free_rings(sc);
981 }
982
983 static int
984 safexcel_init_hw(struct safexcel_softc *sc)
985 {
986         int pe;
987
988         /* 23.3.7 Initialization */
989         if (safexcel_configure(sc) != 0)
990                 return (EINVAL);
991
992         if (safexcel_dma_init(sc) != 0)
993                 return (ENOMEM);
994
995         safexcel_init_rings(sc);
996
997         safexcel_init_hia_bus_access(sc);
998
999         /* 23.3.7.2 Disable EIP-97 global Interrupts */
1000         safexcel_disable_global_interrupts(sc);
1001
1002         for (pe = 0; pe < sc->sc_config.pes; pe++) {
1003                 /* 23.3.7.3 Configure Data Fetch Engine */
1004                 safexcel_configure_dfe_engine(sc, pe);
1005
1006                 /* 23.3.7.4 Configure Data Store Engine */
1007                 if (safexcel_configure_dse(sc, pe)) {
1008                         safexcel_deinit_hw(sc);
1009                         return (-1);
1010                 }
1011
1012                 /* 23.3.7.5 1. Protocol enables */
1013                 SAFEXCEL_WRITE(sc,
1014                     SAFEXCEL_PE(sc) + SAFEXCEL_PE_EIP96_FUNCTION_EN(pe),
1015                     0xffffffff);
1016                 SAFEXCEL_WRITE(sc,
1017                     SAFEXCEL_PE(sc) + SAFEXCEL_PE_EIP96_FUNCTION2_EN(pe),
1018                     0xffffffff);
1019         }
1020
1021         safexcel_hw_prepare_rings(sc);
1022
1023         /* 23.3.7.5 Configure the Processing Engine(s). */
1024         for (pe = 0; pe < sc->sc_config.pes; pe++)
1025                 safexcel_enable_pe_engine(sc, pe);
1026
1027         safexcel_hw_setup_rings(sc);
1028
1029         return (0);
1030 }
1031
1032 static int
1033 safexcel_setup_dev_interrupts(struct safexcel_softc *sc)
1034 {
1035         int error, i, j;
1036
1037         for (i = 0; i < SAFEXCEL_MAX_RINGS && sc->sc_intr[i] != NULL; i++) {
1038                 sc->sc_ih[i].sc = sc;
1039                 sc->sc_ih[i].ring = i;
1040
1041                 if (bus_setup_intr(sc->sc_dev, sc->sc_intr[i],
1042                     INTR_TYPE_NET | INTR_MPSAFE, NULL, safexcel_ring_intr,
1043                     &sc->sc_ih[i], &sc->sc_ih[i].handle)) {
1044                         device_printf(sc->sc_dev,
1045                             "couldn't setup interrupt %d\n", i);
1046                         goto err;
1047                 }
1048
1049                 error = bus_bind_intr(sc->sc_dev, sc->sc_intr[i], i % mp_ncpus);
1050                 if (error != 0)
1051                         device_printf(sc->sc_dev,
1052                             "failed to bind ring %d\n", error);
1053         }
1054
1055         return (0);
1056
1057 err:
1058         for (j = 0; j < i; j++)
1059                 bus_teardown_intr(sc->sc_dev, sc->sc_intr[j],
1060                     sc->sc_ih[j].handle);
1061
1062         return (ENXIO);
1063 }
1064
1065 static void
1066 safexcel_teardown_dev_interrupts(struct safexcel_softc *sc)
1067 {
1068         int i;
1069
1070         for (i = 0; i < SAFEXCEL_MAX_RINGS; i++)
1071                 bus_teardown_intr(sc->sc_dev, sc->sc_intr[i],
1072                     sc->sc_ih[i].handle);
1073 }
1074
1075 static int
1076 safexcel_alloc_dev_resources(struct safexcel_softc *sc)
1077 {
1078         char name[16];
1079         device_t dev;
1080         phandle_t node;
1081         int error, i, rid;
1082
1083         dev = sc->sc_dev;
1084         node = ofw_bus_get_node(dev);
1085
1086         rid = 0;
1087         sc->sc_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
1088             RF_ACTIVE);
1089         if (sc->sc_res == NULL) {
1090                 device_printf(dev, "couldn't allocate memory resources\n");
1091                 return (ENXIO);
1092         }
1093
1094         for (i = 0; i < SAFEXCEL_MAX_RINGS; i++) {
1095                 (void)snprintf(name, sizeof(name), "ring%d", i);
1096                 error = ofw_bus_find_string_index(node, "interrupt-names", name,
1097                     &rid);
1098                 if (error != 0)
1099                         break;
1100
1101                 sc->sc_intr[i] = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
1102                     RF_ACTIVE | RF_SHAREABLE);
1103                 if (sc->sc_intr[i] == NULL) {
1104                         error = ENXIO;
1105                         goto out;
1106                 }
1107         }
1108         if (i == 0) {
1109                 device_printf(dev, "couldn't allocate interrupt resources\n");
1110                 error = ENXIO;
1111                 goto out;
1112         }
1113
1114         return (0);
1115
1116 out:
1117         for (i = 0; i < SAFEXCEL_MAX_RINGS && sc->sc_intr[i] != NULL; i++)
1118                 bus_release_resource(dev, SYS_RES_IRQ,
1119                     rman_get_rid(sc->sc_intr[i]), sc->sc_intr[i]);
1120         bus_release_resource(dev, SYS_RES_MEMORY, rman_get_rid(sc->sc_res),
1121             sc->sc_res);
1122         return (error);
1123 }
1124
1125 static void
1126 safexcel_free_dev_resources(struct safexcel_softc *sc)
1127 {
1128         int i;
1129
1130         for (i = 0; i < SAFEXCEL_MAX_RINGS && sc->sc_intr[i] != NULL; i++)
1131                 bus_release_resource(sc->sc_dev, SYS_RES_IRQ,
1132                     rman_get_rid(sc->sc_intr[i]), sc->sc_intr[i]);
1133         if (sc->sc_res != NULL)
1134                 bus_release_resource(sc->sc_dev, SYS_RES_MEMORY,
1135                     rman_get_rid(sc->sc_res), sc->sc_res);
1136 }
1137
1138 static int
1139 safexcel_probe(device_t dev)
1140 {
1141         struct safexcel_softc *sc;
1142
1143         if (!ofw_bus_status_okay(dev))
1144                 return (ENXIO);
1145
1146         sc = device_get_softc(dev);
1147         sc->sc_type = ofw_bus_search_compatible(dev, safexcel_compat)->ocd_data;
1148         if (sc->sc_type == 0)
1149                 return (ENXIO);
1150
1151         device_set_desc(dev, "SafeXcel EIP-97 crypto accelerator");
1152
1153         return (BUS_PROBE_DEFAULT);
1154 }
1155
1156 static int
1157 safexcel_attach(device_t dev)
1158 {
1159         struct sysctl_ctx_list *ctx;
1160         struct sysctl_oid *oid;
1161         struct sysctl_oid_list *children;
1162         struct safexcel_softc *sc;
1163         struct safexcel_request *req;
1164         struct safexcel_ring *ring;
1165         int i, j, ringidx;
1166
1167         sc = device_get_softc(dev);
1168         sc->sc_dev = dev;
1169         sc->sc_cid = -1;
1170
1171         if (safexcel_alloc_dev_resources(sc))
1172                 goto err;
1173
1174         if (safexcel_setup_dev_interrupts(sc))
1175                 goto err1;
1176
1177         if (safexcel_init_hw(sc))
1178                 goto err2;
1179
1180         for (ringidx = 0; ringidx < sc->sc_config.rings; ringidx++) {
1181                 ring = &sc->sc_ring[ringidx];
1182
1183                 ring->cmd_data = sglist_alloc(SAFEXCEL_MAX_FRAGMENTS, M_WAITOK);
1184                 ring->res_data = sglist_alloc(SAFEXCEL_MAX_FRAGMENTS, M_WAITOK);
1185
1186                 for (i = 0; i < SAFEXCEL_RING_SIZE; i++) {
1187                         req = &ring->requests[i];
1188                         req->sc = sc;
1189                         req->ringidx = ringidx;
1190                         if (bus_dmamap_create(ring->data_dtag,
1191                             BUS_DMA_COHERENT, &req->dmap) != 0) {
1192                                 for (j = 0; j < i; j++)
1193                                         bus_dmamap_destroy(ring->data_dtag,
1194                                             ring->requests[j].dmap);
1195                                 goto err2;
1196                         }
1197                         if (safexcel_dma_alloc_mem(sc, &req->ctx,
1198                             sizeof(struct safexcel_context_record)) != 0) {
1199                                 for (j = 0; j < i; j++) {
1200                                         bus_dmamap_destroy(ring->data_dtag,
1201                                             ring->requests[j].dmap);
1202                                         safexcel_dma_free_mem(
1203                                             &ring->requests[j].ctx);
1204                                 }
1205                                 goto err2;
1206                         }
1207                 }
1208         }
1209
1210         ctx = device_get_sysctl_ctx(dev);
1211         SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
1212             OID_AUTO, "debug", CTLFLAG_RWTUN, &sc->sc_debug, 0,
1213             "Debug message verbosity");
1214
1215         oid = device_get_sysctl_tree(sc->sc_dev);
1216         children = SYSCTL_CHILDREN(oid);
1217         oid = SYSCTL_ADD_NODE(ctx, children, OID_AUTO, "stats",
1218             CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, "statistics");
1219         children = SYSCTL_CHILDREN(oid);
1220
1221         sc->sc_req_alloc_failures = counter_u64_alloc(M_WAITOK);
1222         SYSCTL_ADD_COUNTER_U64(ctx, children, OID_AUTO, "req_alloc_failures",
1223             CTLFLAG_RD, &sc->sc_req_alloc_failures,
1224             "Number of request allocation failures");
1225         sc->sc_cdesc_alloc_failures = counter_u64_alloc(M_WAITOK);
1226         SYSCTL_ADD_COUNTER_U64(ctx, children, OID_AUTO, "cdesc_alloc_failures",
1227             CTLFLAG_RD, &sc->sc_cdesc_alloc_failures,
1228             "Number of command descriptor ring overflows");
1229         sc->sc_rdesc_alloc_failures = counter_u64_alloc(M_WAITOK);
1230         SYSCTL_ADD_COUNTER_U64(ctx, children, OID_AUTO, "rdesc_alloc_failures",
1231             CTLFLAG_RD, &sc->sc_rdesc_alloc_failures,
1232             "Number of result descriptor ring overflows");
1233
1234         sc->sc_cid = crypto_get_driverid(dev, sizeof(struct safexcel_session),
1235             CRYPTOCAP_F_HARDWARE);
1236         if (sc->sc_cid < 0)
1237                 goto err2;
1238
1239         return (0);
1240
1241 err2:
1242         safexcel_teardown_dev_interrupts(sc);
1243 err1:
1244         safexcel_free_dev_resources(sc);
1245 err:
1246         return (ENXIO);
1247 }
1248
1249 static int
1250 safexcel_detach(device_t dev)
1251 {
1252         struct safexcel_ring *ring;
1253         struct safexcel_softc *sc;
1254         int i, ringidx;
1255
1256         sc = device_get_softc(dev);
1257
1258         if (sc->sc_cid >= 0)
1259                 crypto_unregister_all(sc->sc_cid);
1260
1261         counter_u64_free(sc->sc_req_alloc_failures);
1262         counter_u64_free(sc->sc_cdesc_alloc_failures);
1263         counter_u64_free(sc->sc_rdesc_alloc_failures);
1264
1265         for (ringidx = 0; ringidx < sc->sc_config.rings; ringidx++) {
1266                 ring = &sc->sc_ring[ringidx];
1267                 for (i = 0; i < SAFEXCEL_RING_SIZE; i++) {
1268                         bus_dmamap_destroy(ring->data_dtag,
1269                             ring->requests[i].dmap);
1270                         safexcel_dma_free_mem(&ring->requests[i].ctx);
1271                 }
1272                 sglist_free(ring->cmd_data);
1273                 sglist_free(ring->res_data);
1274         }
1275         safexcel_deinit_hw(sc);
1276         safexcel_teardown_dev_interrupts(sc);
1277         safexcel_free_dev_resources(sc);
1278
1279         return (0);
1280 }
1281
1282 /*
1283  * Pre-compute the hash key used in GHASH, which is a block of zeroes encrypted
1284  * using the cipher key.
1285  */
1286 static void
1287 safexcel_setkey_ghash(const uint8_t *key, int klen, uint32_t *hashkey)
1288 {
1289         uint32_t ks[4 * (RIJNDAEL_MAXNR + 1)];
1290         uint8_t zeros[AES_BLOCK_LEN];
1291         int i, rounds;
1292
1293         memset(zeros, 0, sizeof(zeros));
1294
1295         rounds = rijndaelKeySetupEnc(ks, key, klen * NBBY);
1296         rijndaelEncrypt(ks, rounds, zeros, (uint8_t *)hashkey);
1297         for (i = 0; i < GMAC_BLOCK_LEN / sizeof(uint32_t); i++)
1298                 hashkey[i] = htobe32(hashkey[i]);
1299
1300         explicit_bzero(ks, sizeof(ks));
1301 }
1302
1303 /*
1304  * Pre-compute the combined CBC-MAC key, which consists of three keys K1, K2, K3
1305  * in the hardware implementation.  K1 is the cipher key and comes last in the
1306  * buffer since K2 and K3 have a fixed size of AES_BLOCK_LEN.  For now XCBC-MAC
1307  * is not implemented so K2 and K3 are fixed.
1308  */
1309 static void
1310 safexcel_setkey_xcbcmac(const uint8_t *key, int klen, uint32_t *hashkey)
1311 {
1312         int i, off;
1313
1314         memset(hashkey, 0, 2 * AES_BLOCK_LEN);
1315         off = 2 * AES_BLOCK_LEN / sizeof(uint32_t);
1316         for (i = 0; i < klen / sizeof(uint32_t); i++, key += 4)
1317                 hashkey[i + off] = htobe32(le32dec(key));
1318 }
1319
1320 static void
1321 safexcel_setkey_hmac_digest(struct auth_hash *ahash, union authctx *ctx,
1322     char *buf)
1323 {
1324         int hashwords, i;
1325
1326         switch (ahash->type) {
1327         case CRYPTO_SHA1_HMAC:
1328                 hashwords = ahash->hashsize / sizeof(uint32_t);
1329                 for (i = 0; i < hashwords; i++)
1330                         ((uint32_t *)buf)[i] = htobe32(ctx->sha1ctx.h.b32[i]);
1331                 break;
1332         case CRYPTO_SHA2_224_HMAC:
1333                 hashwords = auth_hash_hmac_sha2_256.hashsize / sizeof(uint32_t);
1334                 for (i = 0; i < hashwords; i++)
1335                         ((uint32_t *)buf)[i] = htobe32(ctx->sha224ctx.state[i]);
1336                 break;
1337         case CRYPTO_SHA2_256_HMAC:
1338                 hashwords = ahash->hashsize / sizeof(uint32_t);
1339                 for (i = 0; i < hashwords; i++)
1340                         ((uint32_t *)buf)[i] = htobe32(ctx->sha256ctx.state[i]);
1341                 break;
1342         case CRYPTO_SHA2_384_HMAC:
1343                 hashwords = auth_hash_hmac_sha2_512.hashsize / sizeof(uint64_t);
1344                 for (i = 0; i < hashwords; i++)
1345                         ((uint64_t *)buf)[i] = htobe64(ctx->sha384ctx.state[i]);
1346                 break;
1347         case CRYPTO_SHA2_512_HMAC:
1348                 hashwords = ahash->hashsize / sizeof(uint64_t);
1349                 for (i = 0; i < hashwords; i++)
1350                         ((uint64_t *)buf)[i] = htobe64(ctx->sha512ctx.state[i]);
1351                 break;
1352         }
1353 }
1354
1355 /*
1356  * Pre-compute the inner and outer digests used in the HMAC algorithm.
1357  */
1358 static void
1359 safexcel_setkey_hmac(const struct crypto_session_params *csp,
1360     const uint8_t *key, int klen, uint8_t *ipad, uint8_t *opad)
1361 {
1362         union authctx ctx;
1363         struct auth_hash *ahash;
1364
1365         ahash = crypto_auth_hash(csp);
1366         hmac_init_ipad(ahash, key, klen, &ctx);
1367         safexcel_setkey_hmac_digest(ahash, &ctx, ipad);
1368         hmac_init_opad(ahash, key, klen, &ctx);
1369         safexcel_setkey_hmac_digest(ahash, &ctx, opad);
1370         explicit_bzero(&ctx, ahash->ctxsize);
1371 }
1372
1373 static void
1374 safexcel_setkey_xts(const uint8_t *key, int klen, uint8_t *tweakkey)
1375 {
1376         memcpy(tweakkey, key + klen, klen);
1377 }
1378
1379 /*
1380  * Populate a context record with paramters from a session.  Some consumers
1381  * specify per-request keys, in which case the context must be re-initialized
1382  * for each request.
1383  */
1384 static int
1385 safexcel_set_context(struct safexcel_context_record *ctx, int op,
1386     const uint8_t *ckey, const uint8_t *akey, struct safexcel_session *sess)
1387 {
1388         const struct crypto_session_params *csp;
1389         uint8_t *data;
1390         uint32_t ctrl0, ctrl1;
1391         int aklen, alg, cklen, off;
1392
1393         csp = crypto_get_params(sess->cses);
1394         aklen = csp->csp_auth_klen;
1395         cklen = csp->csp_cipher_klen;
1396         if (csp->csp_cipher_alg == CRYPTO_AES_XTS)
1397                 cklen /= 2;
1398
1399         ctrl0 = sess->alg | sess->digest | sess->hash;
1400         ctrl1 = sess->mode;
1401
1402         data = (uint8_t *)ctx->data;
1403         if (csp->csp_cipher_alg != 0) {
1404                 memcpy(data, ckey, cklen);
1405                 off = cklen;
1406         } else if (csp->csp_auth_alg == CRYPTO_AES_NIST_GMAC) {
1407                 memcpy(data, akey, aklen);
1408                 off = aklen;
1409         } else {
1410                 off = 0;
1411         }
1412
1413         switch (csp->csp_cipher_alg) {
1414         case CRYPTO_AES_NIST_GCM_16:
1415                 safexcel_setkey_ghash(ckey, cklen, (uint32_t *)(data + off));
1416                 off += GMAC_BLOCK_LEN;
1417                 break;
1418         case CRYPTO_AES_CCM_16:
1419                 safexcel_setkey_xcbcmac(ckey, cklen, (uint32_t *)(data + off));
1420                 off += AES_BLOCK_LEN * 2 + cklen;
1421                 break;
1422         case CRYPTO_AES_XTS:
1423                 safexcel_setkey_xts(ckey, cklen, data + off);
1424                 off += cklen;
1425                 break;
1426         }
1427         switch (csp->csp_auth_alg) {
1428         case CRYPTO_AES_NIST_GMAC:
1429                 safexcel_setkey_ghash(akey, aklen, (uint32_t *)(data + off));
1430                 off += GMAC_BLOCK_LEN;
1431                 break;
1432         case CRYPTO_SHA1_HMAC:
1433         case CRYPTO_SHA2_224_HMAC:
1434         case CRYPTO_SHA2_256_HMAC:
1435         case CRYPTO_SHA2_384_HMAC:
1436         case CRYPTO_SHA2_512_HMAC:
1437                 safexcel_setkey_hmac(csp, akey, aklen,
1438                     data + off, data + off + sess->statelen);
1439                 off += sess->statelen * 2;
1440                 break;
1441         }
1442         ctrl0 |= SAFEXCEL_CONTROL0_SIZE(off / sizeof(uint32_t));
1443
1444         alg = csp->csp_cipher_alg;
1445         if (alg == 0)
1446                 alg = csp->csp_auth_alg;
1447
1448         switch (alg) {
1449         case CRYPTO_AES_CCM_16:
1450                 if (CRYPTO_OP_IS_ENCRYPT(op)) {
1451                         ctrl0 |= SAFEXCEL_CONTROL0_TYPE_HASH_ENCRYPT_OUT |
1452                             SAFEXCEL_CONTROL0_KEY_EN;
1453                 } else {
1454                         ctrl0 |= SAFEXCEL_CONTROL0_TYPE_DECRYPT_HASH_IN |
1455                             SAFEXCEL_CONTROL0_KEY_EN;
1456                 }
1457                 ctrl1 |= SAFEXCEL_CONTROL1_IV0 | SAFEXCEL_CONTROL1_IV1 |
1458                     SAFEXCEL_CONTROL1_IV2 | SAFEXCEL_CONTROL1_IV3;
1459                 break;
1460         case CRYPTO_AES_CBC:
1461         case CRYPTO_AES_ICM:
1462         case CRYPTO_AES_XTS:
1463                 if (CRYPTO_OP_IS_ENCRYPT(op)) {
1464                         ctrl0 |= SAFEXCEL_CONTROL0_TYPE_CRYPTO_OUT |
1465                             SAFEXCEL_CONTROL0_KEY_EN;
1466                         if (csp->csp_auth_alg != 0)
1467                                 ctrl0 |=
1468                                     SAFEXCEL_CONTROL0_TYPE_ENCRYPT_HASH_OUT;
1469                 } else {
1470                         ctrl0 |= SAFEXCEL_CONTROL0_TYPE_CRYPTO_IN |
1471                             SAFEXCEL_CONTROL0_KEY_EN;
1472                         if (csp->csp_auth_alg != 0)
1473                                 ctrl0 |= SAFEXCEL_CONTROL0_TYPE_HASH_DECRYPT_IN;
1474                 }
1475                 break;
1476         case CRYPTO_AES_NIST_GCM_16:
1477         case CRYPTO_AES_NIST_GMAC:
1478                 if (CRYPTO_OP_IS_ENCRYPT(op) || csp->csp_auth_alg != 0) {
1479                         ctrl0 |= SAFEXCEL_CONTROL0_TYPE_CRYPTO_OUT |
1480                             SAFEXCEL_CONTROL0_KEY_EN |
1481                             SAFEXCEL_CONTROL0_TYPE_HASH_OUT;
1482                 } else {
1483                         ctrl0 |= SAFEXCEL_CONTROL0_TYPE_CRYPTO_IN |
1484                             SAFEXCEL_CONTROL0_KEY_EN |
1485                             SAFEXCEL_CONTROL0_TYPE_HASH_DECRYPT_IN;
1486                 }
1487                 if (csp->csp_cipher_alg == CRYPTO_AES_NIST_GCM_16) {
1488                         ctrl1 |= SAFEXCEL_CONTROL1_COUNTER_MODE |
1489                             SAFEXCEL_CONTROL1_IV0 | SAFEXCEL_CONTROL1_IV1 |
1490                             SAFEXCEL_CONTROL1_IV2;
1491                 }
1492                 break;
1493         case CRYPTO_SHA1:
1494         case CRYPTO_SHA2_224:
1495         case CRYPTO_SHA2_256:
1496         case CRYPTO_SHA2_384:
1497         case CRYPTO_SHA2_512:
1498                 ctrl0 |= SAFEXCEL_CONTROL0_RESTART_HASH;
1499                 /* FALLTHROUGH */
1500         case CRYPTO_SHA1_HMAC:
1501         case CRYPTO_SHA2_224_HMAC:
1502         case CRYPTO_SHA2_256_HMAC:
1503         case CRYPTO_SHA2_384_HMAC:
1504         case CRYPTO_SHA2_512_HMAC:
1505                 ctrl0 |= SAFEXCEL_CONTROL0_TYPE_HASH_OUT;
1506                 break;
1507         }
1508
1509         ctx->control0 = ctrl0;
1510         ctx->control1 = ctrl1;
1511
1512         return (off);
1513 }
1514
1515 /*
1516  * Construct a no-op instruction, used to pad input tokens.
1517  */
1518 static void
1519 safexcel_instr_nop(struct safexcel_instr **instrp)
1520 {
1521         struct safexcel_instr *instr;
1522
1523         instr = *instrp;
1524         instr->opcode = SAFEXCEL_INSTR_OPCODE_INSERT;
1525         instr->length = (1 << 2);
1526         instr->status = 0;
1527         instr->instructions = 0;
1528
1529         *instrp = instr + 1;
1530 }
1531
1532 /*
1533  * Insert the digest of the input payload.  This is typically the last
1534  * instruction of a sequence.
1535  */
1536 static void
1537 safexcel_instr_insert_digest(struct safexcel_instr **instrp, int len)
1538 {
1539         struct safexcel_instr *instr;
1540
1541         instr = *instrp;
1542         instr->opcode = SAFEXCEL_INSTR_OPCODE_INSERT;
1543         instr->length = len;
1544         instr->status = SAFEXCEL_INSTR_STATUS_LAST_HASH |
1545             SAFEXCEL_INSTR_STATUS_LAST_PACKET;
1546         instr->instructions = SAFEXCEL_INSTR_DEST_OUTPUT |
1547             SAFEXCEL_INSTR_INSERT_HASH_DIGEST;
1548
1549         *instrp = instr + 1;
1550 }
1551
1552 /*
1553  * Retrieve and verify a digest.
1554  */
1555 static void
1556 safexcel_instr_retrieve_digest(struct safexcel_instr **instrp, int len)
1557 {
1558         struct safexcel_instr *instr;
1559
1560         instr = *instrp;
1561         instr->opcode = SAFEXCEL_INSTR_OPCODE_RETRIEVE;
1562         instr->length = len;
1563         instr->status = SAFEXCEL_INSTR_STATUS_LAST_HASH |
1564             SAFEXCEL_INSTR_STATUS_LAST_PACKET;
1565         instr->instructions = SAFEXCEL_INSTR_INSERT_HASH_DIGEST;
1566         instr++;
1567
1568         instr->opcode = SAFEXCEL_INSTR_OPCODE_VERIFY_FIELDS;
1569         instr->length = len | SAFEXCEL_INSTR_VERIFY_HASH;
1570         instr->status = SAFEXCEL_INSTR_STATUS_LAST_HASH |
1571             SAFEXCEL_INSTR_STATUS_LAST_PACKET;
1572         instr->instructions = SAFEXCEL_INSTR_VERIFY_PADDING;
1573
1574         *instrp = instr + 1;
1575 }
1576
1577 static void
1578 safexcel_instr_temp_aes_block(struct safexcel_instr **instrp)
1579 {
1580         struct safexcel_instr *instr;
1581
1582         instr = *instrp;
1583         instr->opcode = SAFEXCEL_INSTR_OPCODE_INSERT_REMOVE_RESULT;
1584         instr->length = 0;
1585         instr->status = 0;
1586         instr->instructions = AES_BLOCK_LEN;
1587         instr++;
1588
1589         instr->opcode = SAFEXCEL_INSTR_OPCODE_INSERT;
1590         instr->length = AES_BLOCK_LEN;
1591         instr->status = 0;
1592         instr->instructions = SAFEXCEL_INSTR_DEST_OUTPUT |
1593             SAFEXCEL_INSTR_DEST_CRYPTO;
1594
1595         *instrp = instr + 1;
1596 }
1597
1598 /*
1599  * Handle a request for an unauthenticated block cipher.
1600  */
1601 static void
1602 safexcel_instr_cipher(struct safexcel_request *req,
1603     struct safexcel_instr *instr, struct safexcel_cmd_descr *cdesc)
1604 {
1605         struct cryptop *crp;
1606
1607         crp = req->crp;
1608
1609         /* Insert the payload. */
1610         instr->opcode = SAFEXCEL_INSTR_OPCODE_DIRECTION;
1611         instr->length = crp->crp_payload_length;
1612         instr->status = SAFEXCEL_INSTR_STATUS_LAST_PACKET |
1613             SAFEXCEL_INSTR_STATUS_LAST_HASH;
1614         instr->instructions = SAFEXCEL_INSTR_INS_LAST |
1615             SAFEXCEL_INSTR_DEST_CRYPTO | SAFEXCEL_INSTR_DEST_OUTPUT;
1616
1617         cdesc->additional_cdata_size = 1;
1618 }
1619
1620 static void
1621 safexcel_instr_eta(struct safexcel_request *req, struct safexcel_instr *instr,
1622     struct safexcel_cmd_descr *cdesc)
1623 {
1624         const struct crypto_session_params *csp;
1625         struct cryptop *crp;
1626         struct safexcel_instr *start;
1627
1628         crp = req->crp;
1629         csp = crypto_get_params(crp->crp_session);
1630         start = instr;
1631
1632         /* Insert the AAD. */
1633         instr->opcode = SAFEXCEL_INSTR_OPCODE_DIRECTION;
1634         instr->length = crp->crp_aad_length;
1635         instr->status = crp->crp_payload_length == 0 ?
1636             SAFEXCEL_INSTR_STATUS_LAST_HASH : 0;
1637         instr->instructions = SAFEXCEL_INSTR_INS_LAST |
1638             SAFEXCEL_INSTR_DEST_HASH;
1639         instr++;
1640
1641         /* Encrypt any data left in the request. */
1642         if (crp->crp_payload_length > 0) {
1643                 instr->opcode = SAFEXCEL_INSTR_OPCODE_DIRECTION;
1644                 instr->length = crp->crp_payload_length;
1645                 instr->status = SAFEXCEL_INSTR_STATUS_LAST_HASH;
1646                 instr->instructions = SAFEXCEL_INSTR_INS_LAST |
1647                     SAFEXCEL_INSTR_DEST_CRYPTO |
1648                     SAFEXCEL_INSTR_DEST_HASH |
1649                     SAFEXCEL_INSTR_DEST_OUTPUT;
1650                 instr++;
1651         }
1652
1653         /*
1654          * Compute the digest, or extract it and place it in the output stream.
1655          */
1656         if (CRYPTO_OP_IS_ENCRYPT(crp->crp_op))
1657                 safexcel_instr_insert_digest(&instr, req->sess->digestlen);
1658         else
1659                 safexcel_instr_retrieve_digest(&instr, req->sess->digestlen);
1660         cdesc->additional_cdata_size = instr - start;
1661 }
1662
1663 static void
1664 safexcel_instr_sha_hash(struct safexcel_request *req,
1665     struct safexcel_instr *instr)
1666 {
1667         struct cryptop *crp;
1668         struct safexcel_instr *start;
1669
1670         crp = req->crp;
1671         start = instr;
1672
1673         /* Pass the input data to the hash engine. */
1674         instr->opcode = SAFEXCEL_INSTR_OPCODE_DIRECTION;
1675         instr->length = crp->crp_payload_length;
1676         instr->status = SAFEXCEL_INSTR_STATUS_LAST_HASH;
1677         instr->instructions = SAFEXCEL_INSTR_DEST_HASH;
1678         instr++;
1679
1680         /* Insert the hash result into the output stream. */
1681         safexcel_instr_insert_digest(&instr, req->sess->digestlen);
1682
1683         /* Pad the rest of the inline instruction space. */
1684         while (instr != start + SAFEXCEL_MAX_ITOKENS)
1685                 safexcel_instr_nop(&instr);
1686 }
1687
1688 static void
1689 safexcel_instr_ccm(struct safexcel_request *req, struct safexcel_instr *instr,
1690     struct safexcel_cmd_descr *cdesc)
1691 {
1692         struct cryptop *crp;
1693         struct safexcel_instr *start;
1694         uint8_t *a0, *b0, *alenp, L;
1695         int aalign, blen;
1696
1697         crp = req->crp;
1698         start = instr;
1699
1700         /*
1701          * Construct two blocks, A0 and B0, used in encryption and
1702          * authentication, respectively.  A0 is embedded in the token
1703          * descriptor, and B0 is inserted directly into the data stream using
1704          * instructions below.
1705          *
1706          * OCF seems to assume a 12-byte IV, fixing L (the payload length size)
1707          * at 3 bytes due to the layout of B0.  This is fine since the driver
1708          * has a maximum of 65535 bytes anyway.
1709          */
1710         blen = AES_BLOCK_LEN;
1711         L = 3;
1712
1713         a0 = (uint8_t *)&cdesc->control_data.token[0];
1714         memset(a0, 0, blen);
1715         a0[0] = L - 1;
1716         memcpy(&a0[1], req->iv, AES_CCM_IV_LEN);
1717
1718         /*
1719          * Insert B0 and the AAD length into the input stream.
1720          */
1721         instr->opcode = SAFEXCEL_INSTR_OPCODE_INSERT;
1722         instr->length = blen + (crp->crp_aad_length > 0 ? 2 : 0);
1723         instr->status = 0;
1724         instr->instructions = SAFEXCEL_INSTR_DEST_HASH |
1725             SAFEXCEL_INSTR_INSERT_IMMEDIATE;
1726         instr++;
1727
1728         b0 = (uint8_t *)instr;
1729         memset(b0, 0, blen);
1730         b0[0] =
1731             (L - 1) | /* payload length size */
1732             ((CCM_CBC_MAX_DIGEST_LEN - 2) / 2) << 3 /* digest length */ |
1733             (crp->crp_aad_length > 0 ? 1 : 0) << 6 /* AAD present bit */;
1734         memcpy(&b0[1], req->iv, AES_CCM_IV_LEN);
1735         b0[14] = crp->crp_payload_length >> 8;
1736         b0[15] = crp->crp_payload_length & 0xff;
1737         instr += blen / sizeof(*instr);
1738
1739         /* Insert the AAD length and data into the input stream. */
1740         if (crp->crp_aad_length > 0) {
1741                 alenp = (uint8_t *)instr;
1742                 alenp[0] = crp->crp_aad_length >> 8;
1743                 alenp[1] = crp->crp_aad_length & 0xff;
1744                 alenp[2] = 0;
1745                 alenp[3] = 0;
1746                 instr++;
1747
1748                 instr->opcode = SAFEXCEL_INSTR_OPCODE_DIRECTION;
1749                 instr->length = crp->crp_aad_length;
1750                 instr->status = 0;
1751                 instr->instructions = SAFEXCEL_INSTR_DEST_HASH;
1752                 instr++;
1753
1754                 /* Insert zero padding. */
1755                 aalign = (crp->crp_aad_length + 2) & (blen - 1);
1756                 instr->opcode = SAFEXCEL_INSTR_OPCODE_INSERT;
1757                 instr->length = aalign == 0 ? 0 :
1758                     blen - ((crp->crp_aad_length + 2) & (blen - 1));
1759                 instr->status = crp->crp_payload_length == 0 ?
1760                     SAFEXCEL_INSTR_STATUS_LAST_HASH : 0;
1761                 instr->instructions = SAFEXCEL_INSTR_DEST_HASH;
1762                 instr++;
1763         }
1764
1765         safexcel_instr_temp_aes_block(&instr);
1766
1767         /* Insert the cipher payload into the input stream. */
1768         if (crp->crp_payload_length > 0) {
1769                 instr->opcode = SAFEXCEL_INSTR_OPCODE_DIRECTION;
1770                 instr->length = crp->crp_payload_length;
1771                 instr->status = (crp->crp_payload_length & (blen - 1)) == 0 ?
1772                     SAFEXCEL_INSTR_STATUS_LAST_HASH : 0;
1773                 instr->instructions = SAFEXCEL_INSTR_DEST_OUTPUT |
1774                     SAFEXCEL_INSTR_DEST_CRYPTO |
1775                     SAFEXCEL_INSTR_DEST_HASH |
1776                     SAFEXCEL_INSTR_INS_LAST;
1777                 instr++;
1778
1779                 /* Insert zero padding. */
1780                 if (crp->crp_payload_length & (blen - 1)) {
1781                         instr->opcode = SAFEXCEL_INSTR_OPCODE_INSERT;
1782                         instr->length = blen -
1783                             (crp->crp_payload_length & (blen - 1));
1784                         instr->status = SAFEXCEL_INSTR_STATUS_LAST_HASH;
1785                         instr->instructions = SAFEXCEL_INSTR_DEST_HASH;
1786                         instr++;
1787                 }
1788         }
1789
1790         /*
1791          * Compute the digest, or extract it and place it in the output stream.
1792          */
1793         if (CRYPTO_OP_IS_ENCRYPT(crp->crp_op))
1794                 safexcel_instr_insert_digest(&instr, req->sess->digestlen);
1795         else
1796                 safexcel_instr_retrieve_digest(&instr, req->sess->digestlen);
1797
1798         cdesc->additional_cdata_size = instr - start;
1799 }
1800
1801 static void
1802 safexcel_instr_gcm(struct safexcel_request *req, struct safexcel_instr *instr,
1803     struct safexcel_cmd_descr *cdesc)
1804 {
1805         struct cryptop *crp;
1806         struct safexcel_instr *start;
1807
1808         memcpy(cdesc->control_data.token, req->iv, AES_GCM_IV_LEN);
1809         cdesc->control_data.token[3] = htobe32(1);
1810
1811         crp = req->crp;
1812         start = instr;
1813
1814         /* Insert the AAD into the input stream. */
1815         instr->opcode = SAFEXCEL_INSTR_OPCODE_DIRECTION;
1816         instr->length = crp->crp_aad_length;
1817         instr->status = crp->crp_payload_length == 0 ?
1818             SAFEXCEL_INSTR_STATUS_LAST_HASH : 0;
1819         instr->instructions = SAFEXCEL_INSTR_INS_LAST |
1820             SAFEXCEL_INSTR_DEST_HASH;
1821         instr++;
1822
1823         safexcel_instr_temp_aes_block(&instr);
1824
1825         /* Insert the cipher payload into the input stream. */
1826         if (crp->crp_payload_length > 0) {
1827                 instr->opcode = SAFEXCEL_INSTR_OPCODE_DIRECTION;
1828                 instr->length = crp->crp_payload_length;
1829                 instr->status = SAFEXCEL_INSTR_STATUS_LAST_HASH;
1830                 instr->instructions = SAFEXCEL_INSTR_DEST_OUTPUT |
1831                     SAFEXCEL_INSTR_DEST_CRYPTO | SAFEXCEL_INSTR_DEST_HASH |
1832                     SAFEXCEL_INSTR_INS_LAST;
1833                 instr++;
1834         }
1835
1836         /*
1837          * Compute the digest, or extract it and place it in the output stream.
1838          */
1839         if (CRYPTO_OP_IS_ENCRYPT(crp->crp_op))
1840                 safexcel_instr_insert_digest(&instr, req->sess->digestlen);
1841         else
1842                 safexcel_instr_retrieve_digest(&instr, req->sess->digestlen);
1843
1844         cdesc->additional_cdata_size = instr - start;
1845 }
1846
1847 static void
1848 safexcel_instr_gmac(struct safexcel_request *req, struct safexcel_instr *instr,
1849     struct safexcel_cmd_descr *cdesc)
1850 {
1851         struct cryptop *crp;
1852         struct safexcel_instr *start;
1853
1854         memcpy(cdesc->control_data.token, req->iv, AES_GCM_IV_LEN);
1855         cdesc->control_data.token[3] = htobe32(1);
1856
1857         crp = req->crp;
1858         start = instr;
1859
1860         instr->opcode = SAFEXCEL_INSTR_OPCODE_DIRECTION;
1861         instr->length = crp->crp_payload_length;
1862         instr->status = SAFEXCEL_INSTR_STATUS_LAST_HASH;
1863         instr->instructions = SAFEXCEL_INSTR_INS_LAST |
1864             SAFEXCEL_INSTR_DEST_HASH;
1865         instr++;
1866
1867         safexcel_instr_temp_aes_block(&instr);
1868
1869         safexcel_instr_insert_digest(&instr, req->sess->digestlen);
1870
1871         cdesc->additional_cdata_size = instr - start;
1872 }
1873
1874 static void
1875 safexcel_set_token(struct safexcel_request *req)
1876 {
1877         const struct crypto_session_params *csp;
1878         struct cryptop *crp;
1879         struct safexcel_cmd_descr *cdesc;
1880         struct safexcel_context_record *ctx;
1881         struct safexcel_context_template *ctxtmp;
1882         struct safexcel_instr *instr;
1883         struct safexcel_softc *sc;
1884         const uint8_t *akey, *ckey;
1885         int ringidx;
1886
1887         crp = req->crp;
1888         csp = crypto_get_params(crp->crp_session);
1889         cdesc = req->cdesc;
1890         sc = req->sc;
1891         ringidx = req->ringidx;
1892
1893         akey = crp->crp_auth_key;
1894         ckey = crp->crp_cipher_key;
1895         if (akey != NULL || ckey != NULL) {
1896                 /*
1897                  * If we have a per-request key we have to generate the context
1898                  * record on the fly.
1899                  */
1900                 if (akey == NULL)
1901                         akey = csp->csp_auth_key;
1902                 if (ckey == NULL)
1903                         ckey = csp->csp_cipher_key;
1904                 ctx = (struct safexcel_context_record *)req->ctx.vaddr;
1905                 (void)safexcel_set_context(ctx, crp->crp_op, ckey, akey,
1906                     req->sess);
1907         } else {
1908                 /*
1909                  * Use the context record template computed at session
1910                  * initialization time.
1911                  */
1912                 ctxtmp = CRYPTO_OP_IS_ENCRYPT(crp->crp_op) ?
1913                     &req->sess->encctx : &req->sess->decctx;
1914                 ctx = &ctxtmp->ctx;
1915                 memcpy(req->ctx.vaddr + 2 * sizeof(uint32_t), ctx->data,
1916                     ctxtmp->len);
1917         }
1918         cdesc->control_data.control0 = ctx->control0;
1919         cdesc->control_data.control1 = ctx->control1;
1920
1921         /*
1922          * For keyless hash operations, the token instructions can be embedded
1923          * in the token itself.  Otherwise we use an additional token descriptor
1924          * and the embedded instruction space is used to store the IV.
1925          */
1926         if (csp->csp_cipher_alg == 0 &&
1927             csp->csp_auth_alg != CRYPTO_AES_NIST_GMAC) {
1928                 instr = (void *)cdesc->control_data.token;
1929         } else {
1930                 instr = (void *)(sc->sc_ring[ringidx].dma_atok.vaddr +
1931                     sc->sc_config.atok_offset *
1932                     (cdesc - sc->sc_ring[ringidx].cdr.desc));
1933                 cdesc->control_data.options |= SAFEXCEL_OPTION_4_TOKEN_IV_CMD;
1934         }
1935
1936         switch (csp->csp_cipher_alg) {
1937         case CRYPTO_AES_NIST_GCM_16:
1938                 safexcel_instr_gcm(req, instr, cdesc);
1939                 break;
1940         case CRYPTO_AES_CCM_16:
1941                 safexcel_instr_ccm(req, instr, cdesc);
1942                 break;
1943         case CRYPTO_AES_XTS:
1944                 memcpy(cdesc->control_data.token, req->iv, AES_XTS_IV_LEN);
1945                 memset(cdesc->control_data.token +
1946                     AES_XTS_IV_LEN / sizeof(uint32_t), 0, AES_XTS_IV_LEN);
1947
1948                 safexcel_instr_cipher(req, instr, cdesc);
1949                 break;
1950         case CRYPTO_AES_CBC:
1951         case CRYPTO_AES_ICM:
1952                 memcpy(cdesc->control_data.token, req->iv, AES_BLOCK_LEN);
1953                 if (csp->csp_auth_alg != 0)
1954                         safexcel_instr_eta(req, instr, cdesc);
1955                 else
1956                         safexcel_instr_cipher(req, instr, cdesc);
1957                 break;
1958         default:
1959                 switch (csp->csp_auth_alg) {
1960                 case CRYPTO_SHA1:
1961                 case CRYPTO_SHA1_HMAC:
1962                 case CRYPTO_SHA2_224:
1963                 case CRYPTO_SHA2_224_HMAC:
1964                 case CRYPTO_SHA2_256:
1965                 case CRYPTO_SHA2_256_HMAC:
1966                 case CRYPTO_SHA2_384:
1967                 case CRYPTO_SHA2_384_HMAC:
1968                 case CRYPTO_SHA2_512:
1969                 case CRYPTO_SHA2_512_HMAC:
1970                         safexcel_instr_sha_hash(req, instr);
1971                         break;
1972                 case CRYPTO_AES_NIST_GMAC:
1973                         safexcel_instr_gmac(req, instr, cdesc);
1974                         break;
1975                 default:
1976                         panic("unhandled auth request %d", csp->csp_auth_alg);
1977                 }
1978                 break;
1979         }
1980 }
1981
1982 static struct safexcel_res_descr *
1983 safexcel_res_descr_add(struct safexcel_ring *ring, bool first, bool last,
1984     bus_addr_t data, uint32_t len)
1985 {
1986         struct safexcel_res_descr *rdesc;
1987         struct safexcel_res_descr_ring *rring;
1988
1989         mtx_assert(&ring->mtx, MA_OWNED);
1990
1991         rring = &ring->rdr;
1992         if ((rring->write + 1) % SAFEXCEL_RING_SIZE == rring->read)
1993                 return (NULL);
1994
1995         rdesc = &rring->desc[rring->write];
1996         rring->write = (rring->write + 1) % SAFEXCEL_RING_SIZE;
1997
1998         rdesc->particle_size = len;
1999         rdesc->rsvd0 = 0;
2000         rdesc->descriptor_overflow = 0;
2001         rdesc->buffer_overflow = 0;
2002         rdesc->last_seg = last;
2003         rdesc->first_seg = first;
2004         rdesc->result_size =
2005             sizeof(struct safexcel_res_data) / sizeof(uint32_t);
2006         rdesc->rsvd1 = 0;
2007         rdesc->data_lo = SAFEXCEL_ADDR_LO(data);
2008         rdesc->data_hi = SAFEXCEL_ADDR_HI(data);
2009
2010         if (first) {
2011                 rdesc->result_data.packet_length = 0;
2012                 rdesc->result_data.error_code = 0;
2013         }
2014
2015         return (rdesc);
2016 }
2017
2018 static struct safexcel_cmd_descr *
2019 safexcel_cmd_descr_add(struct safexcel_ring *ring, bool first, bool last,
2020     bus_addr_t data, uint32_t seglen, uint32_t reqlen, bus_addr_t context)
2021 {
2022         struct safexcel_cmd_descr *cdesc;
2023         struct safexcel_cmd_descr_ring *cring;
2024
2025         KASSERT(reqlen <= SAFEXCEL_MAX_REQUEST_SIZE,
2026             ("%s: request length %u too long", __func__, reqlen));
2027         mtx_assert(&ring->mtx, MA_OWNED);
2028
2029         cring = &ring->cdr;
2030         if ((cring->write + 1) % SAFEXCEL_RING_SIZE == cring->read)
2031                 return (NULL);
2032
2033         cdesc = &cring->desc[cring->write];
2034         cring->write = (cring->write + 1) % SAFEXCEL_RING_SIZE;
2035
2036         cdesc->particle_size = seglen;
2037         cdesc->rsvd0 = 0;
2038         cdesc->last_seg = last;
2039         cdesc->first_seg = first;
2040         cdesc->additional_cdata_size = 0;
2041         cdesc->rsvd1 = 0;
2042         cdesc->data_lo = SAFEXCEL_ADDR_LO(data);
2043         cdesc->data_hi = SAFEXCEL_ADDR_HI(data);
2044         if (first) {
2045                 cdesc->control_data.packet_length = reqlen;
2046                 cdesc->control_data.options = SAFEXCEL_OPTION_IP |
2047                     SAFEXCEL_OPTION_CP | SAFEXCEL_OPTION_CTX_CTRL_IN_CMD |
2048                     SAFEXCEL_OPTION_RC_AUTO;
2049                 cdesc->control_data.type = SAFEXCEL_TOKEN_TYPE_BYPASS;
2050                 cdesc->control_data.context_lo = SAFEXCEL_ADDR_LO(context) |
2051                     SAFEXCEL_CONTEXT_SMALL;
2052                 cdesc->control_data.context_hi = SAFEXCEL_ADDR_HI(context);
2053         }
2054
2055         return (cdesc);
2056 }
2057
2058 static void
2059 safexcel_cmd_descr_rollback(struct safexcel_ring *ring, int count)
2060 {
2061         struct safexcel_cmd_descr_ring *cring;
2062
2063         mtx_assert(&ring->mtx, MA_OWNED);
2064
2065         cring = &ring->cdr;
2066         cring->write -= count;
2067         if (cring->write < 0)
2068                 cring->write += SAFEXCEL_RING_SIZE;
2069 }
2070
2071 static void
2072 safexcel_res_descr_rollback(struct safexcel_ring *ring, int count)
2073 {
2074         struct safexcel_res_descr_ring *rring;
2075
2076         mtx_assert(&ring->mtx, MA_OWNED);
2077
2078         rring = &ring->rdr;
2079         rring->write -= count;
2080         if (rring->write < 0)
2081                 rring->write += SAFEXCEL_RING_SIZE;
2082 }
2083
2084 static void
2085 safexcel_append_segs(bus_dma_segment_t *segs, int nseg, struct sglist *sg,
2086     int start, int len)
2087 {
2088         bus_dma_segment_t *seg;
2089         size_t seglen;
2090         int error, i;
2091
2092         for (i = 0; i < nseg && len > 0; i++) {
2093                 seg = &segs[i];
2094
2095                 if (seg->ds_len <= start) {
2096                         start -= seg->ds_len;
2097                         continue;
2098                 }
2099
2100                 seglen = MIN(len, seg->ds_len - start);
2101                 error = sglist_append_phys(sg, seg->ds_addr + start, seglen);
2102                 if (error != 0)
2103                         panic("%s: ran out of segments: %d", __func__, error);
2104                 len -= seglen;
2105                 start = 0;
2106         }
2107 }
2108
2109 static void
2110 safexcel_create_chain_cb(void *arg, bus_dma_segment_t *segs, int nseg,
2111     int error)
2112 {
2113         const struct crypto_session_params *csp;
2114         struct cryptop *crp;
2115         struct safexcel_cmd_descr *cdesc;
2116         struct safexcel_request *req;
2117         struct safexcel_ring *ring;
2118         struct safexcel_session *sess;
2119         struct sglist *sg;
2120         size_t inlen;
2121         int i;
2122         bool first, last;
2123
2124         req = arg;
2125         if (error != 0) {
2126                 req->error = error;
2127                 return;
2128         }
2129
2130         crp = req->crp;
2131         csp = crypto_get_params(crp->crp_session);
2132         sess = req->sess;
2133         ring = &req->sc->sc_ring[req->ringidx];
2134
2135         mtx_assert(&ring->mtx, MA_OWNED);
2136
2137         /*
2138          * Set up descriptors for input and output data.
2139          *
2140          * The processing engine programs require that any AAD comes first,
2141          * followed by the cipher plaintext, followed by the digest.  Some
2142          * consumers place the digest first in the input buffer, in which case
2143          * we have to create an extra descriptor.
2144          *
2145          * As an optimization, unmodified data is not passed to the output
2146          * stream.
2147          */
2148         sglist_reset(ring->cmd_data);
2149         sglist_reset(ring->res_data);
2150         if (crp->crp_aad_length != 0) {
2151                 safexcel_append_segs(segs, nseg, ring->cmd_data,
2152                     crp->crp_aad_start, crp->crp_aad_length);
2153         }
2154         safexcel_append_segs(segs, nseg, ring->cmd_data,
2155             crp->crp_payload_start, crp->crp_payload_length);
2156         if (csp->csp_cipher_alg != 0) {
2157                 safexcel_append_segs(segs, nseg, ring->res_data,
2158                     crp->crp_payload_start, crp->crp_payload_length);
2159         }
2160         if (sess->digestlen > 0) {
2161                 if ((crp->crp_op & CRYPTO_OP_VERIFY_DIGEST) != 0) {
2162                         safexcel_append_segs(segs, nseg, ring->cmd_data,
2163                             crp->crp_digest_start, sess->digestlen);
2164                 } else {
2165                         safexcel_append_segs(segs, nseg, ring->res_data,
2166                             crp->crp_digest_start, sess->digestlen);
2167                 }
2168         }
2169
2170         sg = ring->cmd_data;
2171         if (sg->sg_nseg == 0) {
2172                 /*
2173                  * Fake a segment for the command descriptor if the input has
2174                  * length zero.  The EIP97 apparently does not handle
2175                  * zero-length packets properly since subsequent requests return
2176                  * bogus errors, so provide a dummy segment using the context
2177                  * descriptor.  Also, we must allocate at least one command ring
2178                  * entry per request to keep the request shadow ring in sync.
2179                  */
2180                 (void)sglist_append_phys(sg, req->ctx.paddr, 1);
2181         }
2182         for (i = 0, inlen = 0; i < sg->sg_nseg; i++)
2183                 inlen += sg->sg_segs[i].ss_len;
2184         for (i = 0; i < sg->sg_nseg; i++) {
2185                 first = i == 0;
2186                 last = i == sg->sg_nseg - 1;
2187
2188                 cdesc = safexcel_cmd_descr_add(ring, first, last,
2189                     sg->sg_segs[i].ss_paddr, sg->sg_segs[i].ss_len,
2190                     (uint32_t)inlen, req->ctx.paddr);
2191                 if (cdesc == NULL) {
2192                         safexcel_cmd_descr_rollback(ring, i);
2193                         counter_u64_add(req->sc->sc_cdesc_alloc_failures, 1);
2194                         req->error = ERESTART;
2195                         return;
2196                 }
2197                 if (i == 0)
2198                         req->cdesc = cdesc;
2199         }
2200         req->cdescs = sg->sg_nseg;
2201
2202         sg = ring->res_data;
2203         if (sg->sg_nseg == 0) {
2204                 /*
2205                  * We need a result descriptor even if the output stream will be
2206                  * empty, for example when verifying an AAD digest.
2207                  */
2208                 sg->sg_segs[0].ss_paddr = 0;
2209                 sg->sg_segs[0].ss_len = 0;
2210                 sg->sg_nseg = 1;
2211         }
2212         for (i = 0; i < sg->sg_nseg; i++) {
2213                 first = i == 0;
2214                 last = i == sg->sg_nseg - 1;
2215
2216                 if (safexcel_res_descr_add(ring, first, last,
2217                     sg->sg_segs[i].ss_paddr, sg->sg_segs[i].ss_len) == NULL) {
2218                         safexcel_cmd_descr_rollback(ring,
2219                             ring->cmd_data->sg_nseg);
2220                         safexcel_res_descr_rollback(ring, i);
2221                         counter_u64_add(req->sc->sc_rdesc_alloc_failures, 1);
2222                         req->error = ERESTART;
2223                         return;
2224                 }
2225         }
2226         req->rdescs = sg->sg_nseg;
2227 }
2228
2229 static int
2230 safexcel_create_chain(struct safexcel_ring *ring, struct safexcel_request *req)
2231 {
2232         int error;
2233
2234         req->error = 0;
2235         req->cdescs = req->rdescs = 0;
2236
2237         error = bus_dmamap_load_crp(ring->data_dtag, req->dmap, req->crp,
2238             safexcel_create_chain_cb, req, BUS_DMA_NOWAIT);
2239         if (error == 0)
2240                 req->dmap_loaded = true;
2241
2242         if (req->error != 0)
2243                 error = req->error;
2244
2245         return (error);
2246 }
2247
2248 static bool
2249 safexcel_probe_cipher(const struct crypto_session_params *csp)
2250 {
2251         switch (csp->csp_cipher_alg) {
2252         case CRYPTO_AES_CBC:
2253         case CRYPTO_AES_ICM:
2254                 if (csp->csp_ivlen != AES_BLOCK_LEN)
2255                         return (false);
2256                 break;
2257         case CRYPTO_AES_XTS:
2258                 if (csp->csp_ivlen != AES_XTS_IV_LEN)
2259                         return (false);
2260                 break;
2261         default:
2262                 return (false);
2263         }
2264
2265         return (true);
2266 }
2267
2268 /*
2269  * Determine whether the driver can implement a session with the requested
2270  * parameters.
2271  */
2272 static int
2273 safexcel_probesession(device_t dev, const struct crypto_session_params *csp)
2274 {
2275         if (csp->csp_flags != 0)
2276                 return (EINVAL);
2277
2278         switch (csp->csp_mode) {
2279         case CSP_MODE_CIPHER:
2280                 if (!safexcel_probe_cipher(csp))
2281                         return (EINVAL);
2282                 break;
2283         case CSP_MODE_DIGEST:
2284                 switch (csp->csp_auth_alg) {
2285                 case CRYPTO_AES_NIST_GMAC:
2286                         if (csp->csp_ivlen != AES_GCM_IV_LEN)
2287                                 return (EINVAL);
2288                         break;
2289                 case CRYPTO_SHA1:
2290                 case CRYPTO_SHA1_HMAC:
2291                 case CRYPTO_SHA2_224:
2292                 case CRYPTO_SHA2_224_HMAC:
2293                 case CRYPTO_SHA2_256:
2294                 case CRYPTO_SHA2_256_HMAC:
2295                 case CRYPTO_SHA2_384:
2296                 case CRYPTO_SHA2_384_HMAC:
2297                 case CRYPTO_SHA2_512:
2298                 case CRYPTO_SHA2_512_HMAC:
2299                         break;
2300                 default:
2301                         return (EINVAL);
2302                 }
2303                 break;
2304         case CSP_MODE_AEAD:
2305                 switch (csp->csp_cipher_alg) {
2306                 case CRYPTO_AES_NIST_GCM_16:
2307                         if (csp->csp_ivlen != AES_GCM_IV_LEN)
2308                                 return (EINVAL);
2309                         break;
2310                 case CRYPTO_AES_CCM_16:
2311                         if (csp->csp_ivlen != AES_CCM_IV_LEN)
2312                                 return (EINVAL);
2313                         break;
2314                 default:
2315                         return (EINVAL);
2316                 }
2317                 break;
2318         case CSP_MODE_ETA:
2319                 if (!safexcel_probe_cipher(csp))
2320                         return (EINVAL);
2321                 switch (csp->csp_cipher_alg) {
2322                 case CRYPTO_AES_CBC:
2323                 case CRYPTO_AES_ICM:
2324                         /*
2325                          * The EIP-97 does not support combining AES-XTS with
2326                          * hash operations.
2327                          */
2328                         if (csp->csp_auth_alg != CRYPTO_SHA1_HMAC &&
2329                             csp->csp_auth_alg != CRYPTO_SHA2_224_HMAC &&
2330                             csp->csp_auth_alg != CRYPTO_SHA2_256_HMAC &&
2331                             csp->csp_auth_alg != CRYPTO_SHA2_384_HMAC &&
2332                             csp->csp_auth_alg != CRYPTO_SHA2_512_HMAC)
2333                                 return (EINVAL);
2334                         break;
2335                 default:
2336                         return (EINVAL);
2337                 }
2338                 break;
2339         default:
2340                 return (EINVAL);
2341         }
2342
2343         return (CRYPTODEV_PROBE_HARDWARE);
2344 }
2345
2346 static uint32_t
2347 safexcel_aes_algid(int keylen)
2348 {
2349         switch (keylen) {
2350         case 16:
2351                 return (SAFEXCEL_CONTROL0_CRYPTO_ALG_AES128);
2352         case 24:
2353                 return (SAFEXCEL_CONTROL0_CRYPTO_ALG_AES192);
2354         case 32:
2355                 return (SAFEXCEL_CONTROL0_CRYPTO_ALG_AES256);
2356         default:
2357                 panic("invalid AES key length %d", keylen);
2358         }
2359 }
2360
2361 static uint32_t
2362 safexcel_aes_ccm_hashid(int keylen)
2363 {
2364         switch (keylen) {
2365         case 16:
2366                 return (SAFEXCEL_CONTROL0_HASH_ALG_XCBC128);
2367         case 24:
2368                 return (SAFEXCEL_CONTROL0_HASH_ALG_XCBC192);
2369         case 32:
2370                 return (SAFEXCEL_CONTROL0_HASH_ALG_XCBC256);
2371         default:
2372                 panic("invalid AES key length %d", keylen);
2373         }
2374 }
2375
2376 static uint32_t
2377 safexcel_sha_hashid(int alg)
2378 {
2379         switch (alg) {
2380         case CRYPTO_SHA1:
2381         case CRYPTO_SHA1_HMAC:
2382                 return (SAFEXCEL_CONTROL0_HASH_ALG_SHA1);
2383         case CRYPTO_SHA2_224:
2384         case CRYPTO_SHA2_224_HMAC:
2385                 return (SAFEXCEL_CONTROL0_HASH_ALG_SHA224);
2386         case CRYPTO_SHA2_256:
2387         case CRYPTO_SHA2_256_HMAC:
2388                 return (SAFEXCEL_CONTROL0_HASH_ALG_SHA256);
2389         case CRYPTO_SHA2_384:
2390         case CRYPTO_SHA2_384_HMAC:
2391                 return (SAFEXCEL_CONTROL0_HASH_ALG_SHA384);
2392         case CRYPTO_SHA2_512:
2393         case CRYPTO_SHA2_512_HMAC:
2394                 return (SAFEXCEL_CONTROL0_HASH_ALG_SHA512);
2395         default:
2396                 __assert_unreachable();
2397         }
2398 }
2399
2400 static int
2401 safexcel_sha_hashlen(int alg)
2402 {
2403         switch (alg) {
2404         case CRYPTO_SHA1:
2405         case CRYPTO_SHA1_HMAC:
2406                 return (SHA1_HASH_LEN);
2407         case CRYPTO_SHA2_224:
2408         case CRYPTO_SHA2_224_HMAC:
2409                 return (SHA2_224_HASH_LEN);
2410         case CRYPTO_SHA2_256:
2411         case CRYPTO_SHA2_256_HMAC:
2412                 return (SHA2_256_HASH_LEN);
2413         case CRYPTO_SHA2_384:
2414         case CRYPTO_SHA2_384_HMAC:
2415                 return (SHA2_384_HASH_LEN);
2416         case CRYPTO_SHA2_512:
2417         case CRYPTO_SHA2_512_HMAC:
2418                 return (SHA2_512_HASH_LEN);
2419         default:
2420                 __assert_unreachable();
2421         }
2422 }
2423
2424 static int
2425 safexcel_sha_statelen(int alg)
2426 {
2427         switch (alg) {
2428         case CRYPTO_SHA1:
2429         case CRYPTO_SHA1_HMAC:
2430                 return (SHA1_HASH_LEN);
2431         case CRYPTO_SHA2_224:
2432         case CRYPTO_SHA2_224_HMAC:
2433         case CRYPTO_SHA2_256:
2434         case CRYPTO_SHA2_256_HMAC:
2435                 return (SHA2_256_HASH_LEN);
2436         case CRYPTO_SHA2_384:
2437         case CRYPTO_SHA2_384_HMAC:
2438         case CRYPTO_SHA2_512:
2439         case CRYPTO_SHA2_512_HMAC:
2440                 return (SHA2_512_HASH_LEN);
2441         default:
2442                 __assert_unreachable();
2443         }
2444 }
2445
2446 static int
2447 safexcel_newsession(device_t dev, crypto_session_t cses,
2448     const struct crypto_session_params *csp)
2449 {
2450         struct safexcel_session *sess;
2451         struct safexcel_softc *sc;
2452
2453         sc = device_get_softc(dev);
2454         sess = crypto_get_driver_session(cses);
2455         sess->cses = cses;
2456
2457         switch (csp->csp_auth_alg) {
2458         case CRYPTO_SHA1:
2459         case CRYPTO_SHA2_224:
2460         case CRYPTO_SHA2_256:
2461         case CRYPTO_SHA2_384:
2462         case CRYPTO_SHA2_512:
2463                 sess->digest = SAFEXCEL_CONTROL0_DIGEST_PRECOMPUTED;
2464                 sess->hash = safexcel_sha_hashid(csp->csp_auth_alg);
2465                 sess->digestlen = safexcel_sha_hashlen(csp->csp_auth_alg);
2466                 sess->statelen = safexcel_sha_statelen(csp->csp_auth_alg);
2467                 break;
2468         case CRYPTO_SHA1_HMAC:
2469         case CRYPTO_SHA2_224_HMAC:
2470         case CRYPTO_SHA2_256_HMAC:
2471         case CRYPTO_SHA2_384_HMAC:
2472         case CRYPTO_SHA2_512_HMAC:
2473                 sess->digest = SAFEXCEL_CONTROL0_DIGEST_HMAC;
2474                 sess->hash = safexcel_sha_hashid(csp->csp_auth_alg);
2475                 sess->digestlen = safexcel_sha_hashlen(csp->csp_auth_alg);
2476                 sess->statelen = safexcel_sha_statelen(csp->csp_auth_alg);
2477                 break;
2478         case CRYPTO_AES_NIST_GMAC:
2479                 sess->digest = SAFEXCEL_CONTROL0_DIGEST_GMAC;
2480                 sess->digestlen = GMAC_DIGEST_LEN;
2481                 sess->hash = SAFEXCEL_CONTROL0_HASH_ALG_GHASH;
2482                 sess->alg = safexcel_aes_algid(csp->csp_auth_klen);
2483                 sess->mode = SAFEXCEL_CONTROL1_CRYPTO_MODE_GCM;
2484                 break;
2485         }
2486
2487         switch (csp->csp_cipher_alg) {
2488         case CRYPTO_AES_NIST_GCM_16:
2489                 sess->digest = SAFEXCEL_CONTROL0_DIGEST_GMAC;
2490                 sess->digestlen = GMAC_DIGEST_LEN;
2491                 sess->hash = SAFEXCEL_CONTROL0_HASH_ALG_GHASH;
2492                 sess->alg = safexcel_aes_algid(csp->csp_cipher_klen);
2493                 sess->mode = SAFEXCEL_CONTROL1_CRYPTO_MODE_GCM;
2494                 break;
2495         case CRYPTO_AES_CCM_16:
2496                 sess->hash = safexcel_aes_ccm_hashid(csp->csp_cipher_klen);
2497                 sess->digest = SAFEXCEL_CONTROL0_DIGEST_CCM;
2498                 sess->digestlen = CCM_CBC_MAX_DIGEST_LEN;
2499                 sess->alg = safexcel_aes_algid(csp->csp_cipher_klen);
2500                 sess->mode = SAFEXCEL_CONTROL1_CRYPTO_MODE_CCM;
2501                 break;
2502         case CRYPTO_AES_CBC:
2503                 sess->alg = safexcel_aes_algid(csp->csp_cipher_klen);
2504                 sess->mode = SAFEXCEL_CONTROL1_CRYPTO_MODE_CBC;
2505                 break;
2506         case CRYPTO_AES_ICM:
2507                 sess->alg = safexcel_aes_algid(csp->csp_cipher_klen);
2508                 sess->mode = SAFEXCEL_CONTROL1_CRYPTO_MODE_CTR;
2509                 break;
2510         case CRYPTO_AES_XTS:
2511                 sess->alg = safexcel_aes_algid(csp->csp_cipher_klen / 2);
2512                 sess->mode = SAFEXCEL_CONTROL1_CRYPTO_MODE_XTS;
2513                 break;
2514         }
2515
2516         if (csp->csp_auth_mlen != 0)
2517                 sess->digestlen = csp->csp_auth_mlen;
2518
2519         if ((csp->csp_cipher_alg == 0 || csp->csp_cipher_key != NULL) &&
2520             (csp->csp_auth_alg == 0 || csp->csp_auth_key != NULL)) {
2521                 sess->encctx.len = safexcel_set_context(&sess->encctx.ctx,
2522                     CRYPTO_OP_ENCRYPT, csp->csp_cipher_key, csp->csp_auth_key,
2523                     sess);
2524                 sess->decctx.len = safexcel_set_context(&sess->decctx.ctx,
2525                     CRYPTO_OP_DECRYPT, csp->csp_cipher_key, csp->csp_auth_key,
2526                     sess);
2527         }
2528
2529         return (0);
2530 }
2531
2532 static int
2533 safexcel_process(device_t dev, struct cryptop *crp, int hint)
2534 {
2535         const struct crypto_session_params *csp;
2536         struct safexcel_request *req;
2537         struct safexcel_ring *ring;
2538         struct safexcel_session *sess;
2539         struct safexcel_softc *sc;
2540         int error;
2541
2542         sc = device_get_softc(dev);
2543         sess = crypto_get_driver_session(crp->crp_session);
2544         csp = crypto_get_params(crp->crp_session);
2545
2546         if (__predict_false(crypto_buffer_len(&crp->crp_buf) >
2547             SAFEXCEL_MAX_REQUEST_SIZE)) {
2548                 crp->crp_etype = E2BIG;
2549                 crypto_done(crp);
2550                 return (0);
2551         }
2552
2553         ring = &sc->sc_ring[curcpu % sc->sc_config.rings];
2554         mtx_lock(&ring->mtx);
2555         req = safexcel_alloc_request(sc, ring);
2556         if (__predict_false(req == NULL)) {
2557                 ring->blocked = CRYPTO_SYMQ;
2558                 mtx_unlock(&ring->mtx);
2559                 counter_u64_add(sc->sc_req_alloc_failures, 1);
2560                 return (ERESTART);
2561         }
2562
2563         req->crp = crp;
2564         req->sess = sess;
2565
2566         crypto_read_iv(crp, req->iv);
2567
2568         error = safexcel_create_chain(ring, req);
2569         if (__predict_false(error != 0)) {
2570                 safexcel_free_request(ring, req);
2571                 if (error == ERESTART)
2572                         ring->blocked = CRYPTO_SYMQ;
2573                 mtx_unlock(&ring->mtx);
2574                 if (error != ERESTART) {
2575                         crp->crp_etype = error;
2576                         crypto_done(crp);
2577                         return (0);
2578                 } else {
2579                         return (ERESTART);
2580                 }
2581         }
2582
2583         safexcel_set_token(req);
2584
2585         bus_dmamap_sync(ring->data_dtag, req->dmap,
2586             BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
2587         bus_dmamap_sync(req->ctx.tag, req->ctx.map,
2588             BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
2589         bus_dmamap_sync(ring->cdr.dma.tag, ring->cdr.dma.map,
2590             BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
2591         bus_dmamap_sync(ring->dma_atok.tag, ring->dma_atok.map,
2592             BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
2593         bus_dmamap_sync(ring->rdr.dma.tag, ring->rdr.dma.map,
2594             BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
2595
2596         safexcel_execute(sc, ring, req, hint);
2597
2598         mtx_unlock(&ring->mtx);
2599
2600         return (0);
2601 }
2602
2603 static device_method_t safexcel_methods[] = {
2604         /* Device interface */
2605         DEVMETHOD(device_probe,         safexcel_probe),
2606         DEVMETHOD(device_attach,        safexcel_attach),
2607         DEVMETHOD(device_detach,        safexcel_detach),
2608
2609         /* Cryptodev interface */
2610         DEVMETHOD(cryptodev_probesession, safexcel_probesession),
2611         DEVMETHOD(cryptodev_newsession, safexcel_newsession),
2612         DEVMETHOD(cryptodev_process,    safexcel_process),
2613
2614         DEVMETHOD_END
2615 };
2616
2617 static devclass_t safexcel_devclass;
2618
2619 static driver_t safexcel_driver = {
2620         .name           = "safexcel",
2621         .methods        = safexcel_methods,
2622         .size           = sizeof(struct safexcel_softc),
2623 };
2624
2625 DRIVER_MODULE(safexcel, simplebus, safexcel_driver, safexcel_devclass, 0, 0);
2626 MODULE_VERSION(safexcel, 1);
2627 MODULE_DEPEND(safexcel, crypto, 1, 1, 1);