1844d9543SConrad Meyer /*- 2844d9543SConrad Meyer * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 3844d9543SConrad Meyer * 4844d9543SConrad Meyer * Copyright (c) 2017 Chelsio Communications, Inc. 5844d9543SConrad Meyer * Copyright (c) 2017 Conrad Meyer <cem@FreeBSD.org> 6844d9543SConrad Meyer * All rights reserved. 7844d9543SConrad Meyer * Largely borrowed from ccr(4), Written by: John Baldwin <jhb@FreeBSD.org> 8844d9543SConrad Meyer * 9844d9543SConrad Meyer * Redistribution and use in source and binary forms, with or without 10844d9543SConrad Meyer * modification, are permitted provided that the following conditions 11844d9543SConrad Meyer * are met: 12844d9543SConrad Meyer * 1. Redistributions of source code must retain the above copyright 13844d9543SConrad Meyer * notice, this list of conditions and the following disclaimer. 14844d9543SConrad Meyer * 2. Redistributions in binary form must reproduce the above copyright 15844d9543SConrad Meyer * notice, this list of conditions and the following disclaimer in the 16844d9543SConrad Meyer * documentation and/or other materials provided with the distribution. 17844d9543SConrad Meyer * 18844d9543SConrad Meyer * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 19844d9543SConrad Meyer * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20844d9543SConrad Meyer * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21844d9543SConrad Meyer * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 22844d9543SConrad Meyer * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23844d9543SConrad Meyer * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24844d9543SConrad Meyer * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25844d9543SConrad Meyer * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26844d9543SConrad Meyer * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27844d9543SConrad Meyer * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28844d9543SConrad Meyer * SUCH DAMAGE. 29844d9543SConrad Meyer */ 30844d9543SConrad Meyer 31844d9543SConrad Meyer #include <sys/cdefs.h> 32844d9543SConrad Meyer __FBSDID("$FreeBSD$"); 33844d9543SConrad Meyer 34844d9543SConrad Meyer #include "opt_ddb.h" 35844d9543SConrad Meyer 36e2e050c8SConrad Meyer #include <sys/param.h> 37844d9543SConrad Meyer #include <sys/bus.h> 38844d9543SConrad Meyer #include <sys/lock.h> 39844d9543SConrad Meyer #include <sys/kernel.h> 40844d9543SConrad Meyer #include <sys/malloc.h> 41844d9543SConrad Meyer #include <sys/mutex.h> 42844d9543SConrad Meyer #include <sys/module.h> 43844d9543SConrad Meyer #include <sys/random.h> 44844d9543SConrad Meyer #include <sys/sglist.h> 45844d9543SConrad Meyer #include <sys/sysctl.h> 46844d9543SConrad Meyer 47844d9543SConrad Meyer #ifdef DDB 48844d9543SConrad Meyer #include <ddb/ddb.h> 49844d9543SConrad Meyer #endif 50844d9543SConrad Meyer 51844d9543SConrad Meyer #include <dev/pci/pcivar.h> 52844d9543SConrad Meyer 53844d9543SConrad Meyer #include <dev/random/randomdev.h> 54844d9543SConrad Meyer 55844d9543SConrad Meyer #include <opencrypto/cryptodev.h> 56844d9543SConrad Meyer #include <opencrypto/xform.h> 57844d9543SConrad Meyer 58844d9543SConrad Meyer #include "cryptodev_if.h" 59844d9543SConrad Meyer 60844d9543SConrad Meyer #include "ccp.h" 61844d9543SConrad Meyer #include "ccp_hardware.h" 62844d9543SConrad Meyer 63844d9543SConrad Meyer MALLOC_DEFINE(M_CCP, "ccp", "AMD CCP crypto"); 64844d9543SConrad Meyer 65844d9543SConrad Meyer /* 66844d9543SConrad Meyer * Need a global softc available for garbage random_source API, which lacks any 67844d9543SConrad Meyer * context pointer. It's also handy for debugging. 68844d9543SConrad Meyer */ 69844d9543SConrad Meyer struct ccp_softc *g_ccp_softc; 70844d9543SConrad Meyer 71844d9543SConrad Meyer bool g_debug_print = false; 72844d9543SConrad Meyer SYSCTL_BOOL(_hw_ccp, OID_AUTO, debug, CTLFLAG_RWTUN, &g_debug_print, 0, 73844d9543SConrad Meyer "Set to enable debugging log messages"); 74844d9543SConrad Meyer 75844d9543SConrad Meyer static struct pciid { 76844d9543SConrad Meyer uint32_t devid; 77844d9543SConrad Meyer const char *desc; 78844d9543SConrad Meyer } ccp_ids[] = { 79844d9543SConrad Meyer { 0x14561022, "AMD CCP-5a" }, 80844d9543SConrad Meyer { 0x14681022, "AMD CCP-5b" }, 81844d9543SConrad Meyer }; 82844d9543SConrad Meyer 83844d9543SConrad Meyer static struct random_source random_ccp = { 84844d9543SConrad Meyer .rs_ident = "AMD CCP TRNG", 85844d9543SConrad Meyer .rs_source = RANDOM_PURE_CCP, 86844d9543SConrad Meyer .rs_read = random_ccp_read, 87844d9543SConrad Meyer }; 88844d9543SConrad Meyer 89844d9543SConrad Meyer /* 90844d9543SConrad Meyer * ccp_populate_sglist() generates a scatter/gather list that covers the entire 91844d9543SConrad Meyer * crypto operation buffer. 92844d9543SConrad Meyer */ 93844d9543SConrad Meyer static int 94844d9543SConrad Meyer ccp_populate_sglist(struct sglist *sg, struct cryptop *crp) 95844d9543SConrad Meyer { 96844d9543SConrad Meyer int error; 97844d9543SConrad Meyer 98844d9543SConrad Meyer sglist_reset(sg); 99*c0341432SJohn Baldwin switch (crp->crp_buf_type) { 100*c0341432SJohn Baldwin case CRYPTO_BUF_MBUF: 101844d9543SConrad Meyer error = sglist_append_mbuf(sg, crp->crp_mbuf); 102*c0341432SJohn Baldwin break; 103*c0341432SJohn Baldwin case CRYPTO_BUF_UIO: 104844d9543SConrad Meyer error = sglist_append_uio(sg, crp->crp_uio); 105*c0341432SJohn Baldwin break; 106*c0341432SJohn Baldwin case CRYPTO_BUF_CONTIG: 107844d9543SConrad Meyer error = sglist_append(sg, crp->crp_buf, crp->crp_ilen); 108*c0341432SJohn Baldwin break; 109*c0341432SJohn Baldwin default: 110*c0341432SJohn Baldwin error = EINVAL; 111*c0341432SJohn Baldwin } 112844d9543SConrad Meyer return (error); 113844d9543SConrad Meyer } 114844d9543SConrad Meyer 115844d9543SConrad Meyer /* 116844d9543SConrad Meyer * Handle a GCM request with an empty payload by performing the 117*c0341432SJohn Baldwin * operation in software. 118844d9543SConrad Meyer */ 119844d9543SConrad Meyer static void 120*c0341432SJohn Baldwin ccp_gcm_soft(struct ccp_session *s, struct cryptop *crp) 121844d9543SConrad Meyer { 122844d9543SConrad Meyer struct aes_gmac_ctx gmac_ctx; 123844d9543SConrad Meyer char block[GMAC_BLOCK_LEN]; 124844d9543SConrad Meyer char digest[GMAC_DIGEST_LEN]; 125844d9543SConrad Meyer char iv[AES_BLOCK_LEN]; 126844d9543SConrad Meyer int i, len; 127844d9543SConrad Meyer 128844d9543SConrad Meyer /* 129844d9543SConrad Meyer * This assumes a 12-byte IV from the crp. See longer comment 130844d9543SConrad Meyer * above in ccp_gcm() for more details. 131844d9543SConrad Meyer */ 132*c0341432SJohn Baldwin if ((crp->crp_flags & CRYPTO_F_IV_SEPARATE) == 0) { 133*c0341432SJohn Baldwin crp->crp_etype = EINVAL; 134*c0341432SJohn Baldwin goto out; 135844d9543SConrad Meyer } 136*c0341432SJohn Baldwin memcpy(iv, crp->crp_iv, 12); 137844d9543SConrad Meyer *(uint32_t *)&iv[12] = htobe32(1); 138844d9543SConrad Meyer 139844d9543SConrad Meyer /* Initialize the MAC. */ 140844d9543SConrad Meyer AES_GMAC_Init(&gmac_ctx); 141844d9543SConrad Meyer AES_GMAC_Setkey(&gmac_ctx, s->blkcipher.enckey, s->blkcipher.key_len); 142844d9543SConrad Meyer AES_GMAC_Reinit(&gmac_ctx, iv, sizeof(iv)); 143844d9543SConrad Meyer 144844d9543SConrad Meyer /* MAC the AAD. */ 145*c0341432SJohn Baldwin for (i = 0; i < crp->crp_aad_length; i += sizeof(block)) { 146*c0341432SJohn Baldwin len = imin(crp->crp_aad_length - i, sizeof(block)); 147*c0341432SJohn Baldwin crypto_copydata(crp, crp->crp_aad_start + i, len, block); 148844d9543SConrad Meyer bzero(block + len, sizeof(block) - len); 149844d9543SConrad Meyer AES_GMAC_Update(&gmac_ctx, block, sizeof(block)); 150844d9543SConrad Meyer } 151844d9543SConrad Meyer 152844d9543SConrad Meyer /* Length block. */ 153844d9543SConrad Meyer bzero(block, sizeof(block)); 154*c0341432SJohn Baldwin ((uint32_t *)block)[1] = htobe32(crp->crp_aad_length * 8); 155844d9543SConrad Meyer AES_GMAC_Update(&gmac_ctx, block, sizeof(block)); 156844d9543SConrad Meyer AES_GMAC_Final(digest, &gmac_ctx); 157844d9543SConrad Meyer 158*c0341432SJohn Baldwin if (CRYPTO_OP_IS_ENCRYPT(crp->crp_op)) { 159*c0341432SJohn Baldwin crypto_copyback(crp, crp->crp_digest_start, sizeof(digest), 160*c0341432SJohn Baldwin digest); 161844d9543SConrad Meyer crp->crp_etype = 0; 162844d9543SConrad Meyer } else { 163844d9543SConrad Meyer char digest2[GMAC_DIGEST_LEN]; 164844d9543SConrad Meyer 165*c0341432SJohn Baldwin crypto_copydata(crp, crp->crp_digest_start, sizeof(digest2), 166*c0341432SJohn Baldwin digest2); 167844d9543SConrad Meyer if (timingsafe_bcmp(digest, digest2, sizeof(digest)) == 0) 168844d9543SConrad Meyer crp->crp_etype = 0; 169844d9543SConrad Meyer else 170844d9543SConrad Meyer crp->crp_etype = EBADMSG; 171844d9543SConrad Meyer } 172*c0341432SJohn Baldwin out: 173844d9543SConrad Meyer crypto_done(crp); 174844d9543SConrad Meyer } 175844d9543SConrad Meyer 176844d9543SConrad Meyer static int 177844d9543SConrad Meyer ccp_probe(device_t dev) 178844d9543SConrad Meyer { 179844d9543SConrad Meyer struct pciid *ip; 180844d9543SConrad Meyer uint32_t id; 181844d9543SConrad Meyer 182844d9543SConrad Meyer id = pci_get_devid(dev); 183844d9543SConrad Meyer for (ip = ccp_ids; ip < &ccp_ids[nitems(ccp_ids)]; ip++) { 184844d9543SConrad Meyer if (id == ip->devid) { 185844d9543SConrad Meyer device_set_desc(dev, ip->desc); 186844d9543SConrad Meyer return (0); 187844d9543SConrad Meyer } 188844d9543SConrad Meyer } 189844d9543SConrad Meyer return (ENXIO); 190844d9543SConrad Meyer } 191844d9543SConrad Meyer 192844d9543SConrad Meyer static void 193844d9543SConrad Meyer ccp_initialize_queues(struct ccp_softc *sc) 194844d9543SConrad Meyer { 195844d9543SConrad Meyer struct ccp_queue *qp; 196844d9543SConrad Meyer size_t i; 197844d9543SConrad Meyer 198844d9543SConrad Meyer for (i = 0; i < nitems(sc->queues); i++) { 199844d9543SConrad Meyer qp = &sc->queues[i]; 200844d9543SConrad Meyer 201844d9543SConrad Meyer qp->cq_softc = sc; 202844d9543SConrad Meyer qp->cq_qindex = i; 203844d9543SConrad Meyer mtx_init(&qp->cq_lock, "ccp queue", NULL, MTX_DEF); 204844d9543SConrad Meyer /* XXX - arbitrarily chosen sizes */ 205844d9543SConrad Meyer qp->cq_sg_crp = sglist_alloc(32, M_WAITOK); 206844d9543SConrad Meyer /* Two more SGEs than sg_crp to accommodate ipad. */ 207844d9543SConrad Meyer qp->cq_sg_ulptx = sglist_alloc(34, M_WAITOK); 208844d9543SConrad Meyer qp->cq_sg_dst = sglist_alloc(2, M_WAITOK); 209844d9543SConrad Meyer } 210844d9543SConrad Meyer } 211844d9543SConrad Meyer 212844d9543SConrad Meyer static void 213844d9543SConrad Meyer ccp_free_queues(struct ccp_softc *sc) 214844d9543SConrad Meyer { 215844d9543SConrad Meyer struct ccp_queue *qp; 216844d9543SConrad Meyer size_t i; 217844d9543SConrad Meyer 218844d9543SConrad Meyer for (i = 0; i < nitems(sc->queues); i++) { 219844d9543SConrad Meyer qp = &sc->queues[i]; 220844d9543SConrad Meyer 221844d9543SConrad Meyer mtx_destroy(&qp->cq_lock); 222844d9543SConrad Meyer sglist_free(qp->cq_sg_crp); 223844d9543SConrad Meyer sglist_free(qp->cq_sg_ulptx); 224844d9543SConrad Meyer sglist_free(qp->cq_sg_dst); 225844d9543SConrad Meyer } 226844d9543SConrad Meyer } 227844d9543SConrad Meyer 228844d9543SConrad Meyer static int 229844d9543SConrad Meyer ccp_attach(device_t dev) 230844d9543SConrad Meyer { 231844d9543SConrad Meyer struct ccp_softc *sc; 232844d9543SConrad Meyer int error; 233844d9543SConrad Meyer 234844d9543SConrad Meyer sc = device_get_softc(dev); 235844d9543SConrad Meyer sc->dev = dev; 236844d9543SConrad Meyer 2371b0909d5SConrad Meyer sc->cid = crypto_get_driverid(dev, sizeof(struct ccp_session), 2381b0909d5SConrad Meyer CRYPTOCAP_F_HARDWARE); 239844d9543SConrad Meyer if (sc->cid < 0) { 240844d9543SConrad Meyer device_printf(dev, "could not get crypto driver id\n"); 241844d9543SConrad Meyer return (ENXIO); 242844d9543SConrad Meyer } 243844d9543SConrad Meyer 244844d9543SConrad Meyer error = ccp_hw_attach(dev); 245844d9543SConrad Meyer if (error != 0) 246844d9543SConrad Meyer return (error); 247844d9543SConrad Meyer 248844d9543SConrad Meyer mtx_init(&sc->lock, "ccp", NULL, MTX_DEF); 249844d9543SConrad Meyer 250844d9543SConrad Meyer ccp_initialize_queues(sc); 251844d9543SConrad Meyer 252844d9543SConrad Meyer if (g_ccp_softc == NULL) { 253844d9543SConrad Meyer g_ccp_softc = sc; 254844d9543SConrad Meyer if ((sc->hw_features & VERSION_CAP_TRNG) != 0) 255844d9543SConrad Meyer random_source_register(&random_ccp); 256844d9543SConrad Meyer } 257844d9543SConrad Meyer 258844d9543SConrad Meyer return (0); 259844d9543SConrad Meyer } 260844d9543SConrad Meyer 261844d9543SConrad Meyer static int 262844d9543SConrad Meyer ccp_detach(device_t dev) 263844d9543SConrad Meyer { 264844d9543SConrad Meyer struct ccp_softc *sc; 265844d9543SConrad Meyer 266844d9543SConrad Meyer sc = device_get_softc(dev); 267844d9543SConrad Meyer 268844d9543SConrad Meyer mtx_lock(&sc->lock); 269844d9543SConrad Meyer sc->detaching = true; 270844d9543SConrad Meyer mtx_unlock(&sc->lock); 271844d9543SConrad Meyer 272844d9543SConrad Meyer crypto_unregister_all(sc->cid); 273844d9543SConrad Meyer if (g_ccp_softc == sc && (sc->hw_features & VERSION_CAP_TRNG) != 0) 274844d9543SConrad Meyer random_source_deregister(&random_ccp); 275844d9543SConrad Meyer 276844d9543SConrad Meyer ccp_hw_detach(dev); 277844d9543SConrad Meyer ccp_free_queues(sc); 278844d9543SConrad Meyer 279844d9543SConrad Meyer if (g_ccp_softc == sc) 280844d9543SConrad Meyer g_ccp_softc = NULL; 281844d9543SConrad Meyer 282844d9543SConrad Meyer mtx_destroy(&sc->lock); 283844d9543SConrad Meyer return (0); 284844d9543SConrad Meyer } 285844d9543SConrad Meyer 286844d9543SConrad Meyer static void 287*c0341432SJohn Baldwin ccp_init_hmac_digest(struct ccp_session *s, const char *key, int klen) 288844d9543SConrad Meyer { 289844d9543SConrad Meyer union authctx auth_ctx; 290844d9543SConrad Meyer struct auth_hash *axf; 291844d9543SConrad Meyer u_int i; 292844d9543SConrad Meyer 293844d9543SConrad Meyer /* 294844d9543SConrad Meyer * If the key is larger than the block size, use the digest of 295844d9543SConrad Meyer * the key as the key instead. 296844d9543SConrad Meyer */ 297844d9543SConrad Meyer axf = s->hmac.auth_hash; 298844d9543SConrad Meyer if (klen > axf->blocksize) { 299844d9543SConrad Meyer axf->Init(&auth_ctx); 300844d9543SConrad Meyer axf->Update(&auth_ctx, key, klen); 301844d9543SConrad Meyer axf->Final(s->hmac.ipad, &auth_ctx); 302844d9543SConrad Meyer explicit_bzero(&auth_ctx, sizeof(auth_ctx)); 303844d9543SConrad Meyer klen = axf->hashsize; 304844d9543SConrad Meyer } else 305844d9543SConrad Meyer memcpy(s->hmac.ipad, key, klen); 306844d9543SConrad Meyer 307844d9543SConrad Meyer memset(s->hmac.ipad + klen, 0, axf->blocksize - klen); 308844d9543SConrad Meyer memcpy(s->hmac.opad, s->hmac.ipad, axf->blocksize); 309844d9543SConrad Meyer 310844d9543SConrad Meyer for (i = 0; i < axf->blocksize; i++) { 311844d9543SConrad Meyer s->hmac.ipad[i] ^= HMAC_IPAD_VAL; 312844d9543SConrad Meyer s->hmac.opad[i] ^= HMAC_OPAD_VAL; 313844d9543SConrad Meyer } 314844d9543SConrad Meyer } 315844d9543SConrad Meyer 316*c0341432SJohn Baldwin static bool 317844d9543SConrad Meyer ccp_aes_check_keylen(int alg, int klen) 318844d9543SConrad Meyer { 319844d9543SConrad Meyer 320*c0341432SJohn Baldwin switch (klen * 8) { 321844d9543SConrad Meyer case 128: 322844d9543SConrad Meyer case 192: 323844d9543SConrad Meyer if (alg == CRYPTO_AES_XTS) 324*c0341432SJohn Baldwin return (false); 325844d9543SConrad Meyer break; 326844d9543SConrad Meyer case 256: 327844d9543SConrad Meyer break; 328844d9543SConrad Meyer case 512: 329844d9543SConrad Meyer if (alg != CRYPTO_AES_XTS) 330*c0341432SJohn Baldwin return (false); 331844d9543SConrad Meyer break; 332844d9543SConrad Meyer default: 333*c0341432SJohn Baldwin return (false); 334844d9543SConrad Meyer } 335*c0341432SJohn Baldwin return (true); 336844d9543SConrad Meyer } 337844d9543SConrad Meyer 338844d9543SConrad Meyer static void 339844d9543SConrad Meyer ccp_aes_setkey(struct ccp_session *s, int alg, const void *key, int klen) 340844d9543SConrad Meyer { 341844d9543SConrad Meyer unsigned kbits; 342844d9543SConrad Meyer 343844d9543SConrad Meyer if (alg == CRYPTO_AES_XTS) 344*c0341432SJohn Baldwin kbits = (klen / 2) * 8; 345844d9543SConrad Meyer else 346*c0341432SJohn Baldwin kbits = klen * 8; 347844d9543SConrad Meyer 348844d9543SConrad Meyer switch (kbits) { 349844d9543SConrad Meyer case 128: 350844d9543SConrad Meyer s->blkcipher.cipher_type = CCP_AES_TYPE_128; 351844d9543SConrad Meyer break; 352844d9543SConrad Meyer case 192: 353844d9543SConrad Meyer s->blkcipher.cipher_type = CCP_AES_TYPE_192; 354844d9543SConrad Meyer break; 355844d9543SConrad Meyer case 256: 356844d9543SConrad Meyer s->blkcipher.cipher_type = CCP_AES_TYPE_256; 357844d9543SConrad Meyer break; 358844d9543SConrad Meyer default: 359844d9543SConrad Meyer panic("should not get here"); 360844d9543SConrad Meyer } 361844d9543SConrad Meyer 362*c0341432SJohn Baldwin s->blkcipher.key_len = klen; 363844d9543SConrad Meyer memcpy(s->blkcipher.enckey, key, s->blkcipher.key_len); 364844d9543SConrad Meyer } 365844d9543SConrad Meyer 366*c0341432SJohn Baldwin static bool 367*c0341432SJohn Baldwin ccp_auth_supported(struct ccp_softc *sc, 368*c0341432SJohn Baldwin const struct crypto_session_params *csp) 369*c0341432SJohn Baldwin { 370*c0341432SJohn Baldwin 371*c0341432SJohn Baldwin if ((sc->hw_features & VERSION_CAP_SHA) == 0) 372*c0341432SJohn Baldwin return (false); 373*c0341432SJohn Baldwin switch (csp->csp_auth_alg) { 374*c0341432SJohn Baldwin case CRYPTO_SHA1_HMAC: 375*c0341432SJohn Baldwin case CRYPTO_SHA2_256_HMAC: 376*c0341432SJohn Baldwin case CRYPTO_SHA2_384_HMAC: 377*c0341432SJohn Baldwin case CRYPTO_SHA2_512_HMAC: 378*c0341432SJohn Baldwin if (csp->csp_auth_key == NULL) 379*c0341432SJohn Baldwin return (false); 380*c0341432SJohn Baldwin break; 381*c0341432SJohn Baldwin default: 382*c0341432SJohn Baldwin return (false); 383*c0341432SJohn Baldwin } 384*c0341432SJohn Baldwin return (true); 385*c0341432SJohn Baldwin } 386*c0341432SJohn Baldwin 387*c0341432SJohn Baldwin static bool 388*c0341432SJohn Baldwin ccp_cipher_supported(struct ccp_softc *sc, 389*c0341432SJohn Baldwin const struct crypto_session_params *csp) 390*c0341432SJohn Baldwin { 391*c0341432SJohn Baldwin 392*c0341432SJohn Baldwin if ((sc->hw_features & VERSION_CAP_AES) == 0) 393*c0341432SJohn Baldwin return (false); 394*c0341432SJohn Baldwin switch (csp->csp_cipher_alg) { 395*c0341432SJohn Baldwin case CRYPTO_AES_CBC: 396*c0341432SJohn Baldwin if (csp->csp_ivlen != AES_BLOCK_LEN) 397*c0341432SJohn Baldwin return (false); 398*c0341432SJohn Baldwin break; 399*c0341432SJohn Baldwin case CRYPTO_AES_ICM: 400*c0341432SJohn Baldwin if (csp->csp_ivlen != AES_BLOCK_LEN) 401*c0341432SJohn Baldwin return (false); 402*c0341432SJohn Baldwin break; 403*c0341432SJohn Baldwin case CRYPTO_AES_XTS: 404*c0341432SJohn Baldwin if (csp->csp_ivlen != AES_XTS_IV_LEN) 405*c0341432SJohn Baldwin return (false); 406*c0341432SJohn Baldwin break; 407*c0341432SJohn Baldwin default: 408*c0341432SJohn Baldwin return (false); 409*c0341432SJohn Baldwin } 410*c0341432SJohn Baldwin return (ccp_aes_check_keylen(csp->csp_cipher_alg, 411*c0341432SJohn Baldwin csp->csp_cipher_klen)); 412*c0341432SJohn Baldwin } 413*c0341432SJohn Baldwin 414844d9543SConrad Meyer static int 415*c0341432SJohn Baldwin ccp_probesession(device_t dev, const struct crypto_session_params *csp) 416844d9543SConrad Meyer { 417844d9543SConrad Meyer struct ccp_softc *sc; 418844d9543SConrad Meyer 419*c0341432SJohn Baldwin if (csp->csp_flags != 0) 420844d9543SConrad Meyer return (EINVAL); 421*c0341432SJohn Baldwin sc = device_get_softc(dev); 422*c0341432SJohn Baldwin switch (csp->csp_mode) { 423*c0341432SJohn Baldwin case CSP_MODE_DIGEST: 424*c0341432SJohn Baldwin if (!ccp_auth_supported(sc, csp)) 425844d9543SConrad Meyer return (EINVAL); 426844d9543SConrad Meyer break; 427*c0341432SJohn Baldwin case CSP_MODE_CIPHER: 428*c0341432SJohn Baldwin if (!ccp_cipher_supported(sc, csp)) 429*c0341432SJohn Baldwin return (EINVAL); 430844d9543SConrad Meyer break; 431*c0341432SJohn Baldwin case CSP_MODE_AEAD: 432*c0341432SJohn Baldwin switch (csp->csp_cipher_alg) { 433844d9543SConrad Meyer case CRYPTO_AES_NIST_GCM_16: 434*c0341432SJohn Baldwin if (csp->csp_ivlen != AES_GCM_IV_LEN) 435844d9543SConrad Meyer return (EINVAL); 436*c0341432SJohn Baldwin if (csp->csp_auth_mlen < 0 || 437*c0341432SJohn Baldwin csp->csp_auth_mlen > AES_GMAC_HASH_LEN) 438*c0341432SJohn Baldwin return (EINVAL); 439*c0341432SJohn Baldwin if ((sc->hw_features & VERSION_CAP_AES) == 0) 440*c0341432SJohn Baldwin return (EINVAL); 441844d9543SConrad Meyer break; 442844d9543SConrad Meyer default: 443844d9543SConrad Meyer return (EINVAL); 444844d9543SConrad Meyer } 445*c0341432SJohn Baldwin break; 446*c0341432SJohn Baldwin case CSP_MODE_ETA: 447*c0341432SJohn Baldwin if (!ccp_auth_supported(sc, csp) || 448*c0341432SJohn Baldwin !ccp_cipher_supported(sc, csp)) 449*c0341432SJohn Baldwin return (EINVAL); 450*c0341432SJohn Baldwin break; 451*c0341432SJohn Baldwin default: 452*c0341432SJohn Baldwin return (EINVAL); 453844d9543SConrad Meyer } 454*c0341432SJohn Baldwin 455*c0341432SJohn Baldwin return (CRYPTODEV_PROBE_HARDWARE); 456*c0341432SJohn Baldwin } 457*c0341432SJohn Baldwin 458*c0341432SJohn Baldwin static int 459*c0341432SJohn Baldwin ccp_newsession(device_t dev, crypto_session_t cses, 460*c0341432SJohn Baldwin const struct crypto_session_params *csp) 461*c0341432SJohn Baldwin { 462*c0341432SJohn Baldwin struct ccp_softc *sc; 463*c0341432SJohn Baldwin struct ccp_session *s; 464*c0341432SJohn Baldwin struct auth_hash *auth_hash; 465*c0341432SJohn Baldwin enum ccp_aes_mode cipher_mode; 466*c0341432SJohn Baldwin unsigned auth_mode; 467*c0341432SJohn Baldwin unsigned q; 468*c0341432SJohn Baldwin 469*c0341432SJohn Baldwin /* XXX reconcile auth_mode with use by ccp_sha */ 470*c0341432SJohn Baldwin switch (csp->csp_auth_alg) { 471*c0341432SJohn Baldwin case CRYPTO_SHA1_HMAC: 472*c0341432SJohn Baldwin auth_hash = &auth_hash_hmac_sha1; 473*c0341432SJohn Baldwin auth_mode = SHA1; 474*c0341432SJohn Baldwin break; 475*c0341432SJohn Baldwin case CRYPTO_SHA2_256_HMAC: 476*c0341432SJohn Baldwin auth_hash = &auth_hash_hmac_sha2_256; 477*c0341432SJohn Baldwin auth_mode = SHA2_256; 478*c0341432SJohn Baldwin break; 479*c0341432SJohn Baldwin case CRYPTO_SHA2_384_HMAC: 480*c0341432SJohn Baldwin auth_hash = &auth_hash_hmac_sha2_384; 481*c0341432SJohn Baldwin auth_mode = SHA2_384; 482*c0341432SJohn Baldwin break; 483*c0341432SJohn Baldwin case CRYPTO_SHA2_512_HMAC: 484*c0341432SJohn Baldwin auth_hash = &auth_hash_hmac_sha2_512; 485*c0341432SJohn Baldwin auth_mode = SHA2_512; 486*c0341432SJohn Baldwin break; 487*c0341432SJohn Baldwin default: 488*c0341432SJohn Baldwin auth_hash = NULL; 489*c0341432SJohn Baldwin auth_mode = 0; 490*c0341432SJohn Baldwin break; 491*c0341432SJohn Baldwin } 492*c0341432SJohn Baldwin 493*c0341432SJohn Baldwin switch (csp->csp_cipher_alg) { 494*c0341432SJohn Baldwin case CRYPTO_AES_CBC: 495*c0341432SJohn Baldwin cipher_mode = CCP_AES_MODE_CBC; 496*c0341432SJohn Baldwin break; 497*c0341432SJohn Baldwin case CRYPTO_AES_ICM: 498*c0341432SJohn Baldwin cipher_mode = CCP_AES_MODE_CTR; 499*c0341432SJohn Baldwin break; 500*c0341432SJohn Baldwin case CRYPTO_AES_NIST_GCM_16: 501*c0341432SJohn Baldwin cipher_mode = CCP_AES_MODE_GCTR; 502*c0341432SJohn Baldwin break; 503*c0341432SJohn Baldwin case CRYPTO_AES_XTS: 504*c0341432SJohn Baldwin cipher_mode = CCP_AES_MODE_XTS; 505*c0341432SJohn Baldwin break; 506*c0341432SJohn Baldwin default: 507*c0341432SJohn Baldwin cipher_mode = CCP_AES_MODE_ECB; 508*c0341432SJohn Baldwin break; 509*c0341432SJohn Baldwin } 510844d9543SConrad Meyer 511844d9543SConrad Meyer sc = device_get_softc(dev); 512844d9543SConrad Meyer mtx_lock(&sc->lock); 513844d9543SConrad Meyer if (sc->detaching) { 514844d9543SConrad Meyer mtx_unlock(&sc->lock); 515844d9543SConrad Meyer return (ENXIO); 516844d9543SConrad Meyer } 517844d9543SConrad Meyer 518*c0341432SJohn Baldwin s = crypto_get_driver_session(cses); 519*c0341432SJohn Baldwin 520844d9543SConrad Meyer /* Just grab the first usable queue for now. */ 521844d9543SConrad Meyer for (q = 0; q < nitems(sc->queues); q++) 522844d9543SConrad Meyer if ((sc->valid_queues & (1 << q)) != 0) 523844d9543SConrad Meyer break; 524844d9543SConrad Meyer if (q == nitems(sc->queues)) { 525844d9543SConrad Meyer mtx_unlock(&sc->lock); 526844d9543SConrad Meyer return (ENXIO); 527844d9543SConrad Meyer } 528844d9543SConrad Meyer s->queue = q; 529844d9543SConrad Meyer 530*c0341432SJohn Baldwin switch (csp->csp_mode) { 531*c0341432SJohn Baldwin case CSP_MODE_AEAD: 532844d9543SConrad Meyer s->mode = GCM; 533*c0341432SJohn Baldwin break; 534*c0341432SJohn Baldwin case CSP_MODE_ETA: 535844d9543SConrad Meyer s->mode = AUTHENC; 536*c0341432SJohn Baldwin break; 537*c0341432SJohn Baldwin case CSP_MODE_DIGEST: 538844d9543SConrad Meyer s->mode = HMAC; 539*c0341432SJohn Baldwin break; 540*c0341432SJohn Baldwin case CSP_MODE_CIPHER: 541844d9543SConrad Meyer s->mode = BLKCIPHER; 542*c0341432SJohn Baldwin break; 543844d9543SConrad Meyer } 544*c0341432SJohn Baldwin 545*c0341432SJohn Baldwin if (s->mode == GCM) { 546*c0341432SJohn Baldwin if (csp->csp_auth_mlen == 0) 547844d9543SConrad Meyer s->gmac.hash_len = AES_GMAC_HASH_LEN; 548844d9543SConrad Meyer else 549*c0341432SJohn Baldwin s->gmac.hash_len = csp->csp_auth_mlen; 550*c0341432SJohn Baldwin } else if (auth_hash != NULL) { 551844d9543SConrad Meyer s->hmac.auth_hash = auth_hash; 552844d9543SConrad Meyer s->hmac.auth_mode = auth_mode; 553*c0341432SJohn Baldwin if (csp->csp_auth_mlen == 0) 554844d9543SConrad Meyer s->hmac.hash_len = auth_hash->hashsize; 555844d9543SConrad Meyer else 556*c0341432SJohn Baldwin s->hmac.hash_len = csp->csp_auth_mlen; 557*c0341432SJohn Baldwin ccp_init_hmac_digest(s, csp->csp_auth_key, csp->csp_auth_klen); 558844d9543SConrad Meyer } 559*c0341432SJohn Baldwin if (cipher_mode != CCP_AES_MODE_ECB) { 560844d9543SConrad Meyer s->blkcipher.cipher_mode = cipher_mode; 561*c0341432SJohn Baldwin if (csp->csp_cipher_key != NULL) 562*c0341432SJohn Baldwin ccp_aes_setkey(s, csp->csp_cipher_alg, 563*c0341432SJohn Baldwin csp->csp_cipher_key, csp->csp_cipher_klen); 564844d9543SConrad Meyer } 565844d9543SConrad Meyer 566844d9543SConrad Meyer s->active = true; 567844d9543SConrad Meyer mtx_unlock(&sc->lock); 568844d9543SConrad Meyer 569844d9543SConrad Meyer return (0); 570844d9543SConrad Meyer } 571844d9543SConrad Meyer 5721b0909d5SConrad Meyer static void 5731b0909d5SConrad Meyer ccp_freesession(device_t dev, crypto_session_t cses) 574844d9543SConrad Meyer { 5751b0909d5SConrad Meyer struct ccp_session *s; 576844d9543SConrad Meyer 5771b0909d5SConrad Meyer s = crypto_get_driver_session(cses); 5781b0909d5SConrad Meyer 5791b0909d5SConrad Meyer if (s->pending != 0) 580844d9543SConrad Meyer device_printf(dev, 5811b0909d5SConrad Meyer "session %p freed with %d pending requests\n", s, 5821b0909d5SConrad Meyer s->pending); 5831b0909d5SConrad Meyer s->active = false; 584844d9543SConrad Meyer } 585844d9543SConrad Meyer 586844d9543SConrad Meyer static int 587844d9543SConrad Meyer ccp_process(device_t dev, struct cryptop *crp, int hint) 588844d9543SConrad Meyer { 589*c0341432SJohn Baldwin const struct crypto_session_params *csp; 590844d9543SConrad Meyer struct ccp_softc *sc; 591844d9543SConrad Meyer struct ccp_queue *qp; 592844d9543SConrad Meyer struct ccp_session *s; 593844d9543SConrad Meyer int error; 594844d9543SConrad Meyer bool qpheld; 595844d9543SConrad Meyer 596844d9543SConrad Meyer qpheld = false; 597844d9543SConrad Meyer qp = NULL; 598844d9543SConrad Meyer 599*c0341432SJohn Baldwin csp = crypto_get_params(crp->crp_session); 6001b0909d5SConrad Meyer s = crypto_get_driver_session(crp->crp_session); 601844d9543SConrad Meyer sc = device_get_softc(dev); 602844d9543SConrad Meyer mtx_lock(&sc->lock); 603844d9543SConrad Meyer qp = &sc->queues[s->queue]; 604844d9543SConrad Meyer mtx_unlock(&sc->lock); 605844d9543SConrad Meyer error = ccp_queue_acquire_reserve(qp, 1 /* placeholder */, M_NOWAIT); 606844d9543SConrad Meyer if (error != 0) 607844d9543SConrad Meyer goto out; 608844d9543SConrad Meyer qpheld = true; 609844d9543SConrad Meyer 610844d9543SConrad Meyer error = ccp_populate_sglist(qp->cq_sg_crp, crp); 611844d9543SConrad Meyer if (error != 0) 612844d9543SConrad Meyer goto out; 613844d9543SConrad Meyer 614*c0341432SJohn Baldwin if (crp->crp_auth_key != NULL) { 615*c0341432SJohn Baldwin KASSERT(s->hmac.auth_hash != NULL, ("auth key without HMAC")); 616*c0341432SJohn Baldwin ccp_init_hmac_digest(s, crp->crp_auth_key, csp->csp_auth_klen); 617*c0341432SJohn Baldwin } 618*c0341432SJohn Baldwin if (crp->crp_cipher_key != NULL) 619*c0341432SJohn Baldwin ccp_aes_setkey(s, csp->csp_cipher_alg, crp->crp_cipher_key, 620*c0341432SJohn Baldwin csp->csp_cipher_klen); 621*c0341432SJohn Baldwin 622844d9543SConrad Meyer switch (s->mode) { 623844d9543SConrad Meyer case HMAC: 624*c0341432SJohn Baldwin if (s->pending != 0) { 625*c0341432SJohn Baldwin error = EAGAIN; 626*c0341432SJohn Baldwin break; 627*c0341432SJohn Baldwin } 628844d9543SConrad Meyer error = ccp_hmac(qp, s, crp); 629844d9543SConrad Meyer break; 630844d9543SConrad Meyer case BLKCIPHER: 631*c0341432SJohn Baldwin if (s->pending != 0) { 632*c0341432SJohn Baldwin error = EAGAIN; 633844d9543SConrad Meyer break; 634844d9543SConrad Meyer } 635844d9543SConrad Meyer error = ccp_blkcipher(qp, s, crp); 636844d9543SConrad Meyer break; 637844d9543SConrad Meyer case AUTHENC: 638*c0341432SJohn Baldwin if (s->pending != 0) { 639*c0341432SJohn Baldwin error = EAGAIN; 640844d9543SConrad Meyer break; 641844d9543SConrad Meyer } 642*c0341432SJohn Baldwin error = ccp_authenc(qp, s, crp); 643844d9543SConrad Meyer break; 644844d9543SConrad Meyer case GCM: 645*c0341432SJohn Baldwin if (crp->crp_payload_length == 0) { 646844d9543SConrad Meyer mtx_unlock(&qp->cq_lock); 647*c0341432SJohn Baldwin ccp_gcm_soft(s, crp); 648844d9543SConrad Meyer return (0); 649844d9543SConrad Meyer } 650*c0341432SJohn Baldwin if (s->pending != 0) { 651*c0341432SJohn Baldwin error = EAGAIN; 652*c0341432SJohn Baldwin break; 653*c0341432SJohn Baldwin } 654*c0341432SJohn Baldwin error = ccp_gcm(qp, s, crp); 655844d9543SConrad Meyer break; 656844d9543SConrad Meyer } 657844d9543SConrad Meyer 658844d9543SConrad Meyer if (error == 0) 659844d9543SConrad Meyer s->pending++; 660844d9543SConrad Meyer 661844d9543SConrad Meyer out: 662844d9543SConrad Meyer if (qpheld) { 663844d9543SConrad Meyer if (error != 0) { 664844d9543SConrad Meyer /* 665844d9543SConrad Meyer * Squash EAGAIN so callers don't uselessly and 666844d9543SConrad Meyer * expensively retry if the ring was full. 667844d9543SConrad Meyer */ 668844d9543SConrad Meyer if (error == EAGAIN) 669844d9543SConrad Meyer error = ENOMEM; 670844d9543SConrad Meyer ccp_queue_abort(qp); 671844d9543SConrad Meyer } else 672844d9543SConrad Meyer ccp_queue_release(qp); 673844d9543SConrad Meyer } 674844d9543SConrad Meyer 675844d9543SConrad Meyer if (error != 0) { 676844d9543SConrad Meyer DPRINTF(dev, "%s: early error:%d\n", __func__, error); 677844d9543SConrad Meyer crp->crp_etype = error; 678844d9543SConrad Meyer crypto_done(crp); 679844d9543SConrad Meyer } 680844d9543SConrad Meyer return (0); 681844d9543SConrad Meyer } 682844d9543SConrad Meyer 683844d9543SConrad Meyer static device_method_t ccp_methods[] = { 684844d9543SConrad Meyer DEVMETHOD(device_probe, ccp_probe), 685844d9543SConrad Meyer DEVMETHOD(device_attach, ccp_attach), 686844d9543SConrad Meyer DEVMETHOD(device_detach, ccp_detach), 687844d9543SConrad Meyer 688*c0341432SJohn Baldwin DEVMETHOD(cryptodev_probesession, ccp_probesession), 689844d9543SConrad Meyer DEVMETHOD(cryptodev_newsession, ccp_newsession), 690844d9543SConrad Meyer DEVMETHOD(cryptodev_freesession, ccp_freesession), 691844d9543SConrad Meyer DEVMETHOD(cryptodev_process, ccp_process), 692844d9543SConrad Meyer 693844d9543SConrad Meyer DEVMETHOD_END 694844d9543SConrad Meyer }; 695844d9543SConrad Meyer 696844d9543SConrad Meyer static driver_t ccp_driver = { 697844d9543SConrad Meyer "ccp", 698844d9543SConrad Meyer ccp_methods, 699844d9543SConrad Meyer sizeof(struct ccp_softc) 700844d9543SConrad Meyer }; 701844d9543SConrad Meyer 702844d9543SConrad Meyer static devclass_t ccp_devclass; 703844d9543SConrad Meyer DRIVER_MODULE(ccp, pci, ccp_driver, ccp_devclass, NULL, NULL); 704844d9543SConrad Meyer MODULE_VERSION(ccp, 1); 705844d9543SConrad Meyer MODULE_DEPEND(ccp, crypto, 1, 1, 1); 706844d9543SConrad Meyer MODULE_DEPEND(ccp, random_device, 1, 1, 1); 70791eeadc5SWarner Losh #if 0 /* There are enough known issues that we shouldn't load automatically */ 708329e817fSWarner Losh MODULE_PNP_INFO("W32:vendor/device", pci, ccp, ccp_ids, 709b7220273SWarner Losh nitems(ccp_ids)); 71091eeadc5SWarner Losh #endif 711844d9543SConrad Meyer 712844d9543SConrad Meyer static int 713844d9543SConrad Meyer ccp_queue_reserve_space(struct ccp_queue *qp, unsigned n, int mflags) 714844d9543SConrad Meyer { 715844d9543SConrad Meyer struct ccp_softc *sc; 716844d9543SConrad Meyer 717844d9543SConrad Meyer mtx_assert(&qp->cq_lock, MA_OWNED); 718844d9543SConrad Meyer sc = qp->cq_softc; 719844d9543SConrad Meyer 720844d9543SConrad Meyer if (n < 1 || n >= (1 << sc->ring_size_order)) 721844d9543SConrad Meyer return (EINVAL); 722844d9543SConrad Meyer 723844d9543SConrad Meyer while (true) { 724844d9543SConrad Meyer if (ccp_queue_get_ring_space(qp) >= n) 725844d9543SConrad Meyer return (0); 726844d9543SConrad Meyer if ((mflags & M_WAITOK) == 0) 727844d9543SConrad Meyer return (EAGAIN); 728844d9543SConrad Meyer qp->cq_waiting = true; 729844d9543SConrad Meyer msleep(&qp->cq_tail, &qp->cq_lock, 0, "ccpqfull", 0); 730844d9543SConrad Meyer } 731844d9543SConrad Meyer } 732844d9543SConrad Meyer 733844d9543SConrad Meyer int 734844d9543SConrad Meyer ccp_queue_acquire_reserve(struct ccp_queue *qp, unsigned n, int mflags) 735844d9543SConrad Meyer { 736844d9543SConrad Meyer int error; 737844d9543SConrad Meyer 738844d9543SConrad Meyer mtx_lock(&qp->cq_lock); 739844d9543SConrad Meyer qp->cq_acq_tail = qp->cq_tail; 740844d9543SConrad Meyer error = ccp_queue_reserve_space(qp, n, mflags); 741844d9543SConrad Meyer if (error != 0) 742844d9543SConrad Meyer mtx_unlock(&qp->cq_lock); 743844d9543SConrad Meyer return (error); 744844d9543SConrad Meyer } 745844d9543SConrad Meyer 746844d9543SConrad Meyer void 747844d9543SConrad Meyer ccp_queue_release(struct ccp_queue *qp) 748844d9543SConrad Meyer { 749844d9543SConrad Meyer 750844d9543SConrad Meyer mtx_assert(&qp->cq_lock, MA_OWNED); 751844d9543SConrad Meyer if (qp->cq_tail != qp->cq_acq_tail) { 752844d9543SConrad Meyer wmb(); 753844d9543SConrad Meyer ccp_queue_write_tail(qp); 754844d9543SConrad Meyer } 755844d9543SConrad Meyer mtx_unlock(&qp->cq_lock); 756844d9543SConrad Meyer } 757844d9543SConrad Meyer 758844d9543SConrad Meyer void 759844d9543SConrad Meyer ccp_queue_abort(struct ccp_queue *qp) 760844d9543SConrad Meyer { 761844d9543SConrad Meyer unsigned i; 762844d9543SConrad Meyer 763844d9543SConrad Meyer mtx_assert(&qp->cq_lock, MA_OWNED); 764844d9543SConrad Meyer 765844d9543SConrad Meyer /* Wipe out any descriptors associated with this aborted txn. */ 766844d9543SConrad Meyer for (i = qp->cq_acq_tail; i != qp->cq_tail; 767844d9543SConrad Meyer i = (i + 1) % (1 << qp->cq_softc->ring_size_order)) { 768844d9543SConrad Meyer memset(&qp->desc_ring[i], 0, sizeof(qp->desc_ring[i])); 769844d9543SConrad Meyer } 770844d9543SConrad Meyer qp->cq_tail = qp->cq_acq_tail; 771844d9543SConrad Meyer 772844d9543SConrad Meyer mtx_unlock(&qp->cq_lock); 773844d9543SConrad Meyer } 774844d9543SConrad Meyer 775844d9543SConrad Meyer #ifdef DDB 776844d9543SConrad Meyer #define _db_show_lock(lo) LOCK_CLASS(lo)->lc_ddb_show(lo) 777844d9543SConrad Meyer #define db_show_lock(lk) _db_show_lock(&(lk)->lock_object) 778844d9543SConrad Meyer static void 779844d9543SConrad Meyer db_show_ccp_sc(struct ccp_softc *sc) 780844d9543SConrad Meyer { 781844d9543SConrad Meyer 782844d9543SConrad Meyer db_printf("ccp softc at %p\n", sc); 783844d9543SConrad Meyer db_printf(" cid: %d\n", (int)sc->cid); 784844d9543SConrad Meyer 785844d9543SConrad Meyer db_printf(" lock: "); 786844d9543SConrad Meyer db_show_lock(&sc->lock); 787844d9543SConrad Meyer 788844d9543SConrad Meyer db_printf(" detaching: %d\n", (int)sc->detaching); 789844d9543SConrad Meyer db_printf(" ring_size_order: %u\n", sc->ring_size_order); 790844d9543SConrad Meyer 791844d9543SConrad Meyer db_printf(" hw_version: %d\n", (int)sc->hw_version); 792844d9543SConrad Meyer db_printf(" hw_features: %b\n", (int)sc->hw_features, 793844d9543SConrad Meyer "\20\24ELFC\23TRNG\22Zip_Compress\16Zip_Decompress\13ECC\12RSA" 794844d9543SConrad Meyer "\11SHA\0103DES\07AES"); 795844d9543SConrad Meyer 796844d9543SConrad Meyer db_printf(" hw status:\n"); 797844d9543SConrad Meyer db_ccp_show_hw(sc); 798844d9543SConrad Meyer } 799844d9543SConrad Meyer 800844d9543SConrad Meyer static void 801844d9543SConrad Meyer db_show_ccp_qp(struct ccp_queue *qp) 802844d9543SConrad Meyer { 803844d9543SConrad Meyer 804844d9543SConrad Meyer db_printf(" lock: "); 805844d9543SConrad Meyer db_show_lock(&qp->cq_lock); 806844d9543SConrad Meyer 807844d9543SConrad Meyer db_printf(" cq_qindex: %u\n", qp->cq_qindex); 808844d9543SConrad Meyer db_printf(" cq_softc: %p\n", qp->cq_softc); 809844d9543SConrad Meyer 810844d9543SConrad Meyer db_printf(" head: %u\n", qp->cq_head); 811844d9543SConrad Meyer db_printf(" tail: %u\n", qp->cq_tail); 812844d9543SConrad Meyer db_printf(" acq_tail: %u\n", qp->cq_acq_tail); 813844d9543SConrad Meyer db_printf(" desc_ring: %p\n", qp->desc_ring); 814844d9543SConrad Meyer db_printf(" completions_ring: %p\n", qp->completions_ring); 815844d9543SConrad Meyer db_printf(" descriptors (phys): 0x%jx\n", 816844d9543SConrad Meyer (uintmax_t)qp->desc_ring_bus_addr); 817844d9543SConrad Meyer 818844d9543SConrad Meyer db_printf(" hw status:\n"); 819844d9543SConrad Meyer db_ccp_show_queue_hw(qp); 820844d9543SConrad Meyer } 821844d9543SConrad Meyer 822844d9543SConrad Meyer DB_SHOW_COMMAND(ccp, db_show_ccp) 823844d9543SConrad Meyer { 824844d9543SConrad Meyer struct ccp_softc *sc; 825844d9543SConrad Meyer unsigned unit, qindex; 826844d9543SConrad Meyer 827844d9543SConrad Meyer if (!have_addr) 828844d9543SConrad Meyer goto usage; 829844d9543SConrad Meyer 830844d9543SConrad Meyer unit = (unsigned)addr; 831844d9543SConrad Meyer 832844d9543SConrad Meyer sc = devclass_get_softc(ccp_devclass, unit); 833844d9543SConrad Meyer if (sc == NULL) { 834844d9543SConrad Meyer db_printf("No such device ccp%u\n", unit); 835844d9543SConrad Meyer goto usage; 836844d9543SConrad Meyer } 837844d9543SConrad Meyer 838844d9543SConrad Meyer if (count == -1) { 839844d9543SConrad Meyer db_show_ccp_sc(sc); 840844d9543SConrad Meyer return; 841844d9543SConrad Meyer } 842844d9543SConrad Meyer 843844d9543SConrad Meyer qindex = (unsigned)count; 844844d9543SConrad Meyer if (qindex >= nitems(sc->queues)) { 845844d9543SConrad Meyer db_printf("No such queue %u\n", qindex); 846844d9543SConrad Meyer goto usage; 847844d9543SConrad Meyer } 848844d9543SConrad Meyer db_show_ccp_qp(&sc->queues[qindex]); 849844d9543SConrad Meyer return; 850844d9543SConrad Meyer 851844d9543SConrad Meyer usage: 852844d9543SConrad Meyer db_printf("usage: show ccp <unit>[,<qindex>]\n"); 853844d9543SConrad Meyer return; 854844d9543SConrad Meyer } 855844d9543SConrad Meyer #endif /* DDB */ 856