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