Home | History | Annotate | Line # | Download | only in marvell
mvxpsec.c revision 1.3
      1 /*	$NetBSD: mvxpsec.c,v 1.3 2019/10/15 00:13:53 chs Exp $	*/
      2 /*
      3  * Copyright (c) 2015 Internet Initiative Japan Inc.
      4  * All rights reserved.
      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
     17  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     18  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
     19  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
     20  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
     21  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
     23  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
     24  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     25  * POSSIBILITY OF SUCH DAMAGE.
     26  */
     27 /*
     28  * Cryptographic Engine and Security Accelerator(MVXPSEC)
     29  */
     30 #include <sys/cdefs.h>
     31 #include <sys/param.h>
     32 #include <sys/types.h>
     33 #include <sys/kernel.h>
     34 #include <sys/queue.h>
     35 #include <sys/conf.h>
     36 #include <sys/proc.h>
     37 #include <sys/bus.h>
     38 #include <sys/evcnt.h>
     39 #include <sys/device.h>
     40 #include <sys/endian.h>
     41 #include <sys/errno.h>
     42 #include <sys/kmem.h>
     43 #include <sys/mbuf.h>
     44 #include <sys/callout.h>
     45 #include <sys/pool.h>
     46 #include <sys/cprng.h>
     47 #include <sys/syslog.h>
     48 #include <sys/mutex.h>
     49 #include <sys/kthread.h>
     50 #include <sys/atomic.h>
     51 #include <sys/sha1.h>
     52 #include <sys/md5.h>
     53 
     54 #include <uvm/uvm_extern.h>
     55 
     56 #include <crypto/rijndael/rijndael.h>
     57 
     58 #include <opencrypto/cryptodev.h>
     59 #include <opencrypto/xform.h>
     60 
     61 #include <net/net_stats.h>
     62 
     63 #include <netinet/in_systm.h>
     64 #include <netinet/in.h>
     65 #include <netinet/ip.h>
     66 #include <netinet/ip6.h>
     67 
     68 #include <netipsec/esp_var.h>
     69 
     70 #include <arm/cpufunc.h>
     71 #include <arm/marvell/mvsocvar.h>
     72 #include <arm/marvell/armadaxpreg.h>
     73 #include <dev/marvell/marvellreg.h>
     74 #include <dev/marvell/marvellvar.h>
     75 #include <dev/marvell/mvxpsecreg.h>
     76 #include <dev/marvell/mvxpsecvar.h>
     77 
     78 #ifdef DEBUG
     79 #define STATIC __attribute__ ((noinline)) extern
     80 #define _STATIC __attribute__ ((noinline)) extern
     81 #define INLINE __attribute__ ((noinline)) extern
     82 #define _INLINE __attribute__ ((noinline)) extern
     83 #else
     84 #define STATIC static
     85 #define _STATIC __attribute__ ((unused)) static
     86 #define INLINE static inline
     87 #define _INLINE __attribute__ ((unused)) static inline
     88 #endif
     89 
     90 /*
     91  * IRQ and SRAM spaces for each of unit
     92  * XXX: move to attach_args
     93  */
     94 struct {
     95 	int		err_int;
     96 } mvxpsec_config[] = {
     97 	{ .err_int = ARMADAXP_IRQ_CESA0_ERR, }, /* unit 0 */
     98 	{ .err_int = ARMADAXP_IRQ_CESA1_ERR, }, /* unit 1 */
     99 };
    100 #define MVXPSEC_ERR_INT(sc) \
    101     mvxpsec_config[device_unit((sc)->sc_dev)].err_int
    102 
    103 /*
    104  * AES
    105  */
    106 #define MAXBC				(128/32)
    107 #define MAXKC				(256/32)
    108 #define MAXROUNDS			14
    109 STATIC int mv_aes_ksched(uint8_t[4][MAXKC], int,
    110     uint8_t[MAXROUNDS+1][4][MAXBC]);
    111 STATIC int mv_aes_deckey(uint8_t *, uint8_t *, int);
    112 
    113 /*
    114  * device driver autoconf interface
    115  */
    116 STATIC int mvxpsec_match(device_t, cfdata_t, void *);
    117 STATIC void mvxpsec_attach(device_t, device_t, void *);
    118 STATIC void mvxpsec_evcnt_attach(struct mvxpsec_softc *);
    119 
    120 /*
    121  * register setup
    122  */
    123 STATIC int mvxpsec_wininit(struct mvxpsec_softc *, enum marvell_tags *);
    124 
    125 /*
    126  * timer(callout) interface
    127  *
    128  * XXX: callout is not MP safe...
    129  */
    130 STATIC void mvxpsec_timer(void *);
    131 
    132 /*
    133  * interrupt interface
    134  */
    135 STATIC int mvxpsec_intr(void *);
    136 INLINE void mvxpsec_intr_cleanup(struct mvxpsec_softc *);
    137 STATIC int mvxpsec_eintr(void *);
    138 STATIC uint32_t mvxpsec_intr_ack(struct mvxpsec_softc *);
    139 STATIC uint32_t mvxpsec_eintr_ack(struct mvxpsec_softc *);
    140 INLINE void mvxpsec_intr_cnt(struct mvxpsec_softc *, int);
    141 
    142 /*
    143  * memory allocators and VM management
    144  */
    145 STATIC struct mvxpsec_devmem *mvxpsec_alloc_devmem(struct mvxpsec_softc *,
    146     paddr_t, int);
    147 STATIC int mvxpsec_init_sram(struct mvxpsec_softc *);
    148 
    149 /*
    150  * Low-level DMA interface
    151  */
    152 STATIC int mvxpsec_init_dma(struct mvxpsec_softc *,
    153     struct marvell_attach_args *);
    154 INLINE int mvxpsec_dma_wait(struct mvxpsec_softc *);
    155 INLINE int mvxpsec_acc_wait(struct mvxpsec_softc *);
    156 INLINE struct mvxpsec_descriptor_handle *mvxpsec_dma_getdesc(struct mvxpsec_softc *);
    157 _INLINE void mvxpsec_dma_putdesc(struct mvxpsec_softc *, struct mvxpsec_descriptor_handle *);
    158 INLINE void mvxpsec_dma_setup(struct mvxpsec_descriptor_handle *,
    159     uint32_t, uint32_t, uint32_t);
    160 INLINE void mvxpsec_dma_cat(struct mvxpsec_softc *,
    161     struct mvxpsec_descriptor_handle *, struct mvxpsec_descriptor_handle *);
    162 
    163 /*
    164  * High-level DMA interface
    165  */
    166 INLINE int mvxpsec_dma_copy0(struct mvxpsec_softc *,
    167     mvxpsec_dma_ring *, uint32_t, uint32_t, uint32_t);
    168 INLINE int mvxpsec_dma_copy(struct mvxpsec_softc *,
    169     mvxpsec_dma_ring *, uint32_t, uint32_t, uint32_t);
    170 INLINE int mvxpsec_dma_acc_activate(struct mvxpsec_softc *,
    171     mvxpsec_dma_ring *);
    172 INLINE void mvxpsec_dma_finalize(struct mvxpsec_softc *,
    173     mvxpsec_dma_ring *);
    174 INLINE void mvxpsec_dma_free(struct mvxpsec_softc *,
    175     mvxpsec_dma_ring *);
    176 INLINE int mvxpsec_dma_copy_packet(struct mvxpsec_softc *, struct mvxpsec_packet *);
    177 INLINE int mvxpsec_dma_sync_packet(struct mvxpsec_softc *, struct mvxpsec_packet *);
    178 
    179 /*
    180  * Session management interface (OpenCrypto)
    181  */
    182 #define MVXPSEC_SESSION(sid)	((sid) & 0x0fffffff)
    183 #define MVXPSEC_SID(crd, sesn)	(((crd) << 28) | ((sesn) & 0x0fffffff))
    184 /* pool management */
    185 STATIC int mvxpsec_session_ctor(void *, void *, int);
    186 STATIC void mvxpsec_session_dtor(void *, void *);
    187 STATIC int mvxpsec_packet_ctor(void *, void *, int);
    188 STATIC void mvxpsec_packet_dtor(void *, void *);
    189 
    190 /* session management */
    191 STATIC struct mvxpsec_session *mvxpsec_session_alloc(struct mvxpsec_softc *);
    192 STATIC void mvxpsec_session_dealloc(struct mvxpsec_session *);
    193 INLINE struct mvxpsec_session *mvxpsec_session_lookup(struct mvxpsec_softc *, int);
    194 INLINE int mvxpsec_session_ref(struct mvxpsec_session *);
    195 INLINE void mvxpsec_session_unref(struct mvxpsec_session *);
    196 
    197 /* packet management */
    198 STATIC struct mvxpsec_packet *mvxpsec_packet_alloc(struct mvxpsec_session *);
    199 INLINE void mvxpsec_packet_enqueue(struct mvxpsec_packet *);
    200 STATIC void mvxpsec_packet_dealloc(struct mvxpsec_packet *);
    201 STATIC int mvxpsec_done_packet(struct mvxpsec_packet *);
    202 
    203 /* session header manegement */
    204 STATIC int mvxpsec_header_finalize(struct mvxpsec_packet *);
    205 
    206 /* packet queue management */
    207 INLINE void mvxpsec_drop(struct mvxpsec_softc *, struct cryptop *, struct mvxpsec_packet *, int);
    208 STATIC int mvxpsec_dispatch_queue(struct mvxpsec_softc *);
    209 
    210 /* opencrypto opration */
    211 INLINE int mvxpsec_parse_crd(struct mvxpsec_packet *, struct cryptodesc *);
    212 INLINE int mvxpsec_parse_crp(struct mvxpsec_packet *);
    213 
    214 /* payload data management */
    215 INLINE int mvxpsec_packet_setcrp(struct mvxpsec_packet *, struct cryptop *);
    216 STATIC int mvxpsec_packet_setdata(struct mvxpsec_packet *, void *, uint32_t);
    217 STATIC int mvxpsec_packet_setmbuf(struct mvxpsec_packet *, struct mbuf *);
    218 STATIC int mvxpsec_packet_setuio(struct mvxpsec_packet *, struct uio *);
    219 STATIC int mvxpsec_packet_rdata(struct mvxpsec_packet *, int, int, void *);
    220 _STATIC int mvxpsec_packet_wdata(struct mvxpsec_packet *, int, int, void *);
    221 STATIC int mvxpsec_packet_write_iv(struct mvxpsec_packet *, void *, int);
    222 STATIC int mvxpsec_packet_copy_iv(struct mvxpsec_packet *, int, int);
    223 
    224 /* key pre-computation */
    225 STATIC int mvxpsec_key_precomp(int, void *, int, void *, void *);
    226 STATIC int mvxpsec_hmac_precomp(int, void *, int, void *, void *);
    227 
    228 /* crypto operation management */
    229 INLINE void mvxpsec_packet_reset_op(struct mvxpsec_packet *);
    230 INLINE void mvxpsec_packet_update_op_order(struct mvxpsec_packet *, int);
    231 
    232 /*
    233  * parameter converters
    234  */
    235 INLINE uint32_t mvxpsec_alg2acc(uint32_t alg);
    236 INLINE uint32_t mvxpsec_aesklen(int klen);
    237 
    238 /*
    239  * string formatters
    240  */
    241 _STATIC const char *s_ctrlreg(uint32_t);
    242 _STATIC const char *s_winreg(uint32_t);
    243 _STATIC const char *s_errreg(uint32_t);
    244 _STATIC const char *s_xpsecintr(uint32_t);
    245 _STATIC const char *s_ctlalg(uint32_t);
    246 _STATIC const char *s_xpsec_op(uint32_t);
    247 _STATIC const char *s_xpsec_enc(uint32_t);
    248 _STATIC const char *s_xpsec_mac(uint32_t);
    249 _STATIC const char *s_xpsec_frag(uint32_t);
    250 
    251 /*
    252  * debugging supports
    253  */
    254 #ifdef MVXPSEC_DEBUG
    255 _STATIC void mvxpsec_dump_dmaq(struct mvxpsec_descriptor_handle *);
    256 _STATIC void mvxpsec_dump_reg(struct mvxpsec_softc *);
    257 _STATIC void mvxpsec_dump_sram(const char *, struct mvxpsec_softc *, size_t);
    258 _STATIC void mvxpsec_dump_data(const char *, void *, size_t);
    259 
    260 _STATIC void mvxpsec_dump_packet(const char *, struct mvxpsec_packet *);
    261 _STATIC void mvxpsec_dump_packet_data(const char *, struct mvxpsec_packet *);
    262 _STATIC void mvxpsec_dump_packet_desc(const char *, struct mvxpsec_packet *);
    263 
    264 _STATIC void mvxpsec_dump_acc_config(const char *, uint32_t);
    265 _STATIC void mvxpsec_dump_acc_encdata(const char *, uint32_t, uint32_t);
    266 _STATIC void mvxpsec_dump_acc_enclen(const char *, uint32_t);
    267 _STATIC void mvxpsec_dump_acc_enckey(const char *, uint32_t);
    268 _STATIC void mvxpsec_dump_acc_enciv(const char *, uint32_t);
    269 _STATIC void mvxpsec_dump_acc_macsrc(const char *, uint32_t);
    270 _STATIC void mvxpsec_dump_acc_macdst(const char *, uint32_t);
    271 _STATIC void mvxpsec_dump_acc_maciv(const char *, uint32_t);
    272 #endif
    273 
    274 /*
    275  * global configurations, params, work spaces, ...
    276  *
    277  * XXX: use sysctl for global configurations
    278  */
    279 /* waiting for device */
    280 static int mvxpsec_wait_interval = 10;		/* usec */
    281 static int mvxpsec_wait_retry = 100;		/* times = wait for 1 [msec] */
    282 #ifdef MVXPSEC_DEBUG
    283 static uint32_t mvxpsec_debug = MVXPSEC_DEBUG;	/* debug level */
    284 #endif
    285 
    286 /*
    287  * Register accessors
    288  */
    289 #define MVXPSEC_WRITE(sc, off, val) \
    290 	bus_space_write_4((sc)->sc_iot, (sc)->sc_ioh, (off), (val))
    291 #define MVXPSEC_READ(sc, off) \
    292 	bus_space_read_4((sc)->sc_iot, (sc)->sc_ioh, (off))
    293 
    294 /*
    295  * device driver autoconf interface
    296  */
    297 CFATTACH_DECL2_NEW(mvxpsec_mbus, sizeof(struct mvxpsec_softc),
    298     mvxpsec_match, mvxpsec_attach, NULL, NULL, NULL, NULL);
    299 
    300 STATIC int
    301 mvxpsec_match(device_t dev, cfdata_t match, void *aux)
    302 {
    303 	struct marvell_attach_args *mva = aux;
    304 	uint32_t tag;
    305 	int window;
    306 
    307 	if (strcmp(mva->mva_name, match->cf_name) != 0)
    308 		return 0;
    309 	if (mva->mva_offset == MVA_OFFSET_DEFAULT)
    310 		return 0;
    311 
    312 	switch (mva->mva_unit) {
    313 	case 0:
    314 		tag = ARMADAXP_TAG_CRYPT0;
    315 		break;
    316 	case 1:
    317 		tag = ARMADAXP_TAG_CRYPT1;
    318 		break;
    319 	default:
    320 		aprint_error_dev(dev,
    321 		    "unit %d is not supported\n", mva->mva_unit);
    322 		return 0;
    323 	}
    324 
    325 	window = mvsoc_target(tag, NULL, NULL, NULL, NULL);
    326 	if (window >= nwindow) {
    327 		aprint_error_dev(dev,
    328 		    "Security Accelerator SRAM is not configured.\n");
    329 		return 0;
    330 	}
    331 
    332 	return 1;
    333 }
    334 
    335 STATIC void
    336 mvxpsec_attach(device_t parent, device_t self, void *aux)
    337 {
    338 	struct marvell_attach_args *mva = aux;
    339 	struct mvxpsec_softc *sc = device_private(self);
    340 	int v;
    341 	int i;
    342 
    343 	sc->sc_dev = self;
    344 
    345 	aprint_normal(": Marvell Crypto Engines and Security Accelerator\n");
    346 	aprint_naive("\n");
    347 #ifdef MVXPSEC_MULTI_PACKET
    348 	aprint_normal_dev(sc->sc_dev, "multi-packet chained mode enabled.\n");
    349 #else
    350 	aprint_normal_dev(sc->sc_dev, "multi-packet chained mode disabled.\n");
    351 #endif
    352 	aprint_normal_dev(sc->sc_dev,
    353 	    "Max %d sessions.\n", MVXPSEC_MAX_SESSIONS);
    354 
    355 	/* mutex */
    356 	mutex_init(&sc->sc_session_mtx, MUTEX_DEFAULT, IPL_NET);
    357 	mutex_init(&sc->sc_dma_mtx, MUTEX_DEFAULT, IPL_NET);
    358 	mutex_init(&sc->sc_queue_mtx, MUTEX_DEFAULT, IPL_NET);
    359 
    360 	/* Packet queue */
    361 	SIMPLEQ_INIT(&sc->sc_wait_queue);
    362 	SIMPLEQ_INIT(&sc->sc_run_queue);
    363 	SLIST_INIT(&sc->sc_free_list);
    364 	sc->sc_wait_qlen = 0;
    365 #ifdef MVXPSEC_MULTI_PACKET
    366 	sc->sc_wait_qlimit = 16;
    367 #else
    368 	sc->sc_wait_qlimit = 0;
    369 #endif
    370 	sc->sc_free_qlen = 0;
    371 
    372 	/* Timer */
    373 	callout_init(&sc->sc_timeout, 0); /* XXX: use CALLOUT_MPSAFE */
    374 	callout_setfunc(&sc->sc_timeout, mvxpsec_timer, sc);
    375 
    376 	/* I/O */
    377 	sc->sc_iot = mva->mva_iot;
    378 	if (bus_space_subregion(mva->mva_iot, mva->mva_ioh,
    379 	    mva->mva_offset, mva->mva_size, &sc->sc_ioh)) {
    380 		aprint_error_dev(self, "Cannot map registers\n");
    381 		return;
    382 	}
    383 
    384 	/* DMA */
    385 	sc->sc_dmat = mva->mva_dmat;
    386 	if (mvxpsec_init_dma(sc, mva) < 0)
    387 		return;
    388 
    389 	/* SRAM */
    390 	if (mvxpsec_init_sram(sc) < 0)
    391 		return;
    392 
    393 	/* Registers */
    394 	mvxpsec_wininit(sc, mva->mva_tags);
    395 
    396 	/* INTR */
    397 	MVXPSEC_WRITE(sc, MVXPSEC_INT_MASK, MVXPSEC_DEFAULT_INT);
    398 	MVXPSEC_WRITE(sc, MV_TDMA_ERR_MASK, MVXPSEC_DEFAULT_ERR);
    399 	sc->sc_done_ih =
    400 	    marvell_intr_establish(mva->mva_irq, IPL_NET, mvxpsec_intr, sc);
    401 	/* XXX: sould pass error IRQ using mva */
    402 	sc->sc_error_ih = marvell_intr_establish(MVXPSEC_ERR_INT(sc),
    403 	    IPL_NET, mvxpsec_eintr, sc);
    404 	aprint_normal_dev(self,
    405 	    "Error Reporting IRQ %d\n", MVXPSEC_ERR_INT(sc));
    406 
    407 	/* Initialize TDMA (It's enabled here, but waiting for SA) */
    408 	if (mvxpsec_dma_wait(sc) < 0)
    409 		panic("%s: DMA DEVICE not responding\n", __func__);
    410 	MVXPSEC_WRITE(sc, MV_TDMA_CNT, 0);
    411 	MVXPSEC_WRITE(sc, MV_TDMA_SRC, 0);
    412 	MVXPSEC_WRITE(sc, MV_TDMA_DST, 0);
    413 	MVXPSEC_WRITE(sc, MV_TDMA_NXT, 0);
    414 	MVXPSEC_WRITE(sc, MV_TDMA_CUR, 0);
    415 	v  = MVXPSEC_READ(sc, MV_TDMA_CONTROL);
    416 	v |= MV_TDMA_CONTROL_ENABLE;
    417 	MVXPSEC_WRITE(sc, MV_TDMA_CONTROL, v);
    418 
    419 	/* Initialize SA */
    420 	if (mvxpsec_acc_wait(sc) < 0)
    421 		panic("%s: MVXPSEC not responding\n", __func__);
    422 	v  = MVXPSEC_READ(sc, MV_ACC_CONFIG);
    423 	v &= ~MV_ACC_CONFIG_STOP_ON_ERR;
    424 	v |= MV_ACC_CONFIG_MULT_PKT;
    425 	v |= MV_ACC_CONFIG_WAIT_TDMA;
    426 	v |= MV_ACC_CONFIG_ACT_TDMA;
    427 	MVXPSEC_WRITE(sc, MV_ACC_CONFIG, v);
    428 	MVXPSEC_WRITE(sc, MV_ACC_DESC, 0);
    429 	MVXPSEC_WRITE(sc, MV_ACC_COMMAND, MV_ACC_COMMAND_STOP);
    430 
    431 	/* Session */
    432 	sc->sc_session_pool =
    433 	    pool_cache_init(sizeof(struct mvxpsec_session), 0, 0, 0,
    434 	    "mvxpsecpl", NULL, IPL_NET,
    435 	    mvxpsec_session_ctor, mvxpsec_session_dtor, sc);
    436 	pool_cache_sethiwat(sc->sc_session_pool, MVXPSEC_MAX_SESSIONS);
    437 	pool_cache_setlowat(sc->sc_session_pool, MVXPSEC_MAX_SESSIONS / 2);
    438 	sc->sc_last_session = NULL;
    439 
    440 	/* Pakcet */
    441 	sc->sc_packet_pool =
    442 	    pool_cache_init(sizeof(struct mvxpsec_session), 0, 0, 0,
    443 	    "mvxpsec_pktpl", NULL, IPL_NET,
    444 	    mvxpsec_packet_ctor, mvxpsec_packet_dtor, sc);
    445 	pool_cache_sethiwat(sc->sc_packet_pool, MVXPSEC_MAX_SESSIONS);
    446 	pool_cache_setlowat(sc->sc_packet_pool, MVXPSEC_MAX_SESSIONS / 2);
    447 
    448 	/* Register to EVCNT framework */
    449 	mvxpsec_evcnt_attach(sc);
    450 
    451 	/* Register to Opencrypto */
    452 	for (i = 0; i < MVXPSEC_MAX_SESSIONS; i++) {
    453 		sc->sc_sessions[i] = NULL;
    454 	}
    455 	if (mvxpsec_register(sc))
    456 		panic("cannot initialize OpenCrypto module.\n");
    457 
    458 	return;
    459 }
    460 
    461 STATIC void
    462 mvxpsec_evcnt_attach(struct mvxpsec_softc *sc)
    463 {
    464 	struct mvxpsec_evcnt *sc_ev = &sc->sc_ev;
    465 
    466 	evcnt_attach_dynamic(&sc_ev->intr_all, EVCNT_TYPE_INTR,
    467 	    NULL, device_xname(sc->sc_dev), "Main Intr.");
    468 	evcnt_attach_dynamic(&sc_ev->intr_auth, EVCNT_TYPE_INTR,
    469 	    NULL, device_xname(sc->sc_dev), "Auth Intr.");
    470 	evcnt_attach_dynamic(&sc_ev->intr_des, EVCNT_TYPE_INTR,
    471 	    NULL, device_xname(sc->sc_dev), "DES Intr.");
    472 	evcnt_attach_dynamic(&sc_ev->intr_aes_enc, EVCNT_TYPE_INTR,
    473 	    NULL, device_xname(sc->sc_dev), "AES-Encrypt Intr.");
    474 	evcnt_attach_dynamic(&sc_ev->intr_aes_dec, EVCNT_TYPE_INTR,
    475 	    NULL, device_xname(sc->sc_dev), "AES-Decrypt Intr.");
    476 	evcnt_attach_dynamic(&sc_ev->intr_enc, EVCNT_TYPE_INTR,
    477 	    NULL, device_xname(sc->sc_dev), "Crypto Intr.");
    478 	evcnt_attach_dynamic(&sc_ev->intr_sa, EVCNT_TYPE_INTR,
    479 	    NULL, device_xname(sc->sc_dev), "SA Intr.");
    480 	evcnt_attach_dynamic(&sc_ev->intr_acctdma, EVCNT_TYPE_INTR,
    481 	    NULL, device_xname(sc->sc_dev), "AccTDMA Intr.");
    482 	evcnt_attach_dynamic(&sc_ev->intr_comp, EVCNT_TYPE_INTR,
    483 	    NULL, device_xname(sc->sc_dev), "TDMA-Complete Intr.");
    484 	evcnt_attach_dynamic(&sc_ev->intr_own, EVCNT_TYPE_INTR,
    485 	    NULL, device_xname(sc->sc_dev), "TDMA-Ownership Intr.");
    486 	evcnt_attach_dynamic(&sc_ev->intr_acctdma_cont, EVCNT_TYPE_INTR,
    487 	    NULL, device_xname(sc->sc_dev), "AccTDMA-Continue Intr.");
    488 
    489 	evcnt_attach_dynamic(&sc_ev->session_new, EVCNT_TYPE_MISC,
    490 	    NULL, device_xname(sc->sc_dev), "New-Session");
    491 	evcnt_attach_dynamic(&sc_ev->session_free, EVCNT_TYPE_MISC,
    492 	    NULL, device_xname(sc->sc_dev), "Free-Session");
    493 
    494 	evcnt_attach_dynamic(&sc_ev->packet_ok, EVCNT_TYPE_MISC,
    495 	    NULL, device_xname(sc->sc_dev), "Packet-OK");
    496 	evcnt_attach_dynamic(&sc_ev->packet_err, EVCNT_TYPE_MISC,
    497 	    NULL, device_xname(sc->sc_dev), "Packet-ERR");
    498 
    499 	evcnt_attach_dynamic(&sc_ev->dispatch_packets, EVCNT_TYPE_MISC,
    500 	    NULL, device_xname(sc->sc_dev), "Packet-Dispatch");
    501 	evcnt_attach_dynamic(&sc_ev->dispatch_queue, EVCNT_TYPE_MISC,
    502 	    NULL, device_xname(sc->sc_dev), "Queue-Dispatch");
    503 	evcnt_attach_dynamic(&sc_ev->queue_full, EVCNT_TYPE_MISC,
    504 	    NULL, device_xname(sc->sc_dev), "Queue-Full");
    505 	evcnt_attach_dynamic(&sc_ev->max_dispatch, EVCNT_TYPE_MISC,
    506 	    NULL, device_xname(sc->sc_dev), "Max-Dispatch");
    507 	evcnt_attach_dynamic(&sc_ev->max_done, EVCNT_TYPE_MISC,
    508 	    NULL, device_xname(sc->sc_dev), "Max-Done");
    509 }
    510 
    511 /*
    512  * Register setup
    513  */
    514 STATIC int mvxpsec_wininit(struct mvxpsec_softc *sc, enum marvell_tags *tags)
    515 {
    516 	device_t pdev = device_parent(sc->sc_dev);
    517 	uint64_t base;
    518 	uint32_t size, reg;
    519 	int window, target, attr, rv, i;
    520 
    521 	/* disable all window */
    522 	for (window = 0; window < MV_TDMA_NWINDOW; window++)
    523 	{
    524 		MVXPSEC_WRITE(sc, MV_TDMA_BAR(window), 0);
    525 		MVXPSEC_WRITE(sc, MV_TDMA_ATTR(window), 0);
    526 	}
    527 
    528 	for (window = 0, i = 0;
    529 	    tags[i] != MARVELL_TAG_UNDEFINED && window < MV_TDMA_NWINDOW; i++) {
    530 		rv = marvell_winparams_by_tag(pdev, tags[i],
    531 		    &target, &attr, &base, &size);
    532 		if (rv != 0 || size == 0)
    533 			continue;
    534 
    535 		if (base > 0xffffffffULL) {
    536 			aprint_error_dev(sc->sc_dev,
    537 			    "can't remap window %d\n", window);
    538 			continue;
    539 		}
    540 
    541 		reg  = MV_TDMA_BAR_BASE(base);
    542 		MVXPSEC_WRITE(sc, MV_TDMA_BAR(window), reg);
    543 
    544 		reg  = MV_TDMA_ATTR_TARGET(target);
    545 		reg |= MV_TDMA_ATTR_ATTR(attr);
    546 		reg |= MV_TDMA_ATTR_SIZE(size);
    547 		reg |= MV_TDMA_ATTR_ENABLE;
    548 		MVXPSEC_WRITE(sc, MV_TDMA_ATTR(window), reg);
    549 
    550 		window++;
    551 	}
    552 
    553 	return 0;
    554 }
    555 
    556 /*
    557  * Timer handling
    558  */
    559 STATIC void
    560 mvxpsec_timer(void *aux)
    561 {
    562 	struct mvxpsec_softc *sc = aux;
    563 	struct mvxpsec_packet *mv_p;
    564 	uint32_t reg;
    565 	int ndone;
    566 	int refill;
    567 	int s;
    568 
    569 	/* IPL_SOFTCLOCK */
    570 
    571 	log(LOG_ERR, "%s: device timeout.\n", __func__);
    572 #ifdef MVXPSEC_DEBUG
    573 	mvxpsec_dump_reg(sc);
    574 #endif
    575 
    576 	s = splnet();
    577 	/* stop security accelerator */
    578 	MVXPSEC_WRITE(sc, MV_ACC_COMMAND, MV_ACC_COMMAND_STOP);
    579 
    580 	/* stop TDMA */
    581 	MVXPSEC_WRITE(sc, MV_TDMA_CONTROL, 0);
    582 
    583 	/* cleanup packet queue */
    584 	mutex_enter(&sc->sc_queue_mtx);
    585 	ndone = 0;
    586 	while ( (mv_p = SIMPLEQ_FIRST(&sc->sc_run_queue)) != NULL) {
    587 		SIMPLEQ_REMOVE_HEAD(&sc->sc_run_queue, queue);
    588 
    589 		mv_p->crp->crp_etype = EINVAL;
    590 		mvxpsec_done_packet(mv_p);
    591 		ndone++;
    592 	}
    593 	MVXPSEC_EVCNT_MAX(sc, max_done, ndone);
    594 	sc->sc_flags &= ~HW_RUNNING;
    595 	refill = (sc->sc_wait_qlen > 0) ? 1 : 0;
    596 	mutex_exit(&sc->sc_queue_mtx);
    597 
    598 	/* reenable TDMA */
    599 	if (mvxpsec_dma_wait(sc) < 0)
    600 		panic("%s: failed to reset DMA DEVICE. give up.", __func__);
    601 	MVXPSEC_WRITE(sc, MV_TDMA_CNT, 0);
    602 	MVXPSEC_WRITE(sc, MV_TDMA_SRC, 0);
    603 	MVXPSEC_WRITE(sc, MV_TDMA_DST, 0);
    604 	MVXPSEC_WRITE(sc, MV_TDMA_CUR, 0);
    605 	MVXPSEC_WRITE(sc, MV_TDMA_NXT, 0);
    606 	reg  = MV_TDMA_DEFAULT_CONTROL;
    607 	reg |= MV_TDMA_CONTROL_ENABLE;
    608 	MVXPSEC_WRITE(sc, MV_TDMA_CONTROL, reg);
    609 
    610 	if (mvxpsec_acc_wait(sc) < 0)
    611 		panic("%s: failed to reset MVXPSEC. give up.", __func__);
    612 	reg  = MV_ACC_CONFIG_MULT_PKT;
    613 	reg |= MV_ACC_CONFIG_WAIT_TDMA;
    614 	reg |= MV_ACC_CONFIG_ACT_TDMA;
    615 	MVXPSEC_WRITE(sc, MV_ACC_CONFIG, reg);
    616 	MVXPSEC_WRITE(sc, MV_ACC_DESC, 0);
    617 
    618 	if (refill) {
    619 		mutex_enter(&sc->sc_queue_mtx);
    620 		mvxpsec_dispatch_queue(sc);
    621 		mutex_exit(&sc->sc_queue_mtx);
    622 	}
    623 
    624 	crypto_unblock(sc->sc_cid, CRYPTO_SYMQ|CRYPTO_ASYMQ);
    625 	splx(s);
    626 }
    627 
    628 /*
    629  * DMA handling
    630  */
    631 
    632 /*
    633  * Allocate kernel devmem and DMA safe memory with bus_dma API
    634  * used for DMA descriptors.
    635  *
    636  * if phys != 0, assume phys is a DMA safe memory and bypass
    637  * allocator.
    638  */
    639 STATIC struct mvxpsec_devmem *
    640 mvxpsec_alloc_devmem(struct mvxpsec_softc *sc, paddr_t phys, int size)
    641 {
    642 	struct mvxpsec_devmem *devmem;
    643 	bus_dma_segment_t seg;
    644 	int rseg;
    645 	int err;
    646 
    647 	if (sc == NULL)
    648 		return NULL;
    649 
    650 	devmem = kmem_alloc(sizeof(*devmem), KM_SLEEP);
    651 	devmem->size = size;
    652 
    653 	if (phys) {
    654 		seg.ds_addr = phys;
    655 		seg.ds_len = devmem->size;
    656 		rseg = 1;
    657 		err = 0;
    658 	}
    659 	else {
    660 		err = bus_dmamem_alloc(sc->sc_dmat,
    661 		    devmem->size, PAGE_SIZE, 0,
    662 		    &seg, MVXPSEC_DMA_MAX_SEGS, &rseg, BUS_DMA_NOWAIT);
    663 	}
    664 	if (err) {
    665 		aprint_error_dev(sc->sc_dev, "can't alloc DMA buffer\n");
    666 		goto fail_kmem_free;
    667 	}
    668 
    669 	err = bus_dmamem_map(sc->sc_dmat, &seg, rseg,
    670 	     devmem->size, &devmem->kva, BUS_DMA_NOWAIT);
    671 	if (err) {
    672 		aprint_error_dev(sc->sc_dev, "can't map DMA buffer\n");
    673 		goto fail_dmamem_free;
    674 	}
    675 
    676 	err = bus_dmamap_create(sc->sc_dmat,
    677 	    size, 1, size, 0, BUS_DMA_NOWAIT, &devmem->map);
    678 	if (err) {
    679 		aprint_error_dev(sc->sc_dev, "can't create DMA map\n");
    680 		goto fail_unmap;
    681 	}
    682 
    683 	err = bus_dmamap_load(sc->sc_dmat,
    684 	    devmem->map, devmem->kva, devmem->size, NULL,
    685 	    BUS_DMA_NOWAIT);
    686 	if (err) {
    687 		aprint_error_dev(sc->sc_dev,
    688 		   "can't load DMA buffer VA:%p PA:0x%08x\n",
    689 		    devmem->kva, (int)seg.ds_addr);
    690 		goto fail_destroy;
    691 	}
    692 
    693 	return devmem;
    694 
    695 fail_destroy:
    696 	bus_dmamap_destroy(sc->sc_dmat, devmem->map);
    697 fail_unmap:
    698 	bus_dmamem_unmap(sc->sc_dmat, devmem->kva, devmem->size);
    699 fail_dmamem_free:
    700 	bus_dmamem_free(sc->sc_dmat, &seg, rseg);
    701 fail_kmem_free:
    702 	kmem_free(devmem, sizeof(*devmem));
    703 
    704 	return NULL;
    705 }
    706 
    707 /*
    708  * Get DMA Descriptor from (DMA safe) descriptor pool.
    709  */
    710 INLINE struct mvxpsec_descriptor_handle *
    711 mvxpsec_dma_getdesc(struct mvxpsec_softc *sc)
    712 {
    713 	struct mvxpsec_descriptor_handle *entry;
    714 
    715 	/* must called with sc->sc_dma_mtx held */
    716 	KASSERT(mutex_owned(&sc->sc_dma_mtx));
    717 
    718 	if (sc->sc_desc_ring_prod == sc->sc_desc_ring_cons)
    719 		return NULL;
    720 
    721 	entry = &sc->sc_desc_ring[sc->sc_desc_ring_prod];
    722 	sc->sc_desc_ring_prod++;
    723 	if (sc->sc_desc_ring_prod >= sc->sc_desc_ring_size)
    724 		sc->sc_desc_ring_prod -= sc->sc_desc_ring_size;
    725 
    726 	return entry;
    727 }
    728 
    729 /*
    730  * Put DMA Descriptor to descriptor pool.
    731  */
    732 _INLINE void
    733 mvxpsec_dma_putdesc(struct mvxpsec_softc *sc,
    734     struct mvxpsec_descriptor_handle *dh)
    735 {
    736 	/* must called with sc->sc_dma_mtx held */
    737 	KASSERT(mutex_owned(&sc->sc_dma_mtx));
    738 
    739 	sc->sc_desc_ring_cons++;
    740 	if (sc->sc_desc_ring_cons >= sc->sc_desc_ring_size)
    741 		sc->sc_desc_ring_cons -= sc->sc_desc_ring_size;
    742 
    743 	return;
    744 }
    745 
    746 /*
    747  * Setup DMA Descriptor
    748  * copy from 'src' to 'dst' by 'size' bytes.
    749  * 'src' or 'dst' must be SRAM address.
    750  */
    751 INLINE void
    752 mvxpsec_dma_setup(struct mvxpsec_descriptor_handle *dh,
    753     uint32_t dst, uint32_t src, uint32_t size)
    754 {
    755 	struct mvxpsec_descriptor *desc;
    756 
    757 	desc = (struct mvxpsec_descriptor *)dh->_desc;
    758 
    759 	desc->tdma_dst = dst;
    760 	desc->tdma_src = src;
    761 	desc->tdma_word0 = size;
    762 	if (size != 0)
    763 		desc->tdma_word0 |= MV_TDMA_CNT_OWN;
    764 	/* size == 0 is owned by ACC, not TDMA */
    765 
    766 #ifdef MVXPSEC_DEBUG
    767 	mvxpsec_dump_dmaq(dh);
    768 #endif
    769 
    770 }
    771 
    772 /*
    773  * Concat 2 DMA
    774  */
    775 INLINE void
    776 mvxpsec_dma_cat(struct mvxpsec_softc *sc,
    777     struct mvxpsec_descriptor_handle *dh1,
    778     struct mvxpsec_descriptor_handle *dh2)
    779 {
    780 	((struct mvxpsec_descriptor*)dh1->_desc)->tdma_nxt = dh2->phys_addr;
    781 	MVXPSEC_SYNC_DESC(sc, dh1, BUS_DMASYNC_PREWRITE);
    782 }
    783 
    784 /*
    785  * Schedule DMA Copy
    786  */
    787 INLINE int
    788 mvxpsec_dma_copy0(struct mvxpsec_softc *sc, mvxpsec_dma_ring *r,
    789     uint32_t dst, uint32_t src, uint32_t size)
    790 {
    791 	struct mvxpsec_descriptor_handle *dh;
    792 
    793 	dh = mvxpsec_dma_getdesc(sc);
    794 	if (dh == NULL) {
    795 		log(LOG_ERR, "%s: descriptor full\n", __func__);
    796 		return -1;
    797 	}
    798 
    799 	mvxpsec_dma_setup(dh, dst, src, size);
    800 	if (r->dma_head == NULL) {
    801 		r->dma_head = dh;
    802 		r->dma_last = dh;
    803 		r->dma_size = 1;
    804 	}
    805 	else {
    806 		mvxpsec_dma_cat(sc, r->dma_last, dh);
    807 		r->dma_last = dh;
    808 		r->dma_size++;
    809 	}
    810 
    811 	return 0;
    812 }
    813 
    814 INLINE int
    815 mvxpsec_dma_copy(struct mvxpsec_softc *sc, mvxpsec_dma_ring *r,
    816     uint32_t dst, uint32_t src, uint32_t size)
    817 {
    818 	if (size == 0) /* 0 is very special descriptor */
    819 		return 0;
    820 
    821 	return mvxpsec_dma_copy0(sc, r, dst, src, size);
    822 }
    823 
    824 /*
    825  * Schedule ACC Activate
    826  */
    827 INLINE int
    828 mvxpsec_dma_acc_activate(struct mvxpsec_softc *sc, mvxpsec_dma_ring *r)
    829 {
    830 	return mvxpsec_dma_copy0(sc, r, 0, 0, 0);
    831 }
    832 
    833 /*
    834  * Finalize DMA setup
    835  */
    836 INLINE void
    837 mvxpsec_dma_finalize(struct mvxpsec_softc *sc, mvxpsec_dma_ring *r)
    838 {
    839 	struct mvxpsec_descriptor_handle *dh;
    840 
    841 	dh = r->dma_last;
    842 	((struct mvxpsec_descriptor*)dh->_desc)->tdma_nxt = 0;
    843 	MVXPSEC_SYNC_DESC(sc, dh, BUS_DMASYNC_PREWRITE);
    844 }
    845 
    846 /*
    847  * Free entire DMA ring
    848  */
    849 INLINE void
    850 mvxpsec_dma_free(struct mvxpsec_softc *sc, mvxpsec_dma_ring *r)
    851 {
    852 	sc->sc_desc_ring_cons += r->dma_size;
    853 	if (sc->sc_desc_ring_cons >= sc->sc_desc_ring_size)
    854 		sc->sc_desc_ring_cons -= sc->sc_desc_ring_size;
    855 	r->dma_head = NULL;
    856 	r->dma_last = NULL;
    857 	r->dma_size = 0;
    858 }
    859 
    860 /*
    861  * create DMA descriptor chain for the packet
    862  */
    863 INLINE int
    864 mvxpsec_dma_copy_packet(struct mvxpsec_softc *sc, struct mvxpsec_packet *mv_p)
    865 {
    866 	struct mvxpsec_session *mv_s = mv_p->mv_s;
    867 	uint32_t src, dst, len;
    868 	uint32_t pkt_off, pkt_off_r;
    869 	int err;
    870 	int i;
    871 
    872 	/* must called with sc->sc_dma_mtx held */
    873 	KASSERT(mutex_owned(&sc->sc_dma_mtx));
    874 
    875 	/*
    876 	 * set offset for mem->device copy
    877 	 *
    878 	 * typical packet image:
    879 	 *
    880 	 *   enc_ivoff
    881 	 *   mac_off
    882 	 *   |
    883 	 *   |    enc_off
    884 	 *   |    |
    885 	 *   v    v
    886 	 *   +----+--------...
    887 	 *   |IV  |DATA
    888 	 *   +----+--------...
    889 	 */
    890 	pkt_off = 0;
    891 	if (mv_p->mac_off > 0)
    892 		pkt_off = mv_p->mac_off;
    893 	if ((mv_p->flags & CRP_EXT_IV) == 0 && pkt_off > mv_p->enc_ivoff)
    894 		pkt_off = mv_p->enc_ivoff;
    895 	if (mv_p->enc_off > 0 && pkt_off > mv_p->enc_off)
    896 		pkt_off = mv_p->enc_off;
    897 	pkt_off_r = pkt_off;
    898 
    899 	/* make DMA descriptors to copy packet header: DRAM -> SRAM */
    900 	dst = (uint32_t)MVXPSEC_SRAM_PKT_HDR_PA(sc);
    901 	src = (uint32_t)mv_p->pkt_header_map->dm_segs[0].ds_addr;
    902 	len = sizeof(mv_p->pkt_header);
    903 	err = mvxpsec_dma_copy(sc, &mv_p->dma_ring, dst, src, len);
    904 	if (__predict_false(err))
    905 		return err;
    906 
    907 	/*
    908 	 * make DMA descriptors to copy session header: DRAM -> SRAM
    909 	 * we can reuse session header on SRAM if session is not changed.
    910 	 */
    911 	if (sc->sc_last_session != mv_s) {
    912 		dst = (uint32_t)MVXPSEC_SRAM_SESS_HDR_PA(sc);
    913 		src = (uint32_t)mv_s->session_header_map->dm_segs[0].ds_addr;
    914 		len = sizeof(mv_s->session_header);
    915 		err = mvxpsec_dma_copy(sc, &mv_p->dma_ring, dst, src, len);
    916 		if (__predict_false(err))
    917 			return err;
    918 		sc->sc_last_session = mv_s;
    919 	}
    920 
    921 	/* make DMA descriptor to copy payload data: DRAM -> SRAM */
    922 	dst = MVXPSEC_SRAM_PAYLOAD_PA(sc, 0);
    923 	for (i = 0; i < mv_p->data_map->dm_nsegs; i++) {
    924 		src = mv_p->data_map->dm_segs[i].ds_addr;
    925 		len = mv_p->data_map->dm_segs[i].ds_len;
    926 		if (pkt_off) {
    927 			if (len <= pkt_off) {
    928 				/* ignore the segment */
    929 				dst += len;
    930 				pkt_off -= len;
    931 				continue;
    932 			}
    933 			/* copy from the middle of the segment */
    934 			dst += pkt_off;
    935 			src += pkt_off;
    936 			len -= pkt_off;
    937 			pkt_off = 0;
    938 		}
    939 		err = mvxpsec_dma_copy(sc, &mv_p->dma_ring, dst, src, len);
    940 		if (__predict_false(err))
    941 			return err;
    942 		dst += len;
    943 	}
    944 
    945 	/* make special descriptor to activate security accelerator */
    946 	err = mvxpsec_dma_acc_activate(sc, &mv_p->dma_ring);
    947 	if (__predict_false(err))
    948 		return err;
    949 
    950 	/* make DMA descriptors to copy payload: SRAM -> DRAM */
    951 	src = (uint32_t)MVXPSEC_SRAM_PAYLOAD_PA(sc, 0);
    952 	for (i = 0; i < mv_p->data_map->dm_nsegs; i++) {
    953 		dst = (uint32_t)mv_p->data_map->dm_segs[i].ds_addr;
    954 		len = (uint32_t)mv_p->data_map->dm_segs[i].ds_len;
    955 		if (pkt_off_r) {
    956 			if (len <= pkt_off_r) {
    957 				/* ignore the segment */
    958 				src += len;
    959 				pkt_off_r -= len;
    960 				continue;
    961 			}
    962 			/* copy from the middle of the segment */
    963 			src += pkt_off_r;
    964 			dst += pkt_off_r;
    965 			len -= pkt_off_r;
    966 			pkt_off_r = 0;
    967 		}
    968 		err = mvxpsec_dma_copy(sc, &mv_p->dma_ring, dst, src, len);
    969 		if (__predict_false(err))
    970 			return err;
    971 		src += len;
    972 	}
    973 	KASSERT(pkt_off == 0);
    974 	KASSERT(pkt_off_r == 0);
    975 
    976 	/*
    977 	 * make DMA descriptors to copy packet header: SRAM->DRAM
    978 	 * if IV is present in the payload, no need to copy.
    979 	 */
    980 	if (mv_p->flags & CRP_EXT_IV) {
    981 		dst = (uint32_t)mv_p->pkt_header_map->dm_segs[0].ds_addr;
    982 		src = (uint32_t)MVXPSEC_SRAM_PKT_HDR_PA(sc);
    983 		len = sizeof(mv_p->pkt_header);
    984 		err = mvxpsec_dma_copy(sc, &mv_p->dma_ring, dst, src, len);
    985 		if (__predict_false(err))
    986 			return err;
    987 	}
    988 
    989 	return 0;
    990 }
    991 
    992 INLINE int
    993 mvxpsec_dma_sync_packet(struct mvxpsec_softc *sc, struct mvxpsec_packet *mv_p)
    994 {
    995 	/* sync packet header */
    996 	bus_dmamap_sync(sc->sc_dmat,
    997 	    mv_p->pkt_header_map, 0, sizeof(mv_p->pkt_header),
    998 	    BUS_DMASYNC_PREWRITE);
    999 
   1000 #ifdef MVXPSEC_DEBUG
   1001 	/* sync session header */
   1002 	if (mvxpsec_debug != 0) {
   1003 		struct mvxpsec_session *mv_s = mv_p->mv_s;
   1004 
   1005 		/* only debug code touch the session header after newsession */
   1006 		bus_dmamap_sync(sc->sc_dmat,
   1007 		    mv_s->session_header_map,
   1008 		    0, sizeof(mv_s->session_header),
   1009 		    BUS_DMASYNC_PREWRITE);
   1010 	}
   1011 #endif
   1012 
   1013 	/* sync packet buffer */
   1014 	bus_dmamap_sync(sc->sc_dmat,
   1015 	    mv_p->data_map, 0, mv_p->data_len,
   1016 	    BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
   1017 
   1018 	return 0;
   1019 }
   1020 
   1021 /*
   1022  * Initialize MVXPSEC Internal SRAM
   1023  *
   1024  * - must be called after DMA initizlization.
   1025  * - make VM mapping for SRAM area on MBus.
   1026  */
   1027 STATIC int
   1028 mvxpsec_init_sram(struct mvxpsec_softc *sc)
   1029 {
   1030 	uint32_t tag, target, attr, base, size;
   1031 	vaddr_t va;
   1032 	int window;
   1033 
   1034 	switch (sc->sc_dev->dv_unit) {
   1035 	case 0:
   1036 		tag = ARMADAXP_TAG_CRYPT0;
   1037 		break;
   1038 	case 1:
   1039 		tag = ARMADAXP_TAG_CRYPT1;
   1040 		break;
   1041 	default:
   1042 		aprint_error_dev(sc->sc_dev, "no internal SRAM mapping\n");
   1043 		return -1;
   1044 	}
   1045 
   1046 	window = mvsoc_target(tag, &target, &attr, &base, &size);
   1047 	if (window >= nwindow) {
   1048 		aprint_error_dev(sc->sc_dev, "no internal SRAM mapping\n");
   1049 		return -1;
   1050 	}
   1051 
   1052 	if (sizeof(struct mvxpsec_crypt_sram) > size) {
   1053 		aprint_error_dev(sc->sc_dev,
   1054 		    "SRAM Data Structure Excceeds SRAM window size.\n");
   1055 		return -1;
   1056 	}
   1057 
   1058 	aprint_normal_dev(sc->sc_dev,
   1059 	    "internal SRAM window at 0x%08x-0x%08x",
   1060 	    base, base + size - 1);
   1061 	sc->sc_sram_pa = base;
   1062 
   1063 	/* get vmspace to read/write device internal SRAM */
   1064 	va = uvm_km_alloc(kernel_map, PAGE_SIZE, PAGE_SIZE,
   1065 			UVM_KMF_VAONLY | UVM_KMF_NOWAIT);
   1066 	if (va == 0) {
   1067 		aprint_error_dev(sc->sc_dev, "cannot map SRAM window\n");
   1068 		sc->sc_sram_va = NULL;
   1069 		aprint_normal("\n");
   1070 		return 0;
   1071 	}
   1072 	/* XXX: not working. PMAP_NOCACHE is not affected? */
   1073 	pmap_kenter_pa(va, base, VM_PROT_READ|VM_PROT_WRITE, PMAP_NOCACHE);
   1074 	pmap_update(pmap_kernel());
   1075 	sc->sc_sram_va = (void *)va;
   1076 	aprint_normal(" va %p\n", sc->sc_sram_va);
   1077 	memset(sc->sc_sram_va, 0xff, MV_ACC_SRAM_SIZE);
   1078 
   1079 	return 0;
   1080 }
   1081 
   1082 /*
   1083  * Initialize TDMA engine.
   1084  */
   1085 STATIC int
   1086 mvxpsec_init_dma(struct mvxpsec_softc *sc, struct marvell_attach_args *mva)
   1087 {
   1088 	struct mvxpsec_descriptor_handle *dh;
   1089 	uint8_t *va;
   1090 	paddr_t pa;
   1091 	off_t va_off, pa_off;
   1092 	int i, n, seg, ndh;
   1093 
   1094 	/* Init Deviced's control parameters (disabled yet) */
   1095 	MVXPSEC_WRITE(sc, MV_TDMA_CONTROL, MV_TDMA_DEFAULT_CONTROL);
   1096 
   1097 	/* Init Software DMA Handlers */
   1098 	sc->sc_devmem_desc =
   1099 	    mvxpsec_alloc_devmem(sc, 0, PAGE_SIZE * MVXPSEC_DMA_DESC_PAGES);
   1100 	ndh = (PAGE_SIZE / sizeof(struct mvxpsec_descriptor))
   1101 	    * MVXPSEC_DMA_DESC_PAGES;
   1102 	sc->sc_desc_ring =
   1103 	    kmem_alloc(sizeof(struct mvxpsec_descriptor_handle) * ndh,
   1104 	        KM_SLEEP);
   1105 	aprint_normal_dev(sc->sc_dev, "%d DMA handles in %zu bytes array\n",
   1106 	    ndh, sizeof(struct mvxpsec_descriptor_handle) * ndh);
   1107 
   1108 	ndh = 0;
   1109 	for (seg = 0; seg < devmem_nseg(sc->sc_devmem_desc); seg++) {
   1110 		va = devmem_va(sc->sc_devmem_desc);
   1111 		pa = devmem_pa(sc->sc_devmem_desc, seg);
   1112 		n = devmem_palen(sc->sc_devmem_desc, seg) /
   1113 		       	sizeof(struct mvxpsec_descriptor);
   1114 		va_off = (PAGE_SIZE * seg);
   1115 		pa_off = 0;
   1116 		for (i = 0; i < n; i++) {
   1117 			dh = &sc->sc_desc_ring[ndh];
   1118 			dh->map = devmem_map(sc->sc_devmem_desc);
   1119 			dh->off = va_off + pa_off;
   1120 			dh->_desc = (void *)(va + va_off + pa_off);
   1121 			dh->phys_addr = pa + pa_off;
   1122 			pa_off += sizeof(struct mvxpsec_descriptor);
   1123 			ndh++;
   1124 		}
   1125 	}
   1126 	sc->sc_desc_ring_size = ndh;
   1127 	sc->sc_desc_ring_prod = 0;
   1128 	sc->sc_desc_ring_cons = sc->sc_desc_ring_size - 1;
   1129 
   1130 	return 0;
   1131 }
   1132 
   1133 /*
   1134  * Wait for TDMA controller become idle
   1135  */
   1136 INLINE int
   1137 mvxpsec_dma_wait(struct mvxpsec_softc *sc)
   1138 {
   1139 	int retry = 0;
   1140 
   1141 	while (MVXPSEC_READ(sc, MV_TDMA_CONTROL) & MV_TDMA_CONTROL_ACT) {
   1142 		delay(mvxpsec_wait_interval);
   1143 		if (retry++ >= mvxpsec_wait_retry)
   1144 			return -1;
   1145 	}
   1146 	return 0;
   1147 }
   1148 
   1149 /*
   1150  * Wait for Security Accelerator become idle
   1151  */
   1152 INLINE int
   1153 mvxpsec_acc_wait(struct mvxpsec_softc *sc)
   1154 {
   1155 	int retry = 0;
   1156 
   1157 	while (MVXPSEC_READ(sc, MV_ACC_COMMAND) & MV_ACC_COMMAND_ACT) {
   1158 		delay(mvxpsec_wait_interval);
   1159 		if (++retry >= mvxpsec_wait_retry)
   1160 			return -1;
   1161 	}
   1162 	return 0;
   1163 }
   1164 
   1165 /*
   1166  * Entry of interrupt handler
   1167  *
   1168  * register this to kernel via marvell_intr_establish()
   1169  */
   1170 int
   1171 mvxpsec_intr(void *arg)
   1172 {
   1173 	struct mvxpsec_softc *sc = arg;
   1174 	uint32_t v;
   1175 
   1176 	/* IPL_NET */
   1177 	while ((v = mvxpsec_intr_ack(sc)) != 0) {
   1178 		mvxpsec_intr_cnt(sc, v);
   1179 		MVXPSEC_PRINTF(MVXPSEC_DEBUG_INTR, "MVXPSEC Intr 0x%08x\n", v);
   1180 		MVXPSEC_PRINTF(MVXPSEC_DEBUG_INTR, "%s\n", s_xpsecintr(v));
   1181 #ifdef MVXPSEC_DEBUG
   1182 		mvxpsec_dump_reg(sc);
   1183 #endif
   1184 
   1185 		/* call high-level handlers */
   1186 		if (v & MVXPSEC_INT_ACCTDMA)
   1187 			mvxpsec_done(sc);
   1188 	}
   1189 
   1190 	return 0;
   1191 }
   1192 
   1193 INLINE void
   1194 mvxpsec_intr_cleanup(struct mvxpsec_softc *sc)
   1195 {
   1196 	struct mvxpsec_packet *mv_p;
   1197 
   1198 	/* must called with sc->sc_dma_mtx held */
   1199 	KASSERT(mutex_owned(&sc->sc_dma_mtx));
   1200 
   1201 	/*
   1202 	 * there is only one intr for run_queue.
   1203 	 * no one touch sc_run_queue.
   1204 	 */
   1205 	SIMPLEQ_FOREACH(mv_p, &sc->sc_run_queue, queue)
   1206 		mvxpsec_dma_free(sc, &mv_p->dma_ring);
   1207 }
   1208 
   1209 /*
   1210  * Acknowledge to interrupt
   1211  *
   1212  * read cause bits, clear it, and return it.
   1213  * NOTE: multiple cause bits may be returned at once.
   1214  */
   1215 STATIC uint32_t
   1216 mvxpsec_intr_ack(struct mvxpsec_softc *sc)
   1217 {
   1218 	uint32_t reg;
   1219 
   1220 	reg  = MVXPSEC_READ(sc, MVXPSEC_INT_CAUSE);
   1221 	reg &= MVXPSEC_DEFAULT_INT;
   1222 	MVXPSEC_WRITE(sc, MVXPSEC_INT_CAUSE, ~reg);
   1223 	MVXPSEC_PRINTF(MVXPSEC_DEBUG_INTR, "Int: %s\n", s_xpsecintr(reg));
   1224 
   1225 	return reg;
   1226 }
   1227 
   1228 /*
   1229  * Entry of TDMA error interrupt handler
   1230  *
   1231  * register this to kernel via marvell_intr_establish()
   1232  */
   1233 int
   1234 mvxpsec_eintr(void *arg)
   1235 {
   1236 	struct mvxpsec_softc *sc = arg;
   1237 	uint32_t err;
   1238 
   1239 	/* IPL_NET */
   1240 again:
   1241 	err = mvxpsec_eintr_ack(sc);
   1242 	if (err == 0)
   1243 		goto done;
   1244 
   1245 	log(LOG_ERR, "%s: DMA Error Interrupt: %s\n", __func__,
   1246 	    s_errreg(err));
   1247 #ifdef MVXPSEC_DEBUG
   1248 	mvxpsec_dump_reg(sc);
   1249 #endif
   1250 
   1251 	goto again;
   1252 done:
   1253 	return 0;
   1254 }
   1255 
   1256 /*
   1257  * Acknowledge to TDMA error interrupt
   1258  *
   1259  * read cause bits, clear it, and return it.
   1260  * NOTE: multiple cause bits may be returned at once.
   1261  */
   1262 STATIC uint32_t
   1263 mvxpsec_eintr_ack(struct mvxpsec_softc *sc)
   1264 {
   1265 	uint32_t reg;
   1266 
   1267 	reg  = MVXPSEC_READ(sc, MV_TDMA_ERR_CAUSE);
   1268 	reg &= MVXPSEC_DEFAULT_ERR;
   1269 	MVXPSEC_WRITE(sc, MV_TDMA_ERR_CAUSE, ~reg);
   1270 	MVXPSEC_PRINTF(MVXPSEC_DEBUG_INTR, "Int: %s\n", s_xpsecintr(reg));
   1271 
   1272 	return reg;
   1273 }
   1274 
   1275 /*
   1276  * Interrupt statistics
   1277  *
   1278  * this is NOT a statistics of how may times the events 'occured'.
   1279  * this ONLY means how many times the events 'handled'.
   1280  */
   1281 INLINE void
   1282 mvxpsec_intr_cnt(struct mvxpsec_softc *sc, int cause)
   1283 {
   1284 	MVXPSEC_EVCNT_INCR(sc, intr_all);
   1285 	if (cause & MVXPSEC_INT_AUTH)
   1286 		MVXPSEC_EVCNT_INCR(sc, intr_auth);
   1287 	if (cause & MVXPSEC_INT_DES)
   1288 		MVXPSEC_EVCNT_INCR(sc, intr_des);
   1289 	if (cause & MVXPSEC_INT_AES_ENC)
   1290 		MVXPSEC_EVCNT_INCR(sc, intr_aes_enc);
   1291 	if (cause & MVXPSEC_INT_AES_DEC)
   1292 		MVXPSEC_EVCNT_INCR(sc, intr_aes_dec);
   1293 	if (cause & MVXPSEC_INT_ENC)
   1294 		MVXPSEC_EVCNT_INCR(sc, intr_enc);
   1295 	if (cause & MVXPSEC_INT_SA)
   1296 		MVXPSEC_EVCNT_INCR(sc, intr_sa);
   1297 	if (cause & MVXPSEC_INT_ACCTDMA)
   1298 		MVXPSEC_EVCNT_INCR(sc, intr_acctdma);
   1299 	if (cause & MVXPSEC_INT_TDMA_COMP)
   1300 		MVXPSEC_EVCNT_INCR(sc, intr_comp);
   1301 	if (cause & MVXPSEC_INT_TDMA_OWN)
   1302 		MVXPSEC_EVCNT_INCR(sc, intr_own);
   1303 	if (cause & MVXPSEC_INT_ACCTDMA_CONT)
   1304 		MVXPSEC_EVCNT_INCR(sc, intr_acctdma_cont);
   1305 }
   1306 
   1307 /*
   1308  * Setup MVXPSEC header structure.
   1309  *
   1310  * the header contains descriptor of security accelerator,
   1311  * key material of chiphers, iv of ciphers and macs, ...
   1312  *
   1313  * the header is transfered to MVXPSEC Internal SRAM by TDMA,
   1314  * and parsed by MVXPSEC H/W.
   1315  */
   1316 STATIC int
   1317 mvxpsec_header_finalize(struct mvxpsec_packet *mv_p)
   1318 {
   1319 	struct mvxpsec_acc_descriptor *desc = &mv_p->pkt_header.desc;
   1320 	int enc_start, enc_len, iv_offset;
   1321 	int mac_start, mac_len, mac_offset;
   1322 
   1323 	/* offset -> device address */
   1324 	enc_start = MVXPSEC_SRAM_PAYLOAD_DA(mv_p->enc_off);
   1325 	enc_len = mv_p->enc_len;
   1326 	if (mv_p->flags & CRP_EXT_IV)
   1327 		iv_offset = mv_p->enc_ivoff;
   1328 	else
   1329 		iv_offset = MVXPSEC_SRAM_PAYLOAD_DA(mv_p->enc_ivoff);
   1330 	mac_start = MVXPSEC_SRAM_PAYLOAD_DA(mv_p->mac_off);
   1331 	mac_len = mv_p->mac_len;
   1332 	mac_offset = MVXPSEC_SRAM_PAYLOAD_DA(mv_p->mac_dst);
   1333 
   1334 	MVXPSEC_PRINTF(MVXPSEC_DEBUG_OPENCRYPTO,
   1335 	    "PAYLOAD at 0x%08x\n", (int)MVXPSEC_SRAM_PAYLOAD_OFF);
   1336 	MVXPSEC_PRINTF(MVXPSEC_DEBUG_OPENCRYPTO,
   1337 	    "ENC from 0x%08x\n", enc_start);
   1338 	MVXPSEC_PRINTF(MVXPSEC_DEBUG_OPENCRYPTO,
   1339 	    "MAC from 0x%08x\n", mac_start);
   1340 	MVXPSEC_PRINTF(MVXPSEC_DEBUG_OPENCRYPTO,
   1341 	    "MAC to 0x%08x\n", mac_offset);
   1342 	MVXPSEC_PRINTF(MVXPSEC_DEBUG_OPENCRYPTO,
   1343 	    "ENC IV at 0x%08x\n", iv_offset);
   1344 
   1345 	/* setup device addresses in Security Accelerator Descriptors */
   1346 	desc->acc_encdata = MV_ACC_DESC_ENC_DATA(enc_start, enc_start);
   1347 	desc->acc_enclen = MV_ACC_DESC_ENC_LEN(enc_len);
   1348 	if (desc->acc_config & MV_ACC_CRYPTO_DECRYPT)
   1349 		desc->acc_enckey =
   1350 		    MV_ACC_DESC_ENC_KEY(MVXPSEC_SRAM_KEY_D_DA);
   1351 	else
   1352 		desc->acc_enckey =
   1353 		    MV_ACC_DESC_ENC_KEY(MVXPSEC_SRAM_KEY_DA);
   1354 	desc->acc_enciv =
   1355 	    MV_ACC_DESC_ENC_IV(MVXPSEC_SRAM_IV_WORK_DA, iv_offset);
   1356 
   1357 	desc->acc_macsrc = MV_ACC_DESC_MAC_SRC(mac_start, mac_len);
   1358 	desc->acc_macdst = MV_ACC_DESC_MAC_DST(mac_offset, mac_len);
   1359 	desc->acc_maciv =
   1360 	    MV_ACC_DESC_MAC_IV(MVXPSEC_SRAM_MIV_IN_DA,
   1361 	        MVXPSEC_SRAM_MIV_OUT_DA);
   1362 
   1363 	return 0;
   1364 }
   1365 
   1366 /*
   1367  * constractor of session structure.
   1368  *
   1369  * this constrator will be called by pool_cache framework.
   1370  */
   1371 STATIC int
   1372 mvxpsec_session_ctor(void *arg, void *obj, int flags)
   1373 {
   1374 	struct mvxpsec_softc *sc = arg;
   1375 	struct mvxpsec_session *mv_s = obj;
   1376 
   1377 	/* pool is owned by softc */
   1378 	mv_s->sc = sc;
   1379 
   1380 	/* Create and load DMA map for session header */
   1381 	mv_s->session_header_map = 0;
   1382 	if (bus_dmamap_create(sc->sc_dmat,
   1383 	    sizeof(mv_s->session_header), 1,
   1384 	    sizeof(mv_s->session_header), 0,
   1385 	    BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW,
   1386 	    &mv_s->session_header_map)) {
   1387 		log(LOG_ERR, "%s: cannot create DMA map\n", __func__);
   1388 		goto fail;
   1389 	}
   1390 	if (bus_dmamap_load(sc->sc_dmat, mv_s->session_header_map,
   1391 	    &mv_s->session_header, sizeof(mv_s->session_header),
   1392 	    NULL, BUS_DMA_NOWAIT)) {
   1393 		log(LOG_ERR, "%s: cannot load header\n", __func__);
   1394 		goto fail;
   1395 	}
   1396 
   1397 	return 0;
   1398 fail:
   1399 	if (mv_s->session_header_map)
   1400 		bus_dmamap_destroy(sc->sc_dmat, mv_s->session_header_map);
   1401 	return ENOMEM;
   1402 }
   1403 
   1404 /*
   1405  * destractor of session structure.
   1406  *
   1407  * this destrator will be called by pool_cache framework.
   1408  */
   1409 STATIC void
   1410 mvxpsec_session_dtor(void *arg, void *obj)
   1411 {
   1412 	struct mvxpsec_softc *sc = arg;
   1413 	struct mvxpsec_session *mv_s = obj;
   1414 
   1415 	if (mv_s->sc != sc)
   1416 		panic("inconsitent context\n");
   1417 
   1418 	bus_dmamap_destroy(sc->sc_dmat, mv_s->session_header_map);
   1419 }
   1420 
   1421 /*
   1422  * constructor of packet structure.
   1423  */
   1424 STATIC int
   1425 mvxpsec_packet_ctor(void *arg, void *obj, int flags)
   1426 {
   1427 	struct mvxpsec_softc *sc = arg;
   1428 	struct mvxpsec_packet *mv_p = obj;
   1429 
   1430 	mv_p->dma_ring.dma_head = NULL;
   1431 	mv_p->dma_ring.dma_last = NULL;
   1432 	mv_p->dma_ring.dma_size = 0;
   1433 
   1434 	/* Create and load DMA map for packet header */
   1435 	mv_p->pkt_header_map = 0;
   1436 	if (bus_dmamap_create(sc->sc_dmat,
   1437 	    sizeof(mv_p->pkt_header), 1, sizeof(mv_p->pkt_header), 0,
   1438 	    BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW,
   1439 	    &mv_p->pkt_header_map)) {
   1440 		log(LOG_ERR, "%s: cannot create DMA map\n", __func__);
   1441 		goto fail;
   1442 	}
   1443 	if (bus_dmamap_load(sc->sc_dmat, mv_p->pkt_header_map,
   1444 	    &mv_p->pkt_header, sizeof(mv_p->pkt_header),
   1445 	    NULL, BUS_DMA_NOWAIT)) {
   1446 		log(LOG_ERR, "%s: cannot load header\n", __func__);
   1447 		goto fail;
   1448 	}
   1449 
   1450 	/* Create DMA map for session data. */
   1451 	mv_p->data_map = 0;
   1452 	if (bus_dmamap_create(sc->sc_dmat,
   1453 	    MVXPSEC_DMA_MAX_SIZE, MVXPSEC_DMA_MAX_SEGS, MVXPSEC_DMA_MAX_SIZE,
   1454 	    0, BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, &mv_p->data_map)) {
   1455 		log(LOG_ERR, "%s: cannot create DMA map\n", __func__);
   1456 		goto fail;
   1457 	}
   1458 
   1459 	return 0;
   1460 fail:
   1461 	if (mv_p->pkt_header_map)
   1462 		bus_dmamap_destroy(sc->sc_dmat, mv_p->pkt_header_map);
   1463 	if (mv_p->data_map)
   1464 		bus_dmamap_destroy(sc->sc_dmat, mv_p->data_map);
   1465 	return ENOMEM;
   1466 }
   1467 
   1468 /*
   1469  * destractor of packet structure.
   1470  */
   1471 STATIC void
   1472 mvxpsec_packet_dtor(void *arg, void *obj)
   1473 {
   1474 	struct mvxpsec_softc *sc = arg;
   1475 	struct mvxpsec_packet *mv_p = obj;
   1476 
   1477 	mutex_enter(&sc->sc_dma_mtx);
   1478 	mvxpsec_dma_free(sc, &mv_p->dma_ring);
   1479 	mutex_exit(&sc->sc_dma_mtx);
   1480 	bus_dmamap_destroy(sc->sc_dmat, mv_p->pkt_header_map);
   1481 	bus_dmamap_destroy(sc->sc_dmat, mv_p->data_map);
   1482 }
   1483 
   1484 /*
   1485  * allocate new session struture.
   1486  */
   1487 STATIC struct mvxpsec_session *
   1488 mvxpsec_session_alloc(struct mvxpsec_softc *sc)
   1489 {
   1490 	struct mvxpsec_session *mv_s;
   1491 
   1492 	mv_s = pool_cache_get(sc->sc_session_pool, PR_NOWAIT);
   1493 	if (mv_s == NULL) {
   1494 		log(LOG_ERR, "%s: cannot allocate memory\n", __func__);
   1495 		return NULL;
   1496 	}
   1497 	mv_s->refs = 1; /* 0 means session is alredy invalid */
   1498 	mv_s->sflags = 0;
   1499 
   1500 	return mv_s;
   1501 }
   1502 
   1503 /*
   1504  * deallocate session structure.
   1505  */
   1506 STATIC void
   1507 mvxpsec_session_dealloc(struct mvxpsec_session *mv_s)
   1508 {
   1509 	struct mvxpsec_softc *sc = mv_s->sc;
   1510 
   1511 	mv_s->sflags |= DELETED;
   1512 	mvxpsec_session_unref(mv_s);
   1513 	crypto_unblock(sc->sc_cid, CRYPTO_SYMQ|CRYPTO_ASYMQ);
   1514 
   1515 	return;
   1516 }
   1517 
   1518 STATIC int
   1519 mvxpsec_session_ref(struct mvxpsec_session *mv_s)
   1520 {
   1521 	uint32_t refs;
   1522 
   1523 	if (mv_s->sflags & DELETED) {
   1524 		log(LOG_ERR,
   1525 		    "%s: session is already deleted.\n", __func__);
   1526 		return -1;
   1527 	}
   1528 
   1529 	refs = atomic_inc_32_nv(&mv_s->refs);
   1530 	if (refs == 1) {
   1531 		/*
   1532 		 * a session with refs == 0 is
   1533 		 * already invalidated. revert it.
   1534 		 * XXX: use CAS ?
   1535 		 */
   1536 		atomic_dec_32(&mv_s->refs);
   1537 		log(LOG_ERR,
   1538 		    "%s: session is already invalidated.\n", __func__);
   1539 		return -1;
   1540 	}
   1541 
   1542 	return 0;
   1543 }
   1544 
   1545 STATIC void
   1546 mvxpsec_session_unref(struct mvxpsec_session *mv_s)
   1547 {
   1548 	uint32_t refs;
   1549 
   1550 	refs = atomic_dec_32_nv(&mv_s->refs);
   1551 	if (refs == 0)
   1552 		pool_cache_put(mv_s->sc->sc_session_pool, mv_s);
   1553 }
   1554 
   1555 /*
   1556  * look for session is exist or not
   1557  */
   1558 INLINE struct mvxpsec_session *
   1559 mvxpsec_session_lookup(struct mvxpsec_softc *sc, int sid)
   1560 {
   1561 	struct mvxpsec_session *mv_s;
   1562 	int session;
   1563 
   1564 	/* must called sc->sc_session_mtx held */
   1565 	KASSERT(mutex_owned(&sc->sc_session_mtx));
   1566 
   1567 	session = MVXPSEC_SESSION(sid);
   1568 	if (__predict_false(session > MVXPSEC_MAX_SESSIONS)) {
   1569 		log(LOG_ERR, "%s: session number too large %d\n",
   1570 		    __func__, session);
   1571 		return NULL;
   1572 	}
   1573 	if (__predict_false( (mv_s = sc->sc_sessions[session]) == NULL)) {
   1574 		log(LOG_ERR, "%s: invalid session %d\n",
   1575 		    __func__, session);
   1576 		return NULL;
   1577 	}
   1578 
   1579 	KASSERT(mv_s->sid == session);
   1580 
   1581 	return mv_s;
   1582 }
   1583 
   1584 /*
   1585  * allocation new packet structure.
   1586  */
   1587 STATIC struct mvxpsec_packet *
   1588 mvxpsec_packet_alloc(struct mvxpsec_session *mv_s)
   1589 {
   1590 	struct mvxpsec_softc *sc = mv_s->sc;
   1591 	struct mvxpsec_packet *mv_p;
   1592 
   1593 	/* must be called mv_queue_mtx held. */
   1594 	KASSERT(mutex_owned(&sc->sc_queue_mtx));
   1595 	/* must be called mv_session_mtx held. */
   1596 	KASSERT(mutex_owned(&sc->sc_session_mtx));
   1597 
   1598 	if (mvxpsec_session_ref(mv_s) < 0) {
   1599 		log(LOG_ERR, "%s: invalid session.\n", __func__);
   1600 		return NULL;
   1601 	}
   1602 
   1603 	if ( (mv_p = SLIST_FIRST(&sc->sc_free_list)) != NULL) {
   1604 		SLIST_REMOVE_HEAD(&sc->sc_free_list, free_list);
   1605 		sc->sc_free_qlen--;
   1606 	}
   1607 	else {
   1608 		mv_p = pool_cache_get(sc->sc_packet_pool, PR_NOWAIT);
   1609 		if (mv_p == NULL) {
   1610 			log(LOG_ERR, "%s: cannot allocate memory\n",
   1611 			    __func__);
   1612 			mvxpsec_session_unref(mv_s);
   1613 			return NULL;
   1614 		}
   1615 	}
   1616 	mv_p->mv_s = mv_s;
   1617 	mv_p->flags = 0;
   1618 	mv_p->data_ptr = NULL;
   1619 
   1620 	return mv_p;
   1621 }
   1622 
   1623 /*
   1624  * free packet structure.
   1625  */
   1626 STATIC void
   1627 mvxpsec_packet_dealloc(struct mvxpsec_packet *mv_p)
   1628 {
   1629 	struct mvxpsec_session *mv_s = mv_p->mv_s;
   1630 	struct mvxpsec_softc *sc = mv_s->sc;
   1631 
   1632 	/* must called with sc->sc_queue_mtx held */
   1633 	KASSERT(mutex_owned(&sc->sc_queue_mtx));
   1634 
   1635 	if (mv_p->dma_ring.dma_size != 0) {
   1636 		sc->sc_desc_ring_cons += mv_p->dma_ring.dma_size;
   1637 	}
   1638 	mv_p->dma_ring.dma_head = NULL;
   1639 	mv_p->dma_ring.dma_last = NULL;
   1640 	mv_p->dma_ring.dma_size = 0;
   1641 
   1642 	if (mv_p->data_map) {
   1643 		if (mv_p->flags & RDY_DATA) {
   1644 			bus_dmamap_unload(sc->sc_dmat, mv_p->data_map);
   1645 			mv_p->flags &= ~RDY_DATA;
   1646 		}
   1647 	}
   1648 
   1649 	if (sc->sc_free_qlen > sc->sc_wait_qlimit)
   1650 		pool_cache_put(sc->sc_packet_pool, mv_p);
   1651 	else {
   1652 		SLIST_INSERT_HEAD(&sc->sc_free_list, mv_p, free_list);
   1653 		sc->sc_free_qlen++;
   1654 	}
   1655 	mvxpsec_session_unref(mv_s);
   1656 }
   1657 
   1658 INLINE void
   1659 mvxpsec_packet_enqueue(struct mvxpsec_packet *mv_p)
   1660 {
   1661 	struct mvxpsec_softc *sc = mv_p->mv_s->sc;
   1662 	struct mvxpsec_packet *last_packet;
   1663 	struct mvxpsec_descriptor_handle *cur_dma, *prev_dma;
   1664 
   1665 	/* must called with sc->sc_queue_mtx held */
   1666 	KASSERT(mutex_owned(&sc->sc_queue_mtx));
   1667 
   1668 	if (sc->sc_wait_qlen == 0) {
   1669 		SIMPLEQ_INSERT_TAIL(&sc->sc_wait_queue, mv_p, queue);
   1670 		sc->sc_wait_qlen++;
   1671 		mv_p->flags |= SETUP_DONE;
   1672 		return;
   1673 	}
   1674 
   1675 	last_packet = SIMPLEQ_LAST(&sc->sc_wait_queue, mvxpsec_packet, queue);
   1676 	SIMPLEQ_INSERT_TAIL(&sc->sc_wait_queue, mv_p, queue);
   1677 	sc->sc_wait_qlen++;
   1678 
   1679 	/* chain the DMA */
   1680 	cur_dma = mv_p->dma_ring.dma_head;
   1681 	prev_dma = last_packet->dma_ring.dma_last;
   1682 	mvxpsec_dma_cat(sc, prev_dma, cur_dma);
   1683 	mv_p->flags |= SETUP_DONE;
   1684 }
   1685 
   1686 /*
   1687  * called by interrupt handler
   1688  */
   1689 STATIC int
   1690 mvxpsec_done_packet(struct mvxpsec_packet *mv_p)
   1691 {
   1692 	struct mvxpsec_session *mv_s = mv_p->mv_s;
   1693 	struct mvxpsec_softc *sc = mv_s->sc;
   1694 
   1695 	KASSERT((mv_p->flags & RDY_DATA));
   1696 	KASSERT((mv_p->flags & SETUP_DONE));
   1697 
   1698 	/* unload data */
   1699 	bus_dmamap_sync(sc->sc_dmat, mv_p->data_map,
   1700 	    0, mv_p->data_len,
   1701 	    BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
   1702 	bus_dmamap_unload(sc->sc_dmat, mv_p->data_map);
   1703 	mv_p->flags &= ~RDY_DATA;
   1704 
   1705 #ifdef MVXPSEC_DEBUG
   1706 	if (mvxpsec_debug != 0) {
   1707 		int s;
   1708 
   1709 		bus_dmamap_sync(sc->sc_dmat, mv_p->pkt_header_map,
   1710 		    0, sizeof(mv_p->pkt_header),
   1711 		    BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
   1712 		bus_dmamap_sync(sc->sc_dmat, mv_s->session_header_map,
   1713 		    0, sizeof(mv_s->session_header),
   1714 		    BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
   1715 
   1716 		if (mvxpsec_debug & MVXPSEC_DEBUG_OPENCRYPTO) {
   1717 			char buf[1500];
   1718 			struct mbuf *m;
   1719 			struct uio *uio;
   1720 			size_t len;
   1721 
   1722 			switch (mv_p->data_type) {
   1723 			case MVXPSEC_DATA_MBUF:
   1724 				m = mv_p->data_mbuf;
   1725 				len = m->m_pkthdr.len;
   1726 				if (len > sizeof(buf))
   1727 					len = sizeof(buf);
   1728 				m_copydata(m, 0, len, buf);
   1729 				break;
   1730 			case MVXPSEC_DATA_UIO:
   1731 				uio = mv_p->data_uio;
   1732 				len = uio->uio_resid;
   1733 				if (len > sizeof(buf))
   1734 					len = sizeof(buf);
   1735 				cuio_copydata(uio, 0, len, buf);
   1736 				break;
   1737 			default:
   1738 				len = 0;
   1739 			}
   1740 			if (len > 0)
   1741 				mvxpsec_dump_data(__func__, buf, len);
   1742 		}
   1743 
   1744 		if (mvxpsec_debug & MVXPSEC_DEBUG_PAYLOAD) {
   1745 			MVXPSEC_PRINTF(MVXPSEC_DEBUG_PAYLOAD,
   1746 			    "%s: session_descriptor:\n", __func__);
   1747 			mvxpsec_dump_packet_desc(__func__, mv_p);
   1748 			MVXPSEC_PRINTF(MVXPSEC_DEBUG_PAYLOAD,
   1749 			    "%s: session_data:\n", __func__);
   1750 			mvxpsec_dump_packet_data(__func__, mv_p);
   1751 		}
   1752 
   1753 		if (mvxpsec_debug & MVXPSEC_DEBUG_SRAM) {
   1754 			MVXPSEC_PRINTF(MVXPSEC_DEBUG_SRAM,
   1755 			    "%s: SRAM\n", __func__);
   1756 			mvxpsec_dump_sram(__func__, sc, 2000);
   1757 		}
   1758 
   1759 		s = MVXPSEC_READ(sc, MV_ACC_STATUS);
   1760 		if (s & MV_ACC_STATUS_MAC_ERR) {
   1761 			MVXPSEC_PRINTF(MVXPSEC_DEBUG_INTR,
   1762 			    "%s: Message Authentication Failed.\n", __func__);
   1763 		}
   1764 	}
   1765 #endif
   1766 
   1767 	/* copy back IV */
   1768 	if (mv_p->flags & CRP_EXT_IV) {
   1769 		memcpy(mv_p->ext_iv,
   1770 		    &mv_p->pkt_header.crp_iv_ext, mv_p->ext_ivlen);
   1771 		mv_p->ext_iv = NULL;
   1772 		mv_p->ext_ivlen = 0;
   1773 	}
   1774 
   1775 	/* notify opencrypto */
   1776 	mv_p->crp->crp_etype = 0;
   1777 	crypto_done(mv_p->crp);
   1778 	mv_p->crp = NULL;
   1779 
   1780 	/* unblock driver */
   1781 	mvxpsec_packet_dealloc(mv_p);
   1782 	crypto_unblock(sc->sc_cid, CRYPTO_SYMQ|CRYPTO_ASYMQ);
   1783 
   1784 	MVXPSEC_EVCNT_INCR(sc, packet_ok);
   1785 
   1786 	return 0;
   1787 }
   1788 
   1789 
   1790 /*
   1791  * Opencrypto API registration
   1792  */
   1793 int
   1794 mvxpsec_register(struct mvxpsec_softc *sc)
   1795 {
   1796 	int oplen = SRAM_PAYLOAD_SIZE;
   1797 	int flags = 0;
   1798 	int err;
   1799 
   1800 	sc->sc_nsessions = 0;
   1801 	sc->sc_cid = crypto_get_driverid(0);
   1802 	if (sc->sc_cid < 0) {
   1803 		log(LOG_ERR,
   1804 		    "%s: crypto_get_driverid() failed.\n", __func__);
   1805 		err = EINVAL;
   1806 		goto done;
   1807 	}
   1808 
   1809 	/* Ciphers */
   1810 	err = crypto_register(sc->sc_cid, CRYPTO_DES_CBC, oplen, flags,
   1811 	    mvxpsec_newsession, mvxpsec_freesession, mvxpsec_dispatch, sc);
   1812 	if (err)
   1813 		goto done;
   1814 
   1815 	err = crypto_register(sc->sc_cid, CRYPTO_3DES_CBC, oplen, flags,
   1816 	    mvxpsec_newsession, mvxpsec_freesession, mvxpsec_dispatch, sc);
   1817 	if (err)
   1818 		goto done;
   1819 
   1820 	err = crypto_register(sc->sc_cid, CRYPTO_AES_CBC, oplen, flags,
   1821 	    mvxpsec_newsession, mvxpsec_freesession, mvxpsec_dispatch, sc);
   1822 	if (err)
   1823 		goto done;
   1824 
   1825 	/* MACs */
   1826 	err = crypto_register(sc->sc_cid, CRYPTO_SHA1_HMAC_96,
   1827 	    oplen, flags,
   1828 	    mvxpsec_newsession, mvxpsec_freesession, mvxpsec_dispatch, sc);
   1829 	if (err)
   1830 		goto done;
   1831 
   1832 	err = crypto_register(sc->sc_cid, CRYPTO_MD5_HMAC_96,
   1833 	    oplen, flags,
   1834 	    mvxpsec_newsession, mvxpsec_freesession, mvxpsec_dispatch, sc);
   1835 	if (err)
   1836 		goto done;
   1837 
   1838 #ifdef DEBUG
   1839 	log(LOG_DEBUG,
   1840 	    "%s: registered to opencrypto(max data = %d bytes)\n",
   1841 	    device_xname(sc->sc_dev), oplen);
   1842 #endif
   1843 
   1844 	err = 0;
   1845 done:
   1846 	return err;
   1847 }
   1848 
   1849 /*
   1850  * Create new opencrypto session
   1851  *
   1852  *   - register cipher key, mac key.
   1853  *   - initialize mac internal state.
   1854  */
   1855 int
   1856 mvxpsec_newsession(void *arg, uint32_t *sidp, struct cryptoini *cri)
   1857 {
   1858 	struct mvxpsec_softc *sc = arg;
   1859 	struct mvxpsec_session *mv_s = NULL;
   1860 	struct cryptoini *c;
   1861 	static int hint = 0;
   1862 	int session = -1;
   1863 	int sid;
   1864 	int err;
   1865 	int i;
   1866 
   1867 	/* allocate driver session context */
   1868 	mv_s = mvxpsec_session_alloc(sc);
   1869 	if (mv_s == NULL)
   1870 		return ENOMEM;
   1871 
   1872 	/*
   1873 	 * lookup opencrypto session table
   1874 	 *
   1875 	 * we have sc_session_mtx after here.
   1876 	 */
   1877 	mutex_enter(&sc->sc_session_mtx);
   1878 	if (sc->sc_nsessions >= MVXPSEC_MAX_SESSIONS) {
   1879 		mutex_exit(&sc->sc_session_mtx);
   1880 		log(LOG_ERR, "%s: too many IPsec SA(max %d)\n",
   1881 				__func__, MVXPSEC_MAX_SESSIONS);
   1882 		mvxpsec_session_dealloc(mv_s);
   1883 		return ENOMEM;
   1884 	}
   1885 	for (i = hint; i < MVXPSEC_MAX_SESSIONS; i++) {
   1886 		if (sc->sc_sessions[i])
   1887 			continue;
   1888 		session = i;
   1889 		hint = session + 1;
   1890 	       	break;
   1891 	}
   1892 	if (session < 0) {
   1893 		for (i = 0; i < hint; i++) {
   1894 			if (sc->sc_sessions[i])
   1895 				continue;
   1896 			session = i;
   1897 			hint = session + 1;
   1898 			break;
   1899 		}
   1900 		if (session < 0) {
   1901 			mutex_exit(&sc->sc_session_mtx);
   1902 			/* session full */
   1903 			log(LOG_ERR, "%s: too many IPsec SA(max %d)\n",
   1904 				__func__, MVXPSEC_MAX_SESSIONS);
   1905 			mvxpsec_session_dealloc(mv_s);
   1906 			hint = 0;
   1907 			return ENOMEM;
   1908 		}
   1909 	}
   1910 	if (hint >= MVXPSEC_MAX_SESSIONS)
   1911 		hint = 0;
   1912 	sc->sc_nsessions++;
   1913 	sc->sc_sessions[session] = mv_s;
   1914 #ifdef DEBUG
   1915 	log(LOG_DEBUG, "%s: new session %d allocated\n", __func__, session);
   1916 #endif
   1917 
   1918 	sid = MVXPSEC_SID(device_unit(sc->sc_dev), session);
   1919 	mv_s->sid = sid;
   1920 
   1921 	/* setup the session key ... */
   1922 	for (c = cri; c; c = c->cri_next) {
   1923 		switch (c->cri_alg) {
   1924 		case CRYPTO_DES_CBC:
   1925 		case CRYPTO_3DES_CBC:
   1926 		case CRYPTO_AES_CBC:
   1927 			/* key */
   1928 			if (mvxpsec_key_precomp(c->cri_alg,
   1929 			    c->cri_key, c->cri_klen,
   1930 			    &mv_s->session_header.crp_key,
   1931 			    &mv_s->session_header.crp_key_d)) {
   1932 				log(LOG_ERR,
   1933 				    "%s: Invalid HMAC key for %s.\n",
   1934 				    __func__, s_ctlalg(c->cri_alg));
   1935 				err = EINVAL;
   1936 				goto fail;
   1937 			}
   1938 			if (mv_s->sflags & RDY_CRP_KEY) {
   1939 				log(LOG_WARNING,
   1940 				    "%s: overwrite cipher: %s->%s.\n",
   1941 				    __func__,
   1942 				    s_ctlalg(mv_s->cipher_alg),
   1943 				    s_ctlalg(c->cri_alg));
   1944 			}
   1945 			mv_s->sflags |= RDY_CRP_KEY;
   1946 			mv_s->enc_klen = c->cri_klen;
   1947 			mv_s->cipher_alg = c->cri_alg;
   1948 			/* create per session IV (compatible with KAME IPsec) */
   1949 			cprng_fast(&mv_s->session_iv, sizeof(mv_s->session_iv));
   1950 			mv_s->sflags |= RDY_CRP_IV;
   1951 			break;
   1952 		case CRYPTO_SHA1_HMAC_96:
   1953 		case CRYPTO_MD5_HMAC_96:
   1954 			/* key */
   1955 			if (mvxpsec_hmac_precomp(c->cri_alg,
   1956 			    c->cri_key, c->cri_klen,
   1957 			    (uint32_t *)&mv_s->session_header.miv_in,
   1958 			    (uint32_t *)&mv_s->session_header.miv_out)) {
   1959 				log(LOG_ERR,
   1960 				    "%s: Invalid MAC key\n", __func__);
   1961 				err = EINVAL;
   1962 				goto fail;
   1963 			}
   1964 			if (mv_s->sflags & RDY_MAC_KEY ||
   1965 			    mv_s->sflags & RDY_MAC_IV) {
   1966 				log(LOG_ERR,
   1967 				    "%s: overwrite HMAC: %s->%s.\n",
   1968 				    __func__, s_ctlalg(mv_s->hmac_alg),
   1969 				    s_ctlalg(c->cri_alg));
   1970 			}
   1971 			mv_s->sflags |= RDY_MAC_KEY;
   1972 			mv_s->sflags |= RDY_MAC_IV;
   1973 
   1974 			mv_s->mac_klen = c->cri_klen;
   1975 			mv_s->hmac_alg = c->cri_alg;
   1976 			break;
   1977 		default:
   1978 			log(LOG_ERR, "%s: Unknown algorithm %d\n",
   1979 			    __func__, c->cri_alg);
   1980 			err = EINVAL;
   1981 			goto fail;
   1982 		}
   1983 	}
   1984 	MVXPSEC_PRINTF(MVXPSEC_DEBUG_OPENCRYPTO,
   1985 	    "H/W Crypto session (id:%u) added.\n", session);
   1986 
   1987 	*sidp = sid;
   1988 	MVXPSEC_EVCNT_INCR(sc, session_new);
   1989 	mutex_exit(&sc->sc_session_mtx);
   1990 
   1991 	/* sync session header(it's never touched after here) */
   1992 	bus_dmamap_sync(sc->sc_dmat,
   1993 	    mv_s->session_header_map,
   1994 	    0, sizeof(mv_s->session_header),
   1995 	    BUS_DMASYNC_PREWRITE);
   1996 
   1997 	return 0;
   1998 
   1999 fail:
   2000 	sc->sc_nsessions--;
   2001 	sc->sc_sessions[session] = NULL;
   2002 	hint = session;
   2003 	if (mv_s)
   2004 		mvxpsec_session_dealloc(mv_s);
   2005 	log(LOG_WARNING,
   2006 	    "%s: Failed to add H/W crypto sessoin (id:%u): err=%d\n",
   2007 	   __func__, session, err);
   2008 
   2009 	mutex_exit(&sc->sc_session_mtx);
   2010 	return err;
   2011 }
   2012 
   2013 /*
   2014  * remove opencrypto session
   2015  */
   2016 int
   2017 mvxpsec_freesession(void *arg, uint64_t tid)
   2018 {
   2019 	struct mvxpsec_softc *sc = arg;
   2020 	struct mvxpsec_session *mv_s;
   2021 	int session;
   2022 	uint32_t sid = ((uint32_t)tid) & 0xffffffff;
   2023 
   2024 	session = MVXPSEC_SESSION(sid);
   2025 	if (session < 0 || session >= MVXPSEC_MAX_SESSIONS) {
   2026 		log(LOG_ERR, "%s: invalid session (id:%u)\n",
   2027 		    __func__, session);
   2028 		return EINVAL;
   2029 	}
   2030 
   2031 	mutex_enter(&sc->sc_session_mtx);
   2032 	if ( (mv_s = sc->sc_sessions[session]) == NULL) {
   2033 		mutex_exit(&sc->sc_session_mtx);
   2034 #ifdef DEBUG
   2035 		log(LOG_DEBUG, "%s: session %d already inactivated\n",
   2036 		    __func__, session);
   2037 #endif
   2038 		return ENOENT;
   2039 	}
   2040 	MVXPSEC_PRINTF(MVXPSEC_DEBUG_OPENCRYPTO,
   2041 	    "%s: inactivate session %d\n", __func__, session);
   2042 
   2043 	/* inactivate mvxpsec session */
   2044 	sc->sc_sessions[session] = NULL;
   2045 	sc->sc_nsessions--;
   2046 	sc->sc_last_session = NULL;
   2047 	mutex_exit(&sc->sc_session_mtx);
   2048 
   2049 	KASSERT(sc->sc_nsessions >= 0);
   2050 	KASSERT(mv_s->sid == sid);
   2051 
   2052 	mvxpsec_session_dealloc(mv_s);
   2053 	MVXPSEC_PRINTF(MVXPSEC_DEBUG_OPENCRYPTO,
   2054 	    "H/W Crypto session (id: %d) deleted.\n", session);
   2055 
   2056 	/* force unblock opencrypto */
   2057 	crypto_unblock(sc->sc_cid, CRYPTO_SYMQ|CRYPTO_ASYMQ);
   2058 
   2059 	MVXPSEC_EVCNT_INCR(sc, session_free);
   2060 
   2061 	return 0;
   2062 }
   2063 
   2064 /*
   2065  * process data with existing session
   2066  */
   2067 int
   2068 mvxpsec_dispatch(void *arg, struct cryptop *crp, int hint)
   2069 {
   2070 	struct mvxpsec_softc *sc = arg;
   2071 	struct mvxpsec_session *mv_s;
   2072 	struct mvxpsec_packet *mv_p;
   2073 	int q_full;
   2074 	int running;
   2075 	int err;
   2076 
   2077 	mutex_enter(&sc->sc_queue_mtx);
   2078 
   2079 	/*
   2080 	 * lookup session
   2081 	 */
   2082 	mutex_enter(&sc->sc_session_mtx);
   2083 	mv_s = mvxpsec_session_lookup(sc, crp->crp_sid);
   2084 	if (__predict_false(mv_s == NULL)) {
   2085 		err = EINVAL;
   2086 		mv_p = NULL;
   2087 		mutex_exit(&sc->sc_session_mtx);
   2088 		goto fail;
   2089 	}
   2090 	mv_p = mvxpsec_packet_alloc(mv_s);
   2091 	if (__predict_false(mv_p == NULL)) {
   2092 		mutex_exit(&sc->sc_session_mtx);
   2093 		mutex_exit(&sc->sc_queue_mtx);
   2094 		return ERESTART; /* => queued in opencrypto layer */
   2095 	}
   2096 	mutex_exit(&sc->sc_session_mtx);
   2097 
   2098 	/*
   2099 	 * check queue status
   2100 	 */
   2101 #ifdef MVXPSEC_MULTI_PACKET
   2102 	q_full = (sc->sc_wait_qlen >= sc->sc_wait_qlimit) ? 1 : 0;
   2103 #else
   2104 	q_full = (sc->sc_wait_qlen != 0) ? 1 : 0;
   2105 #endif
   2106 	running = (sc->sc_flags & HW_RUNNING) ?  1: 0;
   2107 	if (q_full) {
   2108 		/* input queue is full. */
   2109 		if (!running && sc->sc_wait_qlen > 0)
   2110 			mvxpsec_dispatch_queue(sc);
   2111 		MVXPSEC_EVCNT_INCR(sc, queue_full);
   2112 		mvxpsec_packet_dealloc(mv_p);
   2113 		mutex_exit(&sc->sc_queue_mtx);
   2114 		return ERESTART; /* => queued in opencrypto layer */
   2115 	}
   2116 
   2117 	/*
   2118 	 * Load and setup packet data
   2119 	 */
   2120 	err = mvxpsec_packet_setcrp(mv_p, crp);
   2121 	if (__predict_false(err))
   2122 		goto fail;
   2123 
   2124 	/*
   2125 	 * Setup DMA descriptor chains
   2126 	 */
   2127 	mutex_enter(&sc->sc_dma_mtx);
   2128 	err = mvxpsec_dma_copy_packet(sc, mv_p);
   2129 	mutex_exit(&sc->sc_dma_mtx);
   2130 	if (__predict_false(err))
   2131 		goto fail;
   2132 
   2133 #ifdef MVXPSEC_DEBUG
   2134 	mvxpsec_dump_packet(__func__, mv_p);
   2135 #endif
   2136 
   2137 	/*
   2138 	 * Sync/inval the data cache
   2139 	 */
   2140 	err = mvxpsec_dma_sync_packet(sc, mv_p);
   2141 	if (__predict_false(err))
   2142 		goto fail;
   2143 
   2144 	/*
   2145 	 * Enqueue the packet
   2146 	 */
   2147 	MVXPSEC_EVCNT_INCR(sc, dispatch_packets);
   2148 #ifdef MVXPSEC_MULTI_PACKET
   2149 	mvxpsec_packet_enqueue(mv_p);
   2150 	if (!running)
   2151 		mvxpsec_dispatch_queue(sc);
   2152 #else
   2153 	SIMPLEQ_INSERT_TAIL(&sc->sc_wait_queue, mv_p, queue);
   2154 	sc->sc_wait_qlen++;
   2155 	mv_p->flags |= SETUP_DONE;
   2156 	if (!running)
   2157 		mvxpsec_dispatch_queue(sc);
   2158 #endif
   2159 	mutex_exit(&sc->sc_queue_mtx);
   2160 	return 0;
   2161 
   2162 fail:
   2163 	/* Drop the incoming packet */
   2164 	mvxpsec_drop(sc, crp, mv_p, err);
   2165 	mutex_exit(&sc->sc_queue_mtx);
   2166 	return 0;
   2167 }
   2168 
   2169 /*
   2170  * back the packet to the IP stack
   2171  */
   2172 void
   2173 mvxpsec_done(void *arg)
   2174 {
   2175 	struct mvxpsec_softc *sc = arg;
   2176 	struct mvxpsec_packet *mv_p;
   2177 	mvxpsec_queue_t ret_queue;
   2178 	int ndone;
   2179 
   2180 	mutex_enter(&sc->sc_queue_mtx);
   2181 
   2182 	/* stop wdog timer */
   2183 	callout_stop(&sc->sc_timeout);
   2184 
   2185 	/* refill MVXPSEC */
   2186 	ret_queue = sc->sc_run_queue;
   2187 	SIMPLEQ_INIT(&sc->sc_run_queue);
   2188 	sc->sc_flags &= ~HW_RUNNING;
   2189 	if (sc->sc_wait_qlen > 0)
   2190 		mvxpsec_dispatch_queue(sc);
   2191 
   2192 	ndone = 0;
   2193 	while ( (mv_p = SIMPLEQ_FIRST(&ret_queue)) != NULL) {
   2194 		SIMPLEQ_REMOVE_HEAD(&ret_queue, queue);
   2195 		mvxpsec_dma_free(sc, &mv_p->dma_ring);
   2196 		mvxpsec_done_packet(mv_p);
   2197 		ndone++;
   2198 	}
   2199 	MVXPSEC_EVCNT_MAX(sc, max_done, ndone);
   2200 
   2201 	mutex_exit(&sc->sc_queue_mtx);
   2202 }
   2203 
   2204 /*
   2205  * drop the packet
   2206  */
   2207 INLINE void
   2208 mvxpsec_drop(struct mvxpsec_softc *sc, struct cryptop *crp,
   2209     struct mvxpsec_packet *mv_p, int err)
   2210 {
   2211 	/* must called with sc->sc_queue_mtx held */
   2212 	KASSERT(mutex_owned(&sc->sc_queue_mtx));
   2213 
   2214 	if (mv_p)
   2215 		mvxpsec_packet_dealloc(mv_p);
   2216 	if (err < 0)
   2217 		err = EINVAL;
   2218 	crp->crp_etype = err;
   2219 	crypto_done(crp);
   2220 	MVXPSEC_EVCNT_INCR(sc, packet_err);
   2221 
   2222 	/* dispatch other packets in queue */
   2223 	if (sc->sc_wait_qlen > 0 &&
   2224 	    !(sc->sc_flags & HW_RUNNING))
   2225 		mvxpsec_dispatch_queue(sc);
   2226 
   2227 	/* unblock driver for dropped packet */
   2228 	crypto_unblock(sc->sc_cid, CRYPTO_SYMQ|CRYPTO_ASYMQ);
   2229 }
   2230 
   2231 /* move wait queue entry to run queue */
   2232 STATIC int
   2233 mvxpsec_dispatch_queue(struct mvxpsec_softc *sc)
   2234 {
   2235 	struct mvxpsec_packet *mv_p;
   2236 	paddr_t head;
   2237 	int ndispatch = 0;
   2238 
   2239 	/* must called with sc->sc_queue_mtx held */
   2240 	KASSERT(mutex_owned(&sc->sc_queue_mtx));
   2241 
   2242 	/* check there is any task */
   2243 	if (__predict_false(sc->sc_flags & HW_RUNNING)) {
   2244 		log(LOG_WARNING,
   2245 		    "%s: another packet already exist.\n", __func__);
   2246 		return 0;
   2247 	}
   2248 	if (__predict_false(SIMPLEQ_EMPTY(&sc->sc_wait_queue))) {
   2249 		log(LOG_WARNING,
   2250 		    "%s: no waiting packet yet(qlen=%d).\n",
   2251 		    __func__, sc->sc_wait_qlen);
   2252 		return 0;
   2253 	}
   2254 
   2255 	/* move queue */
   2256 	sc->sc_run_queue = sc->sc_wait_queue;
   2257 	sc->sc_flags |= HW_RUNNING; /* dropped by intr or timeout */
   2258 	SIMPLEQ_INIT(&sc->sc_wait_queue);
   2259 	ndispatch = sc->sc_wait_qlen;
   2260 	sc->sc_wait_qlen = 0;
   2261 
   2262 	/* get 1st DMA descriptor */
   2263 	mv_p = SIMPLEQ_FIRST(&sc->sc_run_queue);
   2264 	head = mv_p->dma_ring.dma_head->phys_addr;
   2265 
   2266 	/* terminate last DMA descriptor */
   2267 	mv_p = SIMPLEQ_LAST(&sc->sc_run_queue, mvxpsec_packet, queue);
   2268 	mvxpsec_dma_finalize(sc, &mv_p->dma_ring);
   2269 
   2270 	/* configure TDMA */
   2271 	if (mvxpsec_dma_wait(sc) < 0) {
   2272 		log(LOG_ERR, "%s: DMA DEVICE not responding", __func__);
   2273 		callout_schedule(&sc->sc_timeout, hz);
   2274 		return 0;
   2275 	}
   2276 	MVXPSEC_WRITE(sc, MV_TDMA_NXT, head);
   2277 
   2278 	/* trigger ACC */
   2279 	if (mvxpsec_acc_wait(sc) < 0) {
   2280 		log(LOG_ERR, "%s: MVXPSEC not responding", __func__);
   2281 		callout_schedule(&sc->sc_timeout, hz);
   2282 		return 0;
   2283 	}
   2284 	MVXPSEC_WRITE(sc, MV_ACC_COMMAND, MV_ACC_COMMAND_ACT);
   2285 
   2286 	MVXPSEC_EVCNT_MAX(sc, max_dispatch, ndispatch);
   2287 	MVXPSEC_EVCNT_INCR(sc, dispatch_queue);
   2288 	callout_schedule(&sc->sc_timeout, hz);
   2289 	return 0;
   2290 }
   2291 
   2292 /*
   2293  * process opencrypto operations(cryptop) for packets.
   2294  */
   2295 INLINE int
   2296 mvxpsec_parse_crd(struct mvxpsec_packet *mv_p, struct cryptodesc *crd)
   2297 {
   2298 	int ivlen;
   2299 
   2300 	KASSERT(mv_p->flags & RDY_DATA);
   2301 
   2302 	/* MAC & Ciphers: set data location and operation */
   2303 	switch (crd->crd_alg) {
   2304 	case CRYPTO_SHA1_HMAC_96:
   2305 		mv_p->pkt_header.desc.acc_config |= MV_ACC_CRYPTO_MAC_96;
   2306 		/* fall through */
   2307 	case CRYPTO_SHA1_HMAC:
   2308 		mv_p->mac_dst = crd->crd_inject;
   2309 		mv_p->mac_off = crd->crd_skip;
   2310 		mv_p->mac_len = crd->crd_len;
   2311 		MV_ACC_CRYPTO_MAC_SET(mv_p->pkt_header.desc.acc_config,
   2312 		    MV_ACC_CRYPTO_MAC_HMAC_SHA1);
   2313 		mvxpsec_packet_update_op_order(mv_p, MV_ACC_CRYPTO_OP_MAC);
   2314 		/* No more setup for MAC */
   2315 		return 0;
   2316 	case CRYPTO_MD5_HMAC_96:
   2317 		mv_p->pkt_header.desc.acc_config |= MV_ACC_CRYPTO_MAC_96;
   2318 		/* fall through */
   2319 	case CRYPTO_MD5_HMAC:
   2320 		mv_p->mac_dst = crd->crd_inject;
   2321 		mv_p->mac_off = crd->crd_skip;
   2322 		mv_p->mac_len = crd->crd_len;
   2323 		MV_ACC_CRYPTO_MAC_SET(mv_p->pkt_header.desc.acc_config,
   2324 		    MV_ACC_CRYPTO_MAC_HMAC_MD5);
   2325 		mvxpsec_packet_update_op_order(mv_p, MV_ACC_CRYPTO_OP_MAC);
   2326 		/* No more setup for MAC */
   2327 		return 0;
   2328 	case CRYPTO_DES_CBC:
   2329 		mv_p->enc_ivoff = crd->crd_inject;
   2330 		mv_p->enc_off = crd->crd_skip;
   2331 		mv_p->enc_len = crd->crd_len;
   2332 		ivlen = 8;
   2333 		MV_ACC_CRYPTO_ENC_SET(mv_p->pkt_header.desc.acc_config,
   2334 		    MV_ACC_CRYPTO_ENC_DES);
   2335 		mv_p->pkt_header.desc.acc_config |= MV_ACC_CRYPTO_CBC;
   2336 		mvxpsec_packet_update_op_order(mv_p, MV_ACC_CRYPTO_OP_ENC);
   2337 		break;
   2338 	case CRYPTO_3DES_CBC:
   2339 		mv_p->enc_ivoff = crd->crd_inject;
   2340 		mv_p->enc_off = crd->crd_skip;
   2341 		mv_p->enc_len = crd->crd_len;
   2342 		ivlen = 8;
   2343 		MV_ACC_CRYPTO_ENC_SET(mv_p->pkt_header.desc.acc_config,
   2344 		    MV_ACC_CRYPTO_ENC_3DES);
   2345 		mv_p->pkt_header.desc.acc_config |= MV_ACC_CRYPTO_CBC;
   2346 		mv_p->pkt_header.desc.acc_config |= MV_ACC_CRYPTO_3DES_EDE;
   2347 		mvxpsec_packet_update_op_order(mv_p, MV_ACC_CRYPTO_OP_ENC);
   2348 		break;
   2349 	case CRYPTO_AES_CBC:
   2350 		mv_p->enc_ivoff = crd->crd_inject;
   2351 		mv_p->enc_off = crd->crd_skip;
   2352 		mv_p->enc_len = crd->crd_len;
   2353 		ivlen = 16;
   2354 		MV_ACC_CRYPTO_ENC_SET(mv_p->pkt_header.desc.acc_config,
   2355 		    MV_ACC_CRYPTO_ENC_AES);
   2356 		MV_ACC_CRYPTO_AES_KLEN_SET(
   2357 		    mv_p->pkt_header.desc.acc_config,
   2358 		   mvxpsec_aesklen(mv_p->mv_s->enc_klen));
   2359 		mv_p->pkt_header.desc.acc_config |= MV_ACC_CRYPTO_CBC;
   2360 		mvxpsec_packet_update_op_order(mv_p, MV_ACC_CRYPTO_OP_ENC);
   2361 		break;
   2362 	default:
   2363 		log(LOG_ERR, "%s: Unknown algorithm %d\n",
   2364 		    __func__, crd->crd_alg);
   2365 		return EINVAL;
   2366 	}
   2367 
   2368 	/* Operations only for Cipher, not MAC */
   2369 	if (crd->crd_flags & CRD_F_ENCRYPT) {
   2370 		/* Ciphers: Originate IV for Encryption.*/
   2371 		mv_p->pkt_header.desc.acc_config &= ~MV_ACC_CRYPTO_DECRYPT;
   2372 		mv_p->flags |= DIR_ENCRYPT;
   2373 
   2374 		if (crd->crd_flags & CRD_F_IV_EXPLICIT) {
   2375 			MVXPSEC_PRINTF(MVXPSEC_DEBUG_ENC_IV, "EXPLICIT IV\n");
   2376 			mv_p->flags |= CRP_EXT_IV;
   2377 			mvxpsec_packet_write_iv(mv_p, crd->crd_iv, ivlen);
   2378 			mv_p->enc_ivoff = MVXPSEC_SRAM_IV_EXT_OFF;
   2379 		}
   2380 		else if (crd->crd_flags & CRD_F_IV_PRESENT) {
   2381 			MVXPSEC_PRINTF(MVXPSEC_DEBUG_ENC_IV, "IV is present\n");
   2382 			mvxpsec_packet_copy_iv(mv_p, crd->crd_inject, ivlen);
   2383 		}
   2384 		else {
   2385 			MVXPSEC_PRINTF(MVXPSEC_DEBUG_ENC_IV, "Create New IV\n");
   2386 			mvxpsec_packet_write_iv(mv_p, NULL, ivlen);
   2387 		}
   2388 	}
   2389 	else {
   2390 		/* Ciphers: IV is loadded from crd_inject when it's present */
   2391 		mv_p->pkt_header.desc.acc_config |= MV_ACC_CRYPTO_DECRYPT;
   2392 		mv_p->flags |= DIR_DECRYPT;
   2393 
   2394 		if (crd->crd_flags & CRD_F_IV_EXPLICIT) {
   2395 #ifdef MVXPSEC_DEBUG
   2396 			if (mvxpsec_debug & MVXPSEC_DEBUG_ENC_IV) {
   2397 				MVXPSEC_PRINTF(MVXPSEC_DEBUG_ENC_IV,
   2398 				    "EXPLICIT IV(Decrypt)\n");
   2399 				mvxpsec_dump_data(__func__, crd->crd_iv, ivlen);
   2400 			}
   2401 #endif
   2402 			mv_p->flags |= CRP_EXT_IV;
   2403 			mvxpsec_packet_write_iv(mv_p, crd->crd_iv, ivlen);
   2404 			mv_p->enc_ivoff = MVXPSEC_SRAM_IV_EXT_OFF;
   2405 		}
   2406 	}
   2407 
   2408 	KASSERT(!((mv_p->flags & DIR_ENCRYPT) && (mv_p->flags & DIR_DECRYPT)));
   2409 
   2410 	return 0;
   2411 }
   2412 
   2413 INLINE int
   2414 mvxpsec_parse_crp(struct mvxpsec_packet *mv_p)
   2415 {
   2416 	struct cryptop *crp = mv_p->crp;
   2417 	struct cryptodesc *crd;
   2418 	int err;
   2419 
   2420 	KASSERT(crp);
   2421 
   2422 	mvxpsec_packet_reset_op(mv_p);
   2423 
   2424 	for (crd = crp->crp_desc; crd; crd = crd->crd_next) {
   2425 		err = mvxpsec_parse_crd(mv_p, crd);
   2426 		if (err)
   2427 			return err;
   2428 	}
   2429 
   2430 	return 0;
   2431 }
   2432 
   2433 INLINE int
   2434 mvxpsec_packet_setcrp(struct mvxpsec_packet *mv_p, struct cryptop *crp)
   2435 {
   2436 	int err = EINVAL;
   2437 
   2438 	/* regiseter crp to the MVXPSEC packet */
   2439 	if (crp->crp_flags & CRYPTO_F_IMBUF) {
   2440 		err = mvxpsec_packet_setmbuf(mv_p,
   2441 		    (struct mbuf *)crp->crp_buf);
   2442 		mv_p->crp = crp;
   2443 	}
   2444 	else if (crp->crp_flags & CRYPTO_F_IOV) {
   2445 		err = mvxpsec_packet_setuio(mv_p,
   2446 		    (struct uio *)crp->crp_buf);
   2447 		mv_p->crp = crp;
   2448 	}
   2449 	else {
   2450 		err = mvxpsec_packet_setdata(mv_p,
   2451 		    (struct mbuf *)crp->crp_buf, crp->crp_ilen);
   2452 		mv_p->crp = crp;
   2453 	}
   2454 	if (__predict_false(err))
   2455 		return err;
   2456 
   2457 	/* parse crp and setup MVXPSEC registers/descriptors */
   2458 	err = mvxpsec_parse_crp(mv_p);
   2459 	if (__predict_false(err))
   2460 		return err;
   2461 
   2462 	/* fixup data offset to fit MVXPSEC internal SRAM */
   2463 	err = mvxpsec_header_finalize(mv_p);
   2464 	if (__predict_false(err))
   2465 		return err;
   2466 
   2467 	return 0;
   2468 }
   2469 
   2470 /*
   2471  * load data for encrypt/decrypt/authentication
   2472  *
   2473  * data is raw kernel memory area.
   2474  */
   2475 STATIC int
   2476 mvxpsec_packet_setdata(struct mvxpsec_packet *mv_p,
   2477     void *data, uint32_t data_len)
   2478 {
   2479 	struct mvxpsec_session *mv_s = mv_p->mv_s;
   2480 	struct mvxpsec_softc *sc = mv_s->sc;
   2481 
   2482 	if (bus_dmamap_load(sc->sc_dmat, mv_p->data_map, data, data_len,
   2483 	    NULL, BUS_DMA_NOWAIT)) {
   2484 		log(LOG_ERR, "%s: cannot load data\n", __func__);
   2485 		return -1;
   2486 	}
   2487 	mv_p->data_type = MVXPSEC_DATA_RAW;
   2488 	mv_p->data_raw = data;
   2489 	mv_p->data_len = data_len;
   2490 	mv_p->flags |= RDY_DATA;
   2491 
   2492 	return 0;
   2493 }
   2494 
   2495 /*
   2496  * load data for encrypt/decrypt/authentication
   2497  *
   2498  * data is mbuf based network data.
   2499  */
   2500 STATIC int
   2501 mvxpsec_packet_setmbuf(struct mvxpsec_packet *mv_p, struct mbuf *m)
   2502 {
   2503 	struct mvxpsec_session *mv_s = mv_p->mv_s;
   2504 	struct mvxpsec_softc *sc = mv_s->sc;
   2505 	size_t pktlen = 0;
   2506 
   2507 	if (__predict_true(m->m_flags & M_PKTHDR))
   2508 		pktlen = m->m_pkthdr.len;
   2509 	else {
   2510 		struct mbuf *mp = m;
   2511 
   2512 		while (mp != NULL) {
   2513 			pktlen += m->m_len;
   2514 			mp = mp->m_next;
   2515 		}
   2516 	}
   2517 	if (pktlen > SRAM_PAYLOAD_SIZE) {
   2518 		extern   percpu_t *espstat_percpu;
   2519 	       	/* XXX:
   2520 		 * layer violation. opencrypto knows our max packet size
   2521 		 * from crypto_register(9) API.
   2522 		 */
   2523 
   2524 		_NET_STATINC(espstat_percpu, ESP_STAT_TOOBIG);
   2525 		log(LOG_ERR,
   2526 		    "%s: ESP Packet too large: %zu [oct.] > %zu [oct.]\n",
   2527 		    device_xname(sc->sc_dev),
   2528 		    (size_t)pktlen, SRAM_PAYLOAD_SIZE);
   2529 		mv_p->data_type = MVXPSEC_DATA_NONE;
   2530 		mv_p->data_mbuf = NULL;
   2531 		return -1;
   2532 	}
   2533 
   2534 	if (bus_dmamap_load_mbuf(sc->sc_dmat, mv_p->data_map, m,
   2535 	    BUS_DMA_NOWAIT)) {
   2536 		mv_p->data_type = MVXPSEC_DATA_NONE;
   2537 		mv_p->data_mbuf = NULL;
   2538 		log(LOG_ERR, "%s: cannot load mbuf\n", __func__);
   2539 		return -1;
   2540 	}
   2541 
   2542 	/* set payload buffer */
   2543 	mv_p->data_type = MVXPSEC_DATA_MBUF;
   2544 	mv_p->data_mbuf = m;
   2545 	if (m->m_flags & M_PKTHDR) {
   2546 		mv_p->data_len = m->m_pkthdr.len;
   2547 	}
   2548 	else {
   2549 		mv_p->data_len = 0;
   2550 		while (m) {
   2551 			mv_p->data_len += m->m_len;
   2552 			m = m->m_next;
   2553 		}
   2554 	}
   2555 	mv_p->flags |= RDY_DATA;
   2556 
   2557 	return 0;
   2558 }
   2559 
   2560 STATIC int
   2561 mvxpsec_packet_setuio(struct mvxpsec_packet *mv_p, struct uio *uio)
   2562 {
   2563 	struct mvxpsec_session *mv_s = mv_p->mv_s;
   2564 	struct mvxpsec_softc *sc = mv_s->sc;
   2565 
   2566 	if (uio->uio_resid > SRAM_PAYLOAD_SIZE) {
   2567 		extern   percpu_t *espstat_percpu;
   2568 	       	/* XXX:
   2569 		 * layer violation. opencrypto knows our max packet size
   2570 		 * from crypto_register(9) API.
   2571 		 */
   2572 
   2573 		_NET_STATINC(espstat_percpu, ESP_STAT_TOOBIG);
   2574 		log(LOG_ERR,
   2575 		    "%s: uio request too large: %zu [oct.] > %zu [oct.]\n",
   2576 		    device_xname(sc->sc_dev),
   2577 		    uio->uio_resid, SRAM_PAYLOAD_SIZE);
   2578 		mv_p->data_type = MVXPSEC_DATA_NONE;
   2579 		mv_p->data_mbuf = NULL;
   2580 		return -1;
   2581 	}
   2582 
   2583 	if (bus_dmamap_load_uio(sc->sc_dmat, mv_p->data_map, uio,
   2584 	    BUS_DMA_NOWAIT)) {
   2585 		mv_p->data_type = MVXPSEC_DATA_NONE;
   2586 		mv_p->data_mbuf = NULL;
   2587 		log(LOG_ERR, "%s: cannot load uio buf\n", __func__);
   2588 		return -1;
   2589 	}
   2590 
   2591 	/* set payload buffer */
   2592 	mv_p->data_type = MVXPSEC_DATA_UIO;
   2593 	mv_p->data_uio = uio;
   2594 	mv_p->data_len = uio->uio_resid;
   2595 	mv_p->flags |= RDY_DATA;
   2596 
   2597 	return 0;
   2598 }
   2599 
   2600 STATIC int
   2601 mvxpsec_packet_rdata(struct mvxpsec_packet *mv_p,
   2602     int off, int len, void *cp)
   2603 {
   2604 	uint8_t *p;
   2605 
   2606 	if (mv_p->data_type == MVXPSEC_DATA_RAW) {
   2607 		p = (uint8_t *)mv_p->data_raw + off;
   2608 		memcpy(cp, p, len);
   2609 	}
   2610 	else if (mv_p->data_type == MVXPSEC_DATA_MBUF) {
   2611 		m_copydata(mv_p->data_mbuf, off, len, cp);
   2612 	}
   2613 	else if (mv_p->data_type == MVXPSEC_DATA_UIO) {
   2614 		cuio_copydata(mv_p->data_uio, off, len, cp);
   2615 	}
   2616 	else
   2617 		return -1;
   2618 
   2619 	return 0;
   2620 }
   2621 
   2622 STATIC int
   2623 mvxpsec_packet_wdata(struct mvxpsec_packet *mv_p,
   2624     int off, int len, void *cp)
   2625 {
   2626 	uint8_t *p;
   2627 
   2628 	if (mv_p->data_type == MVXPSEC_DATA_RAW) {
   2629 		p = (uint8_t *)mv_p->data_raw + off;
   2630 		memcpy(p, cp, len);
   2631 	}
   2632 	else if (mv_p->data_type == MVXPSEC_DATA_MBUF) {
   2633 		m_copyback(mv_p->data_mbuf, off, len, cp);
   2634 	}
   2635 	else if (mv_p->data_type == MVXPSEC_DATA_UIO) {
   2636 		cuio_copyback(mv_p->data_uio, off, len, cp);
   2637 	}
   2638 	else
   2639 		return -1;
   2640 
   2641 	return 0;
   2642 }
   2643 
   2644 /*
   2645  * Set initial vector of cipher to the session.
   2646  */
   2647 STATIC int
   2648 mvxpsec_packet_write_iv(struct mvxpsec_packet *mv_p, void *iv, int ivlen)
   2649 {
   2650 	uint8_t ivbuf[16];
   2651 
   2652 	KASSERT(ivlen == 8 || ivlen == 16);
   2653 
   2654 	if (iv == NULL) {
   2655 	       	if (mv_p->mv_s->sflags & RDY_CRP_IV) {
   2656 			/* use per session IV (compatible with KAME IPsec) */
   2657 			mv_p->pkt_header.crp_iv_work = mv_p->mv_s->session_iv;
   2658 			mv_p->flags |= RDY_CRP_IV;
   2659 			return 0;
   2660 		}
   2661 		cprng_fast(ivbuf, ivlen);
   2662 		iv = ivbuf;
   2663 	}
   2664 	memcpy(&mv_p->pkt_header.crp_iv_work, iv, ivlen);
   2665 	if (mv_p->flags & CRP_EXT_IV) {
   2666 		memcpy(&mv_p->pkt_header.crp_iv_ext, iv, ivlen);
   2667 		mv_p->ext_iv = iv;
   2668 		mv_p->ext_ivlen = ivlen;
   2669 	}
   2670 	mv_p->flags |= RDY_CRP_IV;
   2671 
   2672 	return 0;
   2673 }
   2674 
   2675 STATIC int
   2676 mvxpsec_packet_copy_iv(struct mvxpsec_packet *mv_p, int off, int ivlen)
   2677 {
   2678 	mvxpsec_packet_rdata(mv_p, off, ivlen,
   2679 	    &mv_p->pkt_header.crp_iv_work);
   2680 	mv_p->flags |= RDY_CRP_IV;
   2681 
   2682 	return 0;
   2683 }
   2684 
   2685 /*
   2686  * set a encryption or decryption key to the session
   2687  *
   2688  * Input key material is big endian.
   2689  */
   2690 STATIC int
   2691 mvxpsec_key_precomp(int alg, void *keymat, int kbitlen,
   2692     void *key_encrypt, void *key_decrypt)
   2693 {
   2694 	uint32_t *kp = keymat;
   2695 	uint32_t *ekp = key_encrypt;
   2696 	uint32_t *dkp = key_decrypt;
   2697 	int i;
   2698 
   2699 	switch (alg) {
   2700 	case CRYPTO_DES_CBC:
   2701 		if (kbitlen < 64 || (kbitlen % 8) != 0) {
   2702 			log(LOG_WARNING,
   2703 			    "mvxpsec: invalid DES keylen %d\n", kbitlen);
   2704 			return EINVAL;
   2705 		}
   2706 		for (i = 0; i < 2; i++)
   2707 			dkp[i] = ekp[i] = kp[i];
   2708 		for (; i < 8; i++)
   2709 			dkp[i] = ekp[i] = 0;
   2710 		break;
   2711 	case CRYPTO_3DES_CBC:
   2712 		if (kbitlen < 192 || (kbitlen % 8) != 0) {
   2713 			log(LOG_WARNING,
   2714 			    "mvxpsec: invalid 3DES keylen %d\n", kbitlen);
   2715 			return EINVAL;
   2716 		}
   2717 		for (i = 0; i < 8; i++)
   2718 			dkp[i] = ekp[i] = kp[i];
   2719 		break;
   2720 	case CRYPTO_AES_CBC:
   2721 		if (kbitlen < 128) {
   2722 			log(LOG_WARNING,
   2723 			    "mvxpsec: invalid AES keylen %d\n", kbitlen);
   2724 			return EINVAL;
   2725 		}
   2726 		else if (kbitlen < 192) {
   2727 			/* AES-128 */
   2728 			for (i = 0; i < 4; i++)
   2729 				ekp[i] = kp[i];
   2730 			for (; i < 8; i++)
   2731 				ekp[i] = 0;
   2732 		}
   2733 	       	else if (kbitlen < 256) {
   2734 			/* AES-192 */
   2735 			for (i = 0; i < 6; i++)
   2736 				ekp[i] = kp[i];
   2737 			for (; i < 8; i++)
   2738 				ekp[i] = 0;
   2739 		}
   2740 		else  {
   2741 			/* AES-256 */
   2742 			for (i = 0; i < 8; i++)
   2743 				ekp[i] = kp[i];
   2744 		}
   2745 		/* make decryption key */
   2746 		mv_aes_deckey((uint8_t *)dkp, (uint8_t *)ekp, kbitlen);
   2747 		break;
   2748 	default:
   2749 		for (i = 0; i < 8; i++)
   2750 			ekp[0] = dkp[0] = 0;
   2751 		break;
   2752 	}
   2753 
   2754 #ifdef MVXPSEC_DEBUG
   2755 	if (mvxpsec_debug & MVXPSEC_DEBUG_OPENCRYPTO) {
   2756 		MVXPSEC_PRINTF(MVXPSEC_DEBUG_OPENCRYPTO,
   2757 		    "%s: keyregistered\n", __func__);
   2758 		mvxpsec_dump_data(__func__, ekp, 32);
   2759 	}
   2760 #endif
   2761 
   2762 	return 0;
   2763 }
   2764 
   2765 /*
   2766  * set MAC key to the session
   2767  *
   2768  * MAC engine has no register for key itself, but the engine has
   2769  * inner and outer IV register. software must compute IV before
   2770  * enable the engine.
   2771  *
   2772  * IV is a hash of ipad/opad. these are defined by FIPS-198a
   2773  * standard.
   2774  */
   2775 STATIC int
   2776 mvxpsec_hmac_precomp(int alg, void *key, int kbitlen,
   2777     void *iv_inner, void *iv_outer)
   2778 {
   2779 	SHA1_CTX sha1;
   2780 	MD5_CTX md5;
   2781 	uint8_t *key8 = key;
   2782 	uint8_t kbuf[64];
   2783 	uint8_t ipad[64];
   2784 	uint8_t opad[64];
   2785 	uint32_t *iv_in = iv_inner;
   2786 	uint32_t *iv_out = iv_outer;
   2787 	int kbytelen;
   2788 	int i;
   2789 #define HMAC_IPAD 0x36
   2790 #define HMAC_OPAD 0x5c
   2791 
   2792 	kbytelen = kbitlen / 8;
   2793 	KASSERT(kbitlen == kbytelen * 8);
   2794 	if (kbytelen > 64) {
   2795 		SHA1Init(&sha1);
   2796 		SHA1Update(&sha1, key, kbytelen);
   2797 		SHA1Final(kbuf, &sha1);
   2798 		key8 = kbuf;
   2799 		kbytelen = 64;
   2800 	}
   2801 
   2802 	/* make initial 64 oct. string */
   2803 	switch (alg) {
   2804 	case CRYPTO_SHA1_HMAC_96:
   2805 	case CRYPTO_SHA1_HMAC:
   2806 	case CRYPTO_MD5_HMAC_96:
   2807 	case CRYPTO_MD5_HMAC:
   2808 		for (i = 0; i < kbytelen; i++) {
   2809 			ipad[i] = (key8[i] ^ HMAC_IPAD);
   2810 			opad[i] = (key8[i] ^ HMAC_OPAD);
   2811 		}
   2812 		for (; i < 64; i++) {
   2813 			ipad[i] = HMAC_IPAD;
   2814 			opad[i] = HMAC_OPAD;
   2815 		}
   2816 		break;
   2817 	default:
   2818 		break;
   2819 	}
   2820 #ifdef MVXPSEC_DEBUG
   2821 	if (mvxpsec_debug & MVXPSEC_DEBUG_OPENCRYPTO) {
   2822 		MVXPSEC_PRINTF(MVXPSEC_DEBUG_OPENCRYPTO,
   2823 		    "%s: HMAC-KEY Pre-comp:\n", __func__);
   2824 		mvxpsec_dump_data(__func__, key, 64);
   2825 		MVXPSEC_PRINTF(MVXPSEC_DEBUG_OPENCRYPTO,
   2826 		    "%s: ipad:\n", __func__);
   2827 		mvxpsec_dump_data(__func__, ipad, sizeof(ipad));
   2828 		MVXPSEC_PRINTF(MVXPSEC_DEBUG_OPENCRYPTO,
   2829 		    "%s: opad:\n", __func__);
   2830 		mvxpsec_dump_data(__func__, opad, sizeof(opad));
   2831 	}
   2832 #endif
   2833 
   2834 	/* make iv from string */
   2835 	switch (alg) {
   2836 	case CRYPTO_SHA1_HMAC_96:
   2837 	case CRYPTO_SHA1_HMAC:
   2838 		MVXPSEC_PRINTF(MVXPSEC_DEBUG_OPENCRYPTO,
   2839 		    "%s: Generate iv_in(SHA1)\n", __func__);
   2840 		SHA1Init(&sha1);
   2841 		SHA1Update(&sha1, ipad, 64);
   2842 		/* XXX: private state... (LE) */
   2843 		iv_in[0] = htobe32(sha1.state[0]);
   2844 		iv_in[1] = htobe32(sha1.state[1]);
   2845 		iv_in[2] = htobe32(sha1.state[2]);
   2846 		iv_in[3] = htobe32(sha1.state[3]);
   2847 		iv_in[4] = htobe32(sha1.state[4]);
   2848 
   2849 		MVXPSEC_PRINTF(MVXPSEC_DEBUG_OPENCRYPTO,
   2850 		    "%s: Generate iv_out(SHA1)\n", __func__);
   2851 		SHA1Init(&sha1);
   2852 		SHA1Update(&sha1, opad, 64);
   2853 		/* XXX: private state... (LE) */
   2854 		iv_out[0] = htobe32(sha1.state[0]);
   2855 		iv_out[1] = htobe32(sha1.state[1]);
   2856 		iv_out[2] = htobe32(sha1.state[2]);
   2857 		iv_out[3] = htobe32(sha1.state[3]);
   2858 		iv_out[4] = htobe32(sha1.state[4]);
   2859 		break;
   2860 	case CRYPTO_MD5_HMAC_96:
   2861 	case CRYPTO_MD5_HMAC:
   2862 		MVXPSEC_PRINTF(MVXPSEC_DEBUG_OPENCRYPTO,
   2863 		    "%s: Generate iv_in(MD5)\n", __func__);
   2864 		MD5Init(&md5);
   2865 		MD5Update(&md5, ipad, sizeof(ipad));
   2866 		/* XXX: private state... (LE) */
   2867 		iv_in[0] = htobe32(md5.state[0]);
   2868 		iv_in[1] = htobe32(md5.state[1]);
   2869 		iv_in[2] = htobe32(md5.state[2]);
   2870 		iv_in[3] = htobe32(md5.state[3]);
   2871 		iv_in[4] = 0;
   2872 
   2873 		MVXPSEC_PRINTF(MVXPSEC_DEBUG_OPENCRYPTO,
   2874 		    "%s: Generate iv_out(MD5)\n", __func__);
   2875 		MD5Init(&md5);
   2876 		MD5Update(&md5, opad, sizeof(opad));
   2877 		/* XXX: private state... (LE) */
   2878 		iv_out[0] = htobe32(md5.state[0]);
   2879 		iv_out[1] = htobe32(md5.state[1]);
   2880 		iv_out[2] = htobe32(md5.state[2]);
   2881 		iv_out[3] = htobe32(md5.state[3]);
   2882 		iv_out[4] = 0;
   2883 		break;
   2884 	default:
   2885 		break;
   2886 	}
   2887 
   2888 #ifdef MVXPSEC_DEBUG
   2889 	if (mvxpsec_debug & MVXPSEC_DEBUG_HASH_IV) {
   2890 		MVXPSEC_PRINTF(MVXPSEC_DEBUG_HASH_IV,
   2891 		    "%s: HMAC IV-IN\n", __func__);
   2892 		mvxpsec_dump_data(__func__, (uint8_t *)iv_in, 20);
   2893 		MVXPSEC_PRINTF(MVXPSEC_DEBUG_HASH_IV,
   2894 		    "%s: HMAC IV-OUT\n", __func__);
   2895 		mvxpsec_dump_data(__func__, (uint8_t *)iv_out, 20);
   2896 	}
   2897 #endif
   2898 
   2899 	return 0;
   2900 #undef HMAC_IPAD
   2901 #undef HMAC_OPAD
   2902 }
   2903 
   2904 /*
   2905  * AES Support routine
   2906  */
   2907 static uint8_t AES_SBOX[256] = {
   2908 	 99, 124, 119, 123, 242, 107, 111, 197,  48,   1, 103,  43, 254, 215,
   2909        	171, 118, 202, 130, 201, 125, 250,  89,  71, 240, 173, 212, 162, 175,
   2910        	156, 164, 114, 192, 183, 253, 147,  38,  54,  63, 247, 204,  52, 165,
   2911        	229, 241, 113, 216,  49,  21,   4, 199,  35, 195,  24, 150,   5, 154,
   2912        	  7,  18, 128, 226, 235,  39, 178, 117,   9, 131,  44,  26,  27, 110,
   2913 	 90, 160,  82,  59, 214, 179,  41, 227,  47, 132,  83, 209,   0, 237,
   2914        	 32, 252, 177,  91, 106, 203, 190,  57,  74,  76,  88, 207, 208, 239,
   2915 	170, 251,  67,  77,  51, 133,  69, 249,   2, 127,  80,  60, 159, 168,
   2916 	 81, 163,  64, 143, 146, 157,  56, 245, 188, 182, 218,  33,  16, 255,
   2917 	243, 210, 205,  12,  19, 236,  95, 151,  68,  23, 196, 167, 126,  61,
   2918        	100,  93,  25, 115,  96, 129,  79, 220,  34,  42, 144, 136,  70, 238,
   2919        	184,  20, 222,  94,  11, 219, 224,  50,  58,  10,  73,   6,  36,  92,
   2920        	194, 211, 172,  98, 145, 149, 228, 121, 231, 200,  55, 109, 141, 213,
   2921       	 78, 169, 108,  86, 244, 234, 101, 122, 174,   8, 186, 120,  37,  46,
   2922        	 28, 166, 180, 198, 232, 221, 116,  31,  75, 189, 139, 138, 112,  62,
   2923 	181, 102,  72,   3, 246,  14,  97,  53,  87, 185, 134, 193,  29, 158,
   2924        	225, 248, 152,  17, 105, 217, 142, 148, 155,  30, 135, 233, 206,  85,
   2925       	 40, 223, 140, 161, 137,  13, 191, 230,  66, 104,  65, 153,  45,  15,
   2926 	176,  84, 187,  22
   2927 };
   2928 
   2929 static uint32_t AES_RCON[30] = {
   2930 	0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8,
   2931        	0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4,
   2932        	0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91
   2933 };
   2934 
   2935 STATIC int
   2936 mv_aes_ksched(uint8_t k[4][MAXKC], int keyBits,
   2937     uint8_t W[MAXROUNDS+1][4][MAXBC])
   2938 {
   2939 	int KC, BC, ROUNDS;
   2940 	int i, j, t, rconpointer = 0;
   2941 	uint8_t tk[4][MAXKC];
   2942 
   2943 	switch (keyBits) {
   2944 	case 128:
   2945 		ROUNDS = 10;
   2946 		KC = 4;
   2947 		break;
   2948 	case 192:
   2949 		ROUNDS = 12;
   2950 		KC = 6;
   2951 	       	break;
   2952 	case 256:
   2953 		ROUNDS = 14;
   2954 	       	KC = 8;
   2955 	       	break;
   2956 	default:
   2957 	       	return (-1);
   2958 	}
   2959 	BC = 4; /* 128 bits */
   2960 
   2961 	for(j = 0; j < KC; j++)
   2962 		for(i = 0; i < 4; i++)
   2963 			tk[i][j] = k[i][j];
   2964 	t = 0;
   2965 
   2966 	/* copy values into round key array */
   2967 	for(j = 0; (j < KC) && (t < (ROUNDS+1)*BC); j++, t++)
   2968 		for(i = 0; i < 4; i++) W[t / BC][i][t % BC] = tk[i][j];
   2969 
   2970 	while (t < (ROUNDS+1)*BC) { /* while not enough round key material calculated */
   2971 		/* calculate new values */
   2972 		for(i = 0; i < 4; i++)
   2973 			tk[i][0] ^= AES_SBOX[tk[(i+1)%4][KC-1]];
   2974 		tk[0][0] ^= AES_RCON[rconpointer++];
   2975 
   2976 		if (KC != 8)
   2977 			for(j = 1; j < KC; j++)
   2978 				for(i = 0; i < 4; i++)
   2979 				       	tk[i][j] ^= tk[i][j-1];
   2980 		else {
   2981 			for(j = 1; j < KC/2; j++)
   2982 				for(i = 0; i < 4; i++)
   2983 				       	tk[i][j] ^= tk[i][j-1];
   2984 			for(i = 0; i < 4; i++)
   2985 			       	tk[i][KC/2] ^= AES_SBOX[tk[i][KC/2 - 1]];
   2986 			for(j = KC/2 + 1; j < KC; j++)
   2987 				for(i = 0; i < 4; i++)
   2988 				       	tk[i][j] ^= tk[i][j-1];
   2989 	}
   2990 	/* copy values into round key array */
   2991 	for(j = 0; (j < KC) && (t < (ROUNDS+1)*BC); j++, t++)
   2992 		for(i = 0; i < 4; i++) W[t / BC][i][t % BC] = tk[i][j];
   2993 	}
   2994 
   2995 	return 0;
   2996 }
   2997 
   2998 STATIC int
   2999 mv_aes_deckey(uint8_t *expandedKey, uint8_t *keyMaterial, int keyLen)
   3000 {
   3001 	uint8_t   W[MAXROUNDS+1][4][MAXBC];
   3002 	uint8_t   k[4][MAXKC];
   3003 	uint8_t   j;
   3004 	int     i, rounds, KC;
   3005 
   3006 	if (expandedKey == NULL)
   3007 		return -1;
   3008 
   3009 	if (!((keyLen == 128) || (keyLen == 192) || (keyLen == 256)))
   3010 		return -1;
   3011 
   3012 	if (keyMaterial == NULL)
   3013 		return -1;
   3014 
   3015 	/* initialize key schedule: */
   3016 	for (i=0; i<keyLen/8; i++) {
   3017 		j = keyMaterial[i];
   3018 		k[i % 4][i / 4] = j;
   3019 	}
   3020 
   3021 	mv_aes_ksched(k, keyLen, W);
   3022 	switch (keyLen) {
   3023 	case 128:
   3024 		rounds = 10;
   3025 		KC = 4;
   3026 		break;
   3027 	case 192:
   3028 		rounds = 12;
   3029 		KC = 6;
   3030 		break;
   3031 	case 256:
   3032 		rounds = 14;
   3033 		KC = 8;
   3034 		break;
   3035 	default:
   3036 		return -1;
   3037 	}
   3038 
   3039 	for(i=0; i<MAXBC; i++)
   3040 		for(j=0; j<4; j++)
   3041 			expandedKey[i*4+j] = W[rounds][j][i];
   3042 	for(; i<KC; i++)
   3043 		for(j=0; j<4; j++)
   3044 			expandedKey[i*4+j] = W[rounds-1][j][i+MAXBC-KC];
   3045 
   3046 	return 0;
   3047 }
   3048 
   3049 /*
   3050  * Clear cipher/mac operation state
   3051  */
   3052 INLINE void
   3053 mvxpsec_packet_reset_op(struct mvxpsec_packet *mv_p)
   3054 {
   3055 	mv_p->pkt_header.desc.acc_config = 0;
   3056 	mv_p->enc_off = mv_p->enc_ivoff = mv_p->enc_len = 0;
   3057 	mv_p->mac_off = mv_p->mac_dst = mv_p->mac_len = 0;
   3058 }
   3059 
   3060 /*
   3061  * update MVXPSEC operation order
   3062  */
   3063 INLINE void
   3064 mvxpsec_packet_update_op_order(struct mvxpsec_packet *mv_p, int op)
   3065 {
   3066 	struct mvxpsec_acc_descriptor *acc_desc = &mv_p->pkt_header.desc;
   3067 	uint32_t cur_op = acc_desc->acc_config & MV_ACC_CRYPTO_OP_MASK;
   3068 
   3069 	KASSERT(op == MV_ACC_CRYPTO_OP_MAC || op == MV_ACC_CRYPTO_OP_ENC);
   3070 	KASSERT((op & MV_ACC_CRYPTO_OP_MASK) == op);
   3071 
   3072 	if (cur_op == 0)
   3073 		acc_desc->acc_config |= op;
   3074 	else if (cur_op == MV_ACC_CRYPTO_OP_MAC && op == MV_ACC_CRYPTO_OP_ENC) {
   3075 		acc_desc->acc_config &= ~MV_ACC_CRYPTO_OP_MASK;
   3076 		acc_desc->acc_config |= MV_ACC_CRYPTO_OP_MACENC;
   3077 		/* MAC then ENC (= decryption) */
   3078 	}
   3079 	else if (cur_op == MV_ACC_CRYPTO_OP_ENC && op == MV_ACC_CRYPTO_OP_MAC) {
   3080 		acc_desc->acc_config &= ~MV_ACC_CRYPTO_OP_MASK;
   3081 		acc_desc->acc_config |= MV_ACC_CRYPTO_OP_ENCMAC;
   3082 		/* ENC then MAC (= encryption) */
   3083 	}
   3084 	else {
   3085 		log(LOG_ERR, "%s: multiple %s algorithm is not supported.\n",
   3086 		    __func__,
   3087 		    (op == MV_ACC_CRYPTO_OP_ENC) ?  "encryption" : "authentication");
   3088 	}
   3089 }
   3090 
   3091 /*
   3092  * Parameter Conversions
   3093  */
   3094 INLINE uint32_t
   3095 mvxpsec_alg2acc(uint32_t alg)
   3096 {
   3097 	uint32_t reg;
   3098 
   3099 	switch (alg) {
   3100 	case CRYPTO_DES_CBC:
   3101 		reg = MV_ACC_CRYPTO_ENC_DES;
   3102 		reg |= MV_ACC_CRYPTO_CBC;
   3103 		break;
   3104 	case CRYPTO_3DES_CBC:
   3105 		reg = MV_ACC_CRYPTO_ENC_3DES;
   3106 		reg |= MV_ACC_CRYPTO_3DES_EDE;
   3107 		reg |= MV_ACC_CRYPTO_CBC;
   3108 		break;
   3109 	case CRYPTO_AES_CBC:
   3110 		reg = MV_ACC_CRYPTO_ENC_AES;
   3111 		reg |= MV_ACC_CRYPTO_CBC;
   3112 		break;
   3113 	case CRYPTO_SHA1_HMAC_96:
   3114 		reg = MV_ACC_CRYPTO_MAC_HMAC_SHA1;
   3115 		reg |= MV_ACC_CRYPTO_MAC_96;
   3116 		break;
   3117 	case CRYPTO_MD5_HMAC_96:
   3118 		reg = MV_ACC_CRYPTO_MAC_HMAC_MD5;
   3119 		reg |= MV_ACC_CRYPTO_MAC_96;
   3120 		break;
   3121 	default:
   3122 		reg = 0;
   3123 		break;
   3124 	}
   3125 
   3126 	return reg;
   3127 }
   3128 
   3129 INLINE uint32_t
   3130 mvxpsec_aesklen(int klen)
   3131 {
   3132 	if (klen < 128)
   3133 		return 0;
   3134 	else if (klen < 192)
   3135 		return MV_ACC_CRYPTO_AES_KLEN_128;
   3136 	else if (klen < 256)
   3137 		return MV_ACC_CRYPTO_AES_KLEN_192;
   3138 	else
   3139 		return MV_ACC_CRYPTO_AES_KLEN_256;
   3140 
   3141 	return 0;
   3142 }
   3143 
   3144 /*
   3145  * String Conversions
   3146  */
   3147 STATIC const char *
   3148 s_errreg(uint32_t v)
   3149 {
   3150 	static char buf[80];
   3151 
   3152 	snprintf(buf, sizeof(buf),
   3153 	    "%sMiss %sDoubleHit %sBothHit %sDataError",
   3154 	    (v & MV_TDMA_ERRC_MISS) ? "+" : "-",
   3155 	    (v & MV_TDMA_ERRC_DHIT) ? "+" : "-",
   3156 	    (v & MV_TDMA_ERRC_BHIT) ? "+" : "-",
   3157 	    (v & MV_TDMA_ERRC_DERR) ? "+" : "-");
   3158 
   3159 	return (const char *)buf;
   3160 }
   3161 
   3162 STATIC const char *
   3163 s_winreg(uint32_t v)
   3164 {
   3165 	static char buf[80];
   3166 
   3167 	snprintf(buf, sizeof(buf),
   3168 	    "%s TGT 0x%x ATTR 0x%02x size %u(0x%04x)[64KB]",
   3169 	    (v & MV_TDMA_ATTR_ENABLE) ? "EN" : "DIS",
   3170 	    MV_TDMA_ATTR_GET_TARGET(v), MV_TDMA_ATTR_GET_ATTR(v),
   3171 	    MV_TDMA_ATTR_GET_SIZE(v), MV_TDMA_ATTR_GET_SIZE(v));
   3172 
   3173 	return (const char *)buf;
   3174 }
   3175 
   3176 STATIC const char *
   3177 s_ctrlreg(uint32_t reg)
   3178 {
   3179 	static char buf[80];
   3180 
   3181 	snprintf(buf, sizeof(buf),
   3182 	    "%s: %sFETCH DBURST-%u SBURST-%u %sOUTS %sCHAIN %sBSWAP %sACT",
   3183 	    (reg & MV_TDMA_CONTROL_ENABLE) ? "ENABLE" : "DISABLE",
   3184 	    (reg & MV_TDMA_CONTROL_FETCH) ? "+" : "-",
   3185 	    MV_TDMA_CONTROL_GET_DST_BURST(reg),
   3186 	    MV_TDMA_CONTROL_GET_SRC_BURST(reg),
   3187 	    (reg & MV_TDMA_CONTROL_OUTS_EN) ? "+" : "-",
   3188 	    (reg & MV_TDMA_CONTROL_CHAIN_DIS) ? "-" : "+",
   3189 	    (reg & MV_TDMA_CONTROL_BSWAP_DIS) ? "-" : "+",
   3190 	    (reg & MV_TDMA_CONTROL_ACT) ? "+" : "-");
   3191 
   3192 	return (const char *)buf;
   3193 }
   3194 
   3195 _STATIC const char *
   3196 s_xpsecintr(uint32_t v)
   3197 {
   3198 	static char buf[160];
   3199 
   3200 	snprintf(buf, sizeof(buf),
   3201 	    "%sAuth %sDES %sAES-ENC %sAES-DEC %sENC %sSA %sAccAndTDMA "
   3202 	    "%sTDMAComp %sTDMAOwn %sAccAndTDMA_Cont",
   3203 	    (v & MVXPSEC_INT_AUTH) ? "+" : "-",
   3204 	    (v & MVXPSEC_INT_DES) ? "+" : "-",
   3205 	    (v & MVXPSEC_INT_AES_ENC) ? "+" : "-",
   3206 	    (v & MVXPSEC_INT_AES_DEC) ? "+" : "-",
   3207 	    (v & MVXPSEC_INT_ENC) ? "+" : "-",
   3208 	    (v & MVXPSEC_INT_SA) ? "+" : "-",
   3209 	    (v & MVXPSEC_INT_ACCTDMA) ? "+" : "-",
   3210 	    (v & MVXPSEC_INT_TDMA_COMP) ? "+" : "-",
   3211 	    (v & MVXPSEC_INT_TDMA_OWN) ? "+" : "-",
   3212 	    (v & MVXPSEC_INT_ACCTDMA_CONT) ? "+" : "-");
   3213 
   3214 	return (const char *)buf;
   3215 }
   3216 
   3217 STATIC const char *
   3218 s_ctlalg(uint32_t alg)
   3219 {
   3220 	switch (alg) {
   3221 	case CRYPTO_SHA1_HMAC_96:
   3222 		return "HMAC-SHA1-96";
   3223 	case CRYPTO_SHA1_HMAC:
   3224 		return "HMAC-SHA1";
   3225 	case CRYPTO_SHA1:
   3226 		return "SHA1";
   3227 	case CRYPTO_MD5_HMAC_96:
   3228 		return "HMAC-MD5-96";
   3229 	case CRYPTO_MD5_HMAC:
   3230 		return "HMAC-MD5";
   3231 	case CRYPTO_MD5:
   3232 		return "MD5";
   3233 	case CRYPTO_DES_CBC:
   3234 		return "DES-CBC";
   3235 	case CRYPTO_3DES_CBC:
   3236 		return "3DES-CBC";
   3237 	case CRYPTO_AES_CBC:
   3238 		return "AES-CBC";
   3239 	default:
   3240 		break;
   3241 	}
   3242 
   3243 	return "Unknown";
   3244 }
   3245 
   3246 STATIC const char *
   3247 s_xpsec_op(uint32_t reg)
   3248 {
   3249 	reg &= MV_ACC_CRYPTO_OP_MASK;
   3250 	switch (reg) {
   3251 	case MV_ACC_CRYPTO_OP_ENC:
   3252 		return "ENC";
   3253 	case MV_ACC_CRYPTO_OP_MAC:
   3254 		return "MAC";
   3255 	case MV_ACC_CRYPTO_OP_ENCMAC:
   3256 		return "ENC-MAC";
   3257 	case MV_ACC_CRYPTO_OP_MACENC:
   3258 		return "MAC-ENC";
   3259 	default:
   3260 		break;
   3261 	}
   3262 
   3263 	return "Unknown";
   3264 
   3265 }
   3266 
   3267 STATIC const char *
   3268 s_xpsec_enc(uint32_t alg)
   3269 {
   3270 	alg <<= MV_ACC_CRYPTO_ENC_SHIFT;
   3271 	switch (alg) {
   3272 	case MV_ACC_CRYPTO_ENC_DES:
   3273 		return "DES";
   3274 	case MV_ACC_CRYPTO_ENC_3DES:
   3275 		return "3DES";
   3276 	case MV_ACC_CRYPTO_ENC_AES:
   3277 		return "AES";
   3278 	default:
   3279 		break;
   3280 	}
   3281 
   3282 	return "Unknown";
   3283 }
   3284 
   3285 STATIC const char *
   3286 s_xpsec_mac(uint32_t alg)
   3287 {
   3288 	alg <<= MV_ACC_CRYPTO_MAC_SHIFT;
   3289 	switch (alg) {
   3290 	case MV_ACC_CRYPTO_MAC_NONE:
   3291 		return "Disabled";
   3292 	case MV_ACC_CRYPTO_MAC_MD5:
   3293 		return "MD5";
   3294 	case MV_ACC_CRYPTO_MAC_SHA1:
   3295 		return "SHA1";
   3296 	case MV_ACC_CRYPTO_MAC_HMAC_MD5:
   3297 		return "HMAC-MD5";
   3298 	case MV_ACC_CRYPTO_MAC_HMAC_SHA1:
   3299 		return "HMAC-SHA1";
   3300 	default:
   3301 		break;
   3302 	}
   3303 
   3304 	return "Unknown";
   3305 }
   3306 
   3307 STATIC const char *
   3308 s_xpsec_frag(uint32_t frag)
   3309 {
   3310 	frag <<= MV_ACC_CRYPTO_FRAG_SHIFT;
   3311 	switch (frag) {
   3312 	case MV_ACC_CRYPTO_NOFRAG:
   3313 		return "NoFragment";
   3314 	case MV_ACC_CRYPTO_FRAG_FIRST:
   3315 		return "FirstFragment";
   3316 	case MV_ACC_CRYPTO_FRAG_MID:
   3317 		return "MiddleFragment";
   3318 	case MV_ACC_CRYPTO_FRAG_LAST:
   3319 		return "LastFragment";
   3320 	default:
   3321 		break;
   3322 	}
   3323 
   3324 	return "Unknown";
   3325 }
   3326 
   3327 #ifdef MVXPSEC_DEBUG
   3328 void
   3329 mvxpsec_dump_reg(struct mvxpsec_softc *sc)
   3330 {
   3331 	uint32_t reg;
   3332 	int i;
   3333 
   3334 	if ((mvxpsec_debug & MVXPSEC_DEBUG_DESC) == 0)
   3335 		return;
   3336 
   3337 	printf("--- Interrupt Registers ---\n");
   3338 	reg = MVXPSEC_READ(sc, MVXPSEC_INT_CAUSE);
   3339 	printf("MVXPSEC INT CAUSE: 0x%08x\n", reg);
   3340 	printf("MVXPSEC INT CAUSE: %s\n", s_xpsecintr(reg));
   3341 	reg = MVXPSEC_READ(sc, MVXPSEC_INT_MASK);
   3342 	printf("MVXPSEC INT MASK: 0x%08x\n", reg);
   3343 	printf("MVXPSEC INT MASKE: %s\n", s_xpsecintr(reg));
   3344 
   3345 	printf("--- DMA Configuration Registers ---\n");
   3346 	for (i = 0; i < MV_TDMA_NWINDOW; i++) {
   3347 		reg = MVXPSEC_READ(sc, MV_TDMA_BAR(i));
   3348 		printf("TDMA BAR%d: 0x%08x\n", i, reg);
   3349 		reg = MVXPSEC_READ(sc, MV_TDMA_ATTR(i));
   3350 		printf("TDMA ATTR%d: 0x%08x\n", i, reg);
   3351 		printf("  -> %s\n", s_winreg(reg));
   3352 	}
   3353 
   3354 	printf("--- DMA Control Registers ---\n");
   3355 
   3356 	reg = MVXPSEC_READ(sc, MV_TDMA_CONTROL);
   3357 	printf("TDMA CONTROL: 0x%08x\n", reg);
   3358 	printf("  -> %s\n", s_ctrlreg(reg));
   3359 
   3360 	printf("--- DMA Current Command Descriptors ---\n");
   3361 
   3362 	reg = MVXPSEC_READ(sc, MV_TDMA_ERR_CAUSE);
   3363 	printf("TDMA ERR CAUSE: 0x%08x\n", reg);
   3364 
   3365 	reg = MVXPSEC_READ(sc, MV_TDMA_ERR_MASK);
   3366 	printf("TDMA ERR MASK: 0x%08x\n", reg);
   3367 
   3368 	reg = MVXPSEC_READ(sc, MV_TDMA_CNT);
   3369 	printf("TDMA DATA OWNER: %s\n",
   3370 	    (reg & MV_TDMA_CNT_OWN) ? "DMAC" : "CPU");
   3371 	printf("TDMA DATA COUNT: %d(0x%x)\n",
   3372 	    (reg & ~MV_TDMA_CNT_OWN), (reg & ~MV_TDMA_CNT_OWN));
   3373 
   3374 	reg = MVXPSEC_READ(sc, MV_TDMA_SRC);
   3375 	printf("TDMA DATA SRC: 0x%08x\n", reg);
   3376 
   3377 	reg = MVXPSEC_READ(sc, MV_TDMA_DST);
   3378 	printf("TDMA DATA DST: 0x%08x\n", reg);
   3379 
   3380 	reg = MVXPSEC_READ(sc, MV_TDMA_NXT);
   3381 	printf("TDMA DATA NXT: 0x%08x\n", reg);
   3382 
   3383 	reg = MVXPSEC_READ(sc, MV_TDMA_CUR);
   3384 	printf("TDMA DATA CUR: 0x%08x\n", reg);
   3385 
   3386 	printf("--- ACC Command Register ---\n");
   3387 	reg = MVXPSEC_READ(sc, MV_ACC_COMMAND);
   3388 	printf("ACC COMMAND: 0x%08x\n", reg);
   3389 	printf("ACC: %sACT %sSTOP\n",
   3390 	    (reg & MV_ACC_COMMAND_ACT) ? "+" : "-",
   3391 	    (reg & MV_ACC_COMMAND_STOP) ? "+" : "-");
   3392 
   3393 	reg = MVXPSEC_READ(sc, MV_ACC_CONFIG);
   3394 	printf("ACC CONFIG: 0x%08x\n", reg);
   3395 	reg = MVXPSEC_READ(sc, MV_ACC_DESC);
   3396 	printf("ACC DESC: 0x%08x\n", reg);
   3397 
   3398 	printf("--- DES Key Register ---\n");
   3399 	reg = MVXPSEC_READ(sc, MV_CE_DES_KEY0L);
   3400 	printf("DES KEY0  Low: 0x%08x\n", reg);
   3401 	reg = MVXPSEC_READ(sc, MV_CE_DES_KEY0H);
   3402 	printf("DES KEY0 High: 0x%08x\n", reg);
   3403 	reg = MVXPSEC_READ(sc, MV_CE_DES_KEY1L);
   3404 	printf("DES KEY1  Low: 0x%08x\n", reg);
   3405 	reg = MVXPSEC_READ(sc, MV_CE_DES_KEY1H);
   3406 	printf("DES KEY1 High: 0x%08x\n", reg);
   3407 	reg = MVXPSEC_READ(sc, MV_CE_DES_KEY2L);
   3408 	printf("DES KEY2  Low: 0x%08x\n", reg);
   3409 	reg = MVXPSEC_READ(sc, MV_CE_DES_KEY2H);
   3410 	printf("DES KEY2 High: 0x%08x\n", reg);
   3411 
   3412 	printf("--- AES Key Register ---\n");
   3413 	for (i = 0; i < 8; i++) {
   3414 		reg = MVXPSEC_READ(sc, MV_CE_AES_EKEY(i));
   3415 		printf("AES ENC KEY COL%d: %08x\n", i, reg);
   3416 	}
   3417 	for (i = 0; i < 8; i++) {
   3418 		reg = MVXPSEC_READ(sc, MV_CE_AES_DKEY(i));
   3419 		printf("AES DEC KEY COL%d: %08x\n", i, reg);
   3420 	}
   3421 
   3422 	return;
   3423 }
   3424 
   3425 STATIC void
   3426 mvxpsec_dump_sram(const char *name, struct mvxpsec_softc *sc, size_t len)
   3427 {
   3428 	uint32_t reg;
   3429 
   3430 	if (sc->sc_sram_va == NULL)
   3431 		return;
   3432 
   3433 	if (len == 0) {
   3434 		printf("\n%s NO DATA(len=0)\n", name);
   3435 		return;
   3436 	}
   3437 	else if (len > MV_ACC_SRAM_SIZE)
   3438 		len = MV_ACC_SRAM_SIZE;
   3439 
   3440 	mutex_enter(&sc->sc_dma_mtx);
   3441 	reg = MVXPSEC_READ(sc, MV_TDMA_CONTROL);
   3442 	if (reg & MV_TDMA_CONTROL_ACT) {
   3443 		printf("TDMA is active, cannot access SRAM\n");
   3444 		mutex_exit(&sc->sc_dma_mtx);
   3445 		return;
   3446 	}
   3447 	reg = MVXPSEC_READ(sc, MV_ACC_COMMAND);
   3448 	if (reg & MV_ACC_COMMAND_ACT) {
   3449 		printf("SA is active, cannot access SRAM\n");
   3450 		mutex_exit(&sc->sc_dma_mtx);
   3451 		return;
   3452 	}
   3453 
   3454 	printf("%s: dump SRAM, %zu bytes\n", name, len);
   3455 	mvxpsec_dump_data(name, sc->sc_sram_va, len);
   3456 	mutex_exit(&sc->sc_dma_mtx);
   3457 	return;
   3458 }
   3459 
   3460 
   3461 _STATIC void
   3462 mvxpsec_dump_dmaq(struct mvxpsec_descriptor_handle *dh)
   3463 {
   3464 	struct mvxpsec_descriptor *d =
   3465            (struct mvxpsec_descriptor *)dh->_desc;
   3466 
   3467 	printf("--- DMA Command Descriptor ---\n");
   3468 	printf("DESC: VA=%p PA=0x%08x\n",
   3469 	    d, (uint32_t)dh->phys_addr);
   3470 	printf("DESC: WORD0 = 0x%08x\n", d->tdma_word0);
   3471 	printf("DESC: SRC = 0x%08x\n", d->tdma_src);
   3472 	printf("DESC: DST = 0x%08x\n", d->tdma_dst);
   3473 	printf("DESC: NXT = 0x%08x\n", d->tdma_nxt);
   3474 
   3475 	return;
   3476 }
   3477 
   3478 STATIC void
   3479 mvxpsec_dump_data(const char *name, void *p, size_t len)
   3480 {
   3481 	uint8_t *data = p;
   3482 	off_t off;
   3483 
   3484 	printf("%s: dump %p, %zu bytes", name, p, len);
   3485 	if (p == NULL || len == 0) {
   3486 		printf("\n%s: NO DATA\n", name);
   3487 		return;
   3488 	}
   3489 	for (off = 0; off < len; off++) {
   3490 		if ((off % 16) == 0) {
   3491 			printf("\n%s: 0x%08x:", name, (uint32_t)off);
   3492 		}
   3493 		if ((off % 4) == 0) {
   3494 			printf(" ");
   3495 		}
   3496 		printf("%02x", data[off]);
   3497 	}
   3498 	printf("\n");
   3499 
   3500 	return;
   3501 }
   3502 
   3503 _STATIC void
   3504 mvxpsec_dump_packet(const char *name, struct mvxpsec_packet *mv_p)
   3505 {
   3506 	struct mvxpsec_softc *sc = mv_p->mv_s->sc;
   3507 
   3508 	printf("%s: packet_data:\n", name);
   3509 	mvxpsec_dump_packet_data(name, mv_p);
   3510 
   3511 	printf("%s: SRAM:\n", name);
   3512 	mvxpsec_dump_sram(name, sc, 2000);
   3513 
   3514 	printf("%s: packet_descriptor:\n", name);
   3515 	mvxpsec_dump_packet_desc(name, mv_p);
   3516 }
   3517 
   3518 _STATIC void
   3519 mvxpsec_dump_packet_data(const char *name, struct mvxpsec_packet *mv_p)
   3520 {
   3521 	static char buf[1500];
   3522 	int len;
   3523 
   3524 	if (mv_p->data_type == MVXPSEC_DATA_MBUF) {
   3525 		struct mbuf *m;
   3526 
   3527 		m = mv_p->data.mbuf;
   3528 		len = m->m_pkthdr.len;
   3529 		if (len > sizeof(buf))
   3530 			len = sizeof(buf);
   3531 		m_copydata(m, 0, len, buf);
   3532 	}
   3533 	else if (mv_p->data_type == MVXPSEC_DATA_UIO) {
   3534 		struct uio *uio;
   3535 
   3536 		uio = mv_p->data.uio;
   3537 		len = uio->uio_resid;
   3538 		if (len > sizeof(buf))
   3539 			len = sizeof(buf);
   3540 		cuio_copydata(uio, 0, len, buf);
   3541 	}
   3542 	else if (mv_p->data_type == MVXPSEC_DATA_RAW) {
   3543 		len = mv_p->data_len;
   3544 		if (len > sizeof(buf))
   3545 			len = sizeof(buf);
   3546 		memcpy(buf, mv_p->data.raw, len);
   3547 	}
   3548 	else
   3549 		return;
   3550 	mvxpsec_dump_data(name, buf, len);
   3551 
   3552 	return;
   3553 }
   3554 
   3555 _STATIC void
   3556 mvxpsec_dump_packet_desc(const char *name, struct mvxpsec_packet *mv_p)
   3557 {
   3558 	uint32_t *words;
   3559 
   3560 	if (mv_p == NULL)
   3561 		return;
   3562 
   3563 	words = &mv_p->pkt_header.desc.acc_desc_dword0;
   3564 	mvxpsec_dump_acc_config(name, words[0]);
   3565 	mvxpsec_dump_acc_encdata(name, words[1], words[2]);
   3566 	mvxpsec_dump_acc_enclen(name, words[2]);
   3567 	mvxpsec_dump_acc_enckey(name, words[3]);
   3568 	mvxpsec_dump_acc_enciv(name, words[4]);
   3569 	mvxpsec_dump_acc_macsrc(name, words[5]);
   3570 	mvxpsec_dump_acc_macdst(name, words[6]);
   3571 	mvxpsec_dump_acc_maciv(name, words[7]);
   3572 
   3573 	return;
   3574 }
   3575 
   3576 _STATIC void
   3577 mvxpsec_dump_acc_config(const char *name, uint32_t w)
   3578 {
   3579 	/* SA: Dword 0 */
   3580 	printf("%s: Dword0=0x%08x\n", name, w);
   3581 	printf("%s:   OP = %s\n", name,
   3582 	    s_xpsec_op(MV_ACC_CRYPTO_OP(w)));
   3583 	printf("%s:   MAC = %s\n", name,
   3584 	    s_xpsec_mac(MV_ACC_CRYPTO_MAC(w)));
   3585 	printf("%s:   MAC_LEN = %s\n", name,
   3586 	    w & MV_ACC_CRYPTO_MAC_96 ? "96-bit" : "full-bit");
   3587 	printf("%s:   ENC = %s\n", name,
   3588 	    s_xpsec_enc(MV_ACC_CRYPTO_ENC(w)));
   3589 	printf("%s:   DIR = %s\n", name,
   3590 	    w & MV_ACC_CRYPTO_DECRYPT ? "decryption" : "encryption");
   3591 	printf("%s:   CHAIN = %s\n", name,
   3592 	    w & MV_ACC_CRYPTO_CBC ? "CBC" : "ECB");
   3593 	printf("%s:   3DES = %s\n", name,
   3594 	    w & MV_ACC_CRYPTO_3DES_EDE ? "EDE" : "EEE");
   3595 	printf("%s:   FRAGMENT = %s\n", name,
   3596 	    s_xpsec_frag(MV_ACC_CRYPTO_FRAG(w)));
   3597 	return;
   3598 }
   3599 
   3600 STATIC void
   3601 mvxpsec_dump_acc_encdata(const char *name, uint32_t w, uint32_t w2)
   3602 {
   3603 	/* SA: Dword 1 */
   3604 	printf("%s: Dword1=0x%08x\n", name, w);
   3605 	printf("%s:   ENC SRC = 0x%x\n", name, MV_ACC_DESC_GET_VAL_1(w));
   3606 	printf("%s:   ENC DST = 0x%x\n", name, MV_ACC_DESC_GET_VAL_2(w));
   3607 	printf("%s:   ENC RANGE = 0x%x - 0x%x\n", name,
   3608 	    MV_ACC_DESC_GET_VAL_1(w),
   3609 	    MV_ACC_DESC_GET_VAL_1(w) + MV_ACC_DESC_GET_VAL_1(w2) - 1);
   3610 	return;
   3611 }
   3612 
   3613 STATIC void
   3614 mvxpsec_dump_acc_enclen(const char *name, uint32_t w)
   3615 {
   3616 	/* SA: Dword 2 */
   3617 	printf("%s: Dword2=0x%08x\n", name, w);
   3618 	printf("%s:   ENC LEN = %d\n", name,
   3619 	    MV_ACC_DESC_GET_VAL_1(w));
   3620 	return;
   3621 }
   3622 
   3623 STATIC void
   3624 mvxpsec_dump_acc_enckey(const char *name, uint32_t w)
   3625 {
   3626 	/* SA: Dword 3 */
   3627 	printf("%s: Dword3=0x%08x\n", name, w);
   3628 	printf("%s:   EKEY = 0x%x\n", name,
   3629 	    MV_ACC_DESC_GET_VAL_1(w));
   3630 	return;
   3631 }
   3632 
   3633 STATIC void
   3634 mvxpsec_dump_acc_enciv(const char *name, uint32_t w)
   3635 {
   3636 	/* SA: Dword 4 */
   3637 	printf("%s: Dword4=0x%08x\n", name, w);
   3638 	printf("%s:   EIV = 0x%x\n", name, MV_ACC_DESC_GET_VAL_1(w));
   3639 	printf("%s:   EIV_BUF = 0x%x\n", name, MV_ACC_DESC_GET_VAL_2(w));
   3640 	return;
   3641 }
   3642 
   3643 STATIC void
   3644 mvxpsec_dump_acc_macsrc(const char *name, uint32_t w)
   3645 {
   3646 	/* SA: Dword 5 */
   3647 	printf("%s: Dword5=0x%08x\n", name, w);
   3648 	printf("%s:   MAC_SRC = 0x%x\n", name,
   3649 	    MV_ACC_DESC_GET_VAL_1(w));
   3650 	printf("%s:   MAC_TOTAL_LEN = %d\n", name,
   3651 	    MV_ACC_DESC_GET_VAL_3(w));
   3652 	printf("%s:   MAC_RANGE = 0x%0x - 0x%0x\n", name,
   3653 	    MV_ACC_DESC_GET_VAL_1(w),
   3654 	    MV_ACC_DESC_GET_VAL_1(w) + MV_ACC_DESC_GET_VAL_3(w) - 1);
   3655 	return;
   3656 }
   3657 
   3658 STATIC void
   3659 mvxpsec_dump_acc_macdst(const char *name, uint32_t w)
   3660 {
   3661 	/* SA: Dword 6 */
   3662 	printf("%s: Dword6=0x%08x\n", name, w);
   3663 	printf("%s:   MAC_DST = 0x%x\n", name, MV_ACC_DESC_GET_VAL_1(w));
   3664 	printf("%s:   MAC_BLOCK_LEN = %d\n", name,
   3665 	    MV_ACC_DESC_GET_VAL_2(w));
   3666 	return;
   3667 }
   3668 
   3669 STATIC void
   3670 mvxpsec_dump_acc_maciv(const char *name, uint32_t w)
   3671 {
   3672 	/* SA: Dword 7 */
   3673 	printf("%s: Dword7=0x%08x\n", name, w);
   3674 	printf("%s:   MAC_INNER_IV = 0x%x\n", name,
   3675 	    MV_ACC_DESC_GET_VAL_1(w));
   3676 	printf("%s:   MAC_OUTER_IV = 0x%x\n", name,
   3677 	    MV_ACC_DESC_GET_VAL_2(w));
   3678 	return;
   3679 }
   3680 #endif
   3681