1*844d9543SConrad Meyer /*- 2*844d9543SConrad Meyer * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 3*844d9543SConrad Meyer * 4*844d9543SConrad Meyer * Copyright (c) 2017 Chelsio Communications, Inc. 5*844d9543SConrad Meyer * Copyright (c) 2017 Conrad Meyer <cem@FreeBSD.org> 6*844d9543SConrad Meyer * All rights reserved. 7*844d9543SConrad Meyer * Largely borrowed from ccr(4), Written by: John Baldwin <jhb@FreeBSD.org> 8*844d9543SConrad Meyer * 9*844d9543SConrad Meyer * Redistribution and use in source and binary forms, with or without 10*844d9543SConrad Meyer * modification, are permitted provided that the following conditions 11*844d9543SConrad Meyer * are met: 12*844d9543SConrad Meyer * 1. Redistributions of source code must retain the above copyright 13*844d9543SConrad Meyer * notice, this list of conditions and the following disclaimer. 14*844d9543SConrad Meyer * 2. Redistributions in binary form must reproduce the above copyright 15*844d9543SConrad Meyer * notice, this list of conditions and the following disclaimer in the 16*844d9543SConrad Meyer * documentation and/or other materials provided with the distribution. 17*844d9543SConrad Meyer * 18*844d9543SConrad Meyer * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 19*844d9543SConrad Meyer * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20*844d9543SConrad Meyer * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21*844d9543SConrad Meyer * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 22*844d9543SConrad Meyer * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23*844d9543SConrad Meyer * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24*844d9543SConrad Meyer * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25*844d9543SConrad Meyer * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26*844d9543SConrad Meyer * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27*844d9543SConrad Meyer * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28*844d9543SConrad Meyer * SUCH DAMAGE. 29*844d9543SConrad Meyer */ 30*844d9543SConrad Meyer 31*844d9543SConrad Meyer #include <sys/cdefs.h> 32*844d9543SConrad Meyer __FBSDID("$FreeBSD$"); 33*844d9543SConrad Meyer 34*844d9543SConrad Meyer #include "opt_ddb.h" 35*844d9543SConrad Meyer 36*844d9543SConrad Meyer #include <sys/types.h> 37*844d9543SConrad Meyer #include <sys/bus.h> 38*844d9543SConrad Meyer #include <sys/lock.h> 39*844d9543SConrad Meyer #include <sys/kernel.h> 40*844d9543SConrad Meyer #include <sys/malloc.h> 41*844d9543SConrad Meyer #include <sys/mutex.h> 42*844d9543SConrad Meyer #include <sys/module.h> 43*844d9543SConrad Meyer #include <sys/rman.h> 44*844d9543SConrad Meyer #include <sys/sglist.h> 45*844d9543SConrad Meyer #include <sys/sysctl.h> 46*844d9543SConrad Meyer 47*844d9543SConrad Meyer #ifdef DDB 48*844d9543SConrad Meyer #include <ddb/ddb.h> 49*844d9543SConrad Meyer #endif 50*844d9543SConrad Meyer 51*844d9543SConrad Meyer #include <dev/pci/pcireg.h> 52*844d9543SConrad Meyer #include <dev/pci/pcivar.h> 53*844d9543SConrad Meyer 54*844d9543SConrad Meyer #include <machine/bus.h> 55*844d9543SConrad Meyer #include <machine/resource.h> 56*844d9543SConrad Meyer #include <machine/vmparam.h> 57*844d9543SConrad Meyer 58*844d9543SConrad Meyer #include <opencrypto/cryptodev.h> 59*844d9543SConrad Meyer #include <opencrypto/xform.h> 60*844d9543SConrad Meyer 61*844d9543SConrad Meyer #include <vm/vm.h> 62*844d9543SConrad Meyer #include <vm/pmap.h> 63*844d9543SConrad Meyer 64*844d9543SConrad Meyer #include "cryptodev_if.h" 65*844d9543SConrad Meyer 66*844d9543SConrad Meyer #include "ccp.h" 67*844d9543SConrad Meyer #include "ccp_hardware.h" 68*844d9543SConrad Meyer #include "ccp_lsb.h" 69*844d9543SConrad Meyer 70*844d9543SConrad Meyer CTASSERT(sizeof(struct ccp_desc) == 32); 71*844d9543SConrad Meyer 72*844d9543SConrad Meyer static struct ccp_xts_unitsize_map_entry { 73*844d9543SConrad Meyer enum ccp_xts_unitsize cxu_id; 74*844d9543SConrad Meyer unsigned cxu_size; 75*844d9543SConrad Meyer } ccp_xts_unitsize_map[] = { 76*844d9543SConrad Meyer { CCP_XTS_AES_UNIT_SIZE_16, 16 }, 77*844d9543SConrad Meyer { CCP_XTS_AES_UNIT_SIZE_512, 512 }, 78*844d9543SConrad Meyer { CCP_XTS_AES_UNIT_SIZE_1024, 1024 }, 79*844d9543SConrad Meyer { CCP_XTS_AES_UNIT_SIZE_2048, 2048 }, 80*844d9543SConrad Meyer { CCP_XTS_AES_UNIT_SIZE_4096, 4096 }, 81*844d9543SConrad Meyer }; 82*844d9543SConrad Meyer 83*844d9543SConrad Meyer SYSCTL_NODE(_hw, OID_AUTO, ccp, CTLFLAG_RD, 0, "ccp node"); 84*844d9543SConrad Meyer 85*844d9543SConrad Meyer unsigned g_ccp_ring_order = 11; 86*844d9543SConrad Meyer SYSCTL_UINT(_hw_ccp, OID_AUTO, ring_order, CTLFLAG_RDTUN, &g_ccp_ring_order, 87*844d9543SConrad Meyer 0, "Set CCP ring order. (1 << this) == ring size. Min: 6, Max: 16"); 88*844d9543SConrad Meyer 89*844d9543SConrad Meyer /* 90*844d9543SConrad Meyer * Zero buffer, sufficient for padding LSB entries, that does not span a page 91*844d9543SConrad Meyer * boundary 92*844d9543SConrad Meyer */ 93*844d9543SConrad Meyer static const char g_zeroes[32] __aligned(32); 94*844d9543SConrad Meyer 95*844d9543SConrad Meyer static inline uint32_t 96*844d9543SConrad Meyer ccp_read_4(struct ccp_softc *sc, uint32_t offset) 97*844d9543SConrad Meyer { 98*844d9543SConrad Meyer return (bus_space_read_4(sc->pci_bus_tag, sc->pci_bus_handle, offset)); 99*844d9543SConrad Meyer } 100*844d9543SConrad Meyer 101*844d9543SConrad Meyer static inline void 102*844d9543SConrad Meyer ccp_write_4(struct ccp_softc *sc, uint32_t offset, uint32_t value) 103*844d9543SConrad Meyer { 104*844d9543SConrad Meyer bus_space_write_4(sc->pci_bus_tag, sc->pci_bus_handle, offset, value); 105*844d9543SConrad Meyer } 106*844d9543SConrad Meyer 107*844d9543SConrad Meyer static inline uint32_t 108*844d9543SConrad Meyer ccp_read_queue_4(struct ccp_softc *sc, unsigned queue, uint32_t offset) 109*844d9543SConrad Meyer { 110*844d9543SConrad Meyer /* 111*844d9543SConrad Meyer * Each queue gets its own 4kB register space. Queue 0 is at 0x1000. 112*844d9543SConrad Meyer */ 113*844d9543SConrad Meyer return (ccp_read_4(sc, (CMD_Q_STATUS_INCR * (1 + queue)) + offset)); 114*844d9543SConrad Meyer } 115*844d9543SConrad Meyer 116*844d9543SConrad Meyer static inline void 117*844d9543SConrad Meyer ccp_write_queue_4(struct ccp_softc *sc, unsigned queue, uint32_t offset, 118*844d9543SConrad Meyer uint32_t value) 119*844d9543SConrad Meyer { 120*844d9543SConrad Meyer ccp_write_4(sc, (CMD_Q_STATUS_INCR * (1 + queue)) + offset, value); 121*844d9543SConrad Meyer } 122*844d9543SConrad Meyer 123*844d9543SConrad Meyer void 124*844d9543SConrad Meyer ccp_queue_write_tail(struct ccp_queue *qp) 125*844d9543SConrad Meyer { 126*844d9543SConrad Meyer ccp_write_queue_4(qp->cq_softc, qp->cq_qindex, CMD_Q_TAIL_LO_BASE, 127*844d9543SConrad Meyer ((uint32_t)qp->desc_ring_bus_addr) + (Q_DESC_SIZE * qp->cq_tail)); 128*844d9543SConrad Meyer } 129*844d9543SConrad Meyer 130*844d9543SConrad Meyer /* 131*844d9543SConrad Meyer * Given a queue and a reserved LSB entry index, compute the LSB *entry id* of 132*844d9543SConrad Meyer * that entry for the queue's private LSB region. 133*844d9543SConrad Meyer */ 134*844d9543SConrad Meyer static inline uint8_t 135*844d9543SConrad Meyer ccp_queue_lsb_entry(struct ccp_queue *qp, unsigned lsb_entry) 136*844d9543SConrad Meyer { 137*844d9543SConrad Meyer return ((qp->private_lsb * LSB_REGION_LENGTH + lsb_entry)); 138*844d9543SConrad Meyer } 139*844d9543SConrad Meyer 140*844d9543SConrad Meyer /* 141*844d9543SConrad Meyer * Given a queue and a reserved LSB entry index, compute the LSB *address* of 142*844d9543SConrad Meyer * that entry for the queue's private LSB region. 143*844d9543SConrad Meyer */ 144*844d9543SConrad Meyer static inline uint32_t 145*844d9543SConrad Meyer ccp_queue_lsb_address(struct ccp_queue *qp, unsigned lsb_entry) 146*844d9543SConrad Meyer { 147*844d9543SConrad Meyer return (ccp_queue_lsb_entry(qp, lsb_entry) * LSB_ENTRY_SIZE); 148*844d9543SConrad Meyer } 149*844d9543SConrad Meyer 150*844d9543SConrad Meyer /* 151*844d9543SConrad Meyer * Some terminology: 152*844d9543SConrad Meyer * 153*844d9543SConrad Meyer * LSB - Local Storage Block 154*844d9543SConrad Meyer * ========================= 155*844d9543SConrad Meyer * 156*844d9543SConrad Meyer * 8 segments/regions, each containing 16 entries. 157*844d9543SConrad Meyer * 158*844d9543SConrad Meyer * Each entry contains 256 bits (32 bytes). 159*844d9543SConrad Meyer * 160*844d9543SConrad Meyer * Segments are virtually addressed in commands, but accesses cannot cross 161*844d9543SConrad Meyer * segment boundaries. Virtual map uses an identity mapping by default 162*844d9543SConrad Meyer * (virtual segment N corresponds to physical segment N). 163*844d9543SConrad Meyer * 164*844d9543SConrad Meyer * Access to a physical region can be restricted to any subset of all five 165*844d9543SConrad Meyer * queues. 166*844d9543SConrad Meyer * 167*844d9543SConrad Meyer * "Pass-through" mode 168*844d9543SConrad Meyer * =================== 169*844d9543SConrad Meyer * 170*844d9543SConrad Meyer * Pass-through is a generic DMA engine, much like ioat(4). Some nice 171*844d9543SConrad Meyer * features: 172*844d9543SConrad Meyer * 173*844d9543SConrad Meyer * - Supports byte-swapping for endian conversion (32- or 256-bit words) 174*844d9543SConrad Meyer * - AND, OR, XOR with fixed 256-bit mask 175*844d9543SConrad Meyer * - CRC32 of data (may be used in tandem with bswap, but not bit operations) 176*844d9543SConrad Meyer * - Read/write of LSB 177*844d9543SConrad Meyer * - Memset 178*844d9543SConrad Meyer * 179*844d9543SConrad Meyer * If bit manipulation mode is enabled, input must be a multiple of 256 bits 180*844d9543SConrad Meyer * (32 bytes). 181*844d9543SConrad Meyer * 182*844d9543SConrad Meyer * If byte-swapping is enabled, input must be a multiple of the word size. 183*844d9543SConrad Meyer * 184*844d9543SConrad Meyer * Zlib mode -- only usable from one queue at a time, single job at a time. 185*844d9543SConrad Meyer * ======================================================================== 186*844d9543SConrad Meyer * 187*844d9543SConrad Meyer * Only usable from private host, aka PSP? Not host processor? 188*844d9543SConrad Meyer * 189*844d9543SConrad Meyer * RNG. 190*844d9543SConrad Meyer * ==== 191*844d9543SConrad Meyer * 192*844d9543SConrad Meyer * Raw bits are conditioned with AES and fed through CTR_DRBG. Output goes in 193*844d9543SConrad Meyer * a ring buffer readable by software. 194*844d9543SConrad Meyer * 195*844d9543SConrad Meyer * NIST SP 800-90B Repetition Count and Adaptive Proportion health checks are 196*844d9543SConrad Meyer * implemented on the raw input stream and may be enabled to verify min-entropy 197*844d9543SConrad Meyer * of 0.5 bits per bit. 198*844d9543SConrad Meyer */ 199*844d9543SConrad Meyer 200*844d9543SConrad Meyer static void 201*844d9543SConrad Meyer ccp_dmamap_cb(void *arg, bus_dma_segment_t *segs, int nseg, int error) 202*844d9543SConrad Meyer { 203*844d9543SConrad Meyer bus_addr_t *baddr; 204*844d9543SConrad Meyer 205*844d9543SConrad Meyer KASSERT(error == 0, ("%s: error:%d", __func__, error)); 206*844d9543SConrad Meyer baddr = arg; 207*844d9543SConrad Meyer *baddr = segs->ds_addr; 208*844d9543SConrad Meyer } 209*844d9543SConrad Meyer 210*844d9543SConrad Meyer static int 211*844d9543SConrad Meyer ccp_hw_attach_queue(device_t dev, uint64_t lsbmask, unsigned queue) 212*844d9543SConrad Meyer { 213*844d9543SConrad Meyer struct ccp_softc *sc; 214*844d9543SConrad Meyer struct ccp_queue *qp; 215*844d9543SConrad Meyer void *desc; 216*844d9543SConrad Meyer size_t ringsz, num_descriptors; 217*844d9543SConrad Meyer int error; 218*844d9543SConrad Meyer 219*844d9543SConrad Meyer desc = NULL; 220*844d9543SConrad Meyer sc = device_get_softc(dev); 221*844d9543SConrad Meyer qp = &sc->queues[queue]; 222*844d9543SConrad Meyer 223*844d9543SConrad Meyer /* 224*844d9543SConrad Meyer * Don't bother allocating a ring for queues the host isn't allowed to 225*844d9543SConrad Meyer * drive. 226*844d9543SConrad Meyer */ 227*844d9543SConrad Meyer if ((sc->valid_queues & (1 << queue)) == 0) 228*844d9543SConrad Meyer return (0); 229*844d9543SConrad Meyer 230*844d9543SConrad Meyer ccp_queue_decode_lsb_regions(sc, lsbmask, queue); 231*844d9543SConrad Meyer 232*844d9543SConrad Meyer /* Ignore queues that do not have any LSB access. */ 233*844d9543SConrad Meyer if (qp->lsb_mask == 0) { 234*844d9543SConrad Meyer device_printf(dev, "Ignoring queue %u with no LSB access\n", 235*844d9543SConrad Meyer queue); 236*844d9543SConrad Meyer sc->valid_queues &= ~(1 << queue); 237*844d9543SConrad Meyer return (0); 238*844d9543SConrad Meyer } 239*844d9543SConrad Meyer 240*844d9543SConrad Meyer num_descriptors = 1 << sc->ring_size_order; 241*844d9543SConrad Meyer ringsz = sizeof(struct ccp_desc) * num_descriptors; 242*844d9543SConrad Meyer 243*844d9543SConrad Meyer /* 244*844d9543SConrad Meyer * "Queue_Size" is order - 1. 245*844d9543SConrad Meyer * 246*844d9543SConrad Meyer * Queue must be aligned to 5+Queue_Size+1 == 5 + order bits. 247*844d9543SConrad Meyer */ 248*844d9543SConrad Meyer error = bus_dma_tag_create(bus_get_dma_tag(dev), 249*844d9543SConrad Meyer 1 << (5 + sc->ring_size_order), 250*844d9543SConrad Meyer #if defined(__i386__) && !defined(PAE) 251*844d9543SConrad Meyer 0, BUS_SPACE_MAXADDR, 252*844d9543SConrad Meyer #else 253*844d9543SConrad Meyer (bus_addr_t)1 << 32, BUS_SPACE_MAXADDR_48BIT, 254*844d9543SConrad Meyer #endif 255*844d9543SConrad Meyer BUS_SPACE_MAXADDR, NULL, NULL, ringsz, 1, 256*844d9543SConrad Meyer ringsz, 0, NULL, NULL, &qp->ring_desc_tag); 257*844d9543SConrad Meyer if (error != 0) 258*844d9543SConrad Meyer goto out; 259*844d9543SConrad Meyer 260*844d9543SConrad Meyer error = bus_dmamem_alloc(qp->ring_desc_tag, &desc, 261*844d9543SConrad Meyer BUS_DMA_ZERO | BUS_DMA_WAITOK, &qp->ring_desc_map); 262*844d9543SConrad Meyer if (error != 0) 263*844d9543SConrad Meyer goto out; 264*844d9543SConrad Meyer 265*844d9543SConrad Meyer error = bus_dmamap_load(qp->ring_desc_tag, qp->ring_desc_map, desc, 266*844d9543SConrad Meyer ringsz, ccp_dmamap_cb, &qp->desc_ring_bus_addr, BUS_DMA_WAITOK); 267*844d9543SConrad Meyer if (error != 0) 268*844d9543SConrad Meyer goto out; 269*844d9543SConrad Meyer 270*844d9543SConrad Meyer qp->desc_ring = desc; 271*844d9543SConrad Meyer qp->completions_ring = malloc(num_descriptors * 272*844d9543SConrad Meyer sizeof(*qp->completions_ring), M_CCP, M_ZERO | M_WAITOK); 273*844d9543SConrad Meyer 274*844d9543SConrad Meyer /* Zero control register; among other things, clears the RUN flag. */ 275*844d9543SConrad Meyer qp->qcontrol = 0; 276*844d9543SConrad Meyer ccp_write_queue_4(sc, queue, CMD_Q_CONTROL_BASE, qp->qcontrol); 277*844d9543SConrad Meyer ccp_write_queue_4(sc, queue, CMD_Q_INT_ENABLE_BASE, 0); 278*844d9543SConrad Meyer 279*844d9543SConrad Meyer /* Clear any leftover interrupt status flags */ 280*844d9543SConrad Meyer ccp_write_queue_4(sc, queue, CMD_Q_INTERRUPT_STATUS_BASE, 281*844d9543SConrad Meyer ALL_INTERRUPTS); 282*844d9543SConrad Meyer 283*844d9543SConrad Meyer qp->qcontrol |= (sc->ring_size_order - 1) << CMD_Q_SIZE_SHIFT; 284*844d9543SConrad Meyer 285*844d9543SConrad Meyer ccp_write_queue_4(sc, queue, CMD_Q_TAIL_LO_BASE, 286*844d9543SConrad Meyer (uint32_t)qp->desc_ring_bus_addr); 287*844d9543SConrad Meyer ccp_write_queue_4(sc, queue, CMD_Q_HEAD_LO_BASE, 288*844d9543SConrad Meyer (uint32_t)qp->desc_ring_bus_addr); 289*844d9543SConrad Meyer 290*844d9543SConrad Meyer /* 291*844d9543SConrad Meyer * Enable completion interrupts, as well as error or administrative 292*844d9543SConrad Meyer * halt interrupts. We don't use administrative halts, but they 293*844d9543SConrad Meyer * shouldn't trip unless we do, so it ought to be harmless. 294*844d9543SConrad Meyer */ 295*844d9543SConrad Meyer ccp_write_queue_4(sc, queue, CMD_Q_INT_ENABLE_BASE, 296*844d9543SConrad Meyer INT_COMPLETION | INT_ERROR | INT_QUEUE_STOPPED); 297*844d9543SConrad Meyer 298*844d9543SConrad Meyer qp->qcontrol |= (qp->desc_ring_bus_addr >> 32) << CMD_Q_PTR_HI_SHIFT; 299*844d9543SConrad Meyer qp->qcontrol |= CMD_Q_RUN; 300*844d9543SConrad Meyer ccp_write_queue_4(sc, queue, CMD_Q_CONTROL_BASE, qp->qcontrol); 301*844d9543SConrad Meyer 302*844d9543SConrad Meyer out: 303*844d9543SConrad Meyer if (error != 0) { 304*844d9543SConrad Meyer if (qp->desc_ring != NULL) 305*844d9543SConrad Meyer bus_dmamap_unload(qp->ring_desc_tag, 306*844d9543SConrad Meyer qp->ring_desc_map); 307*844d9543SConrad Meyer if (desc != NULL) 308*844d9543SConrad Meyer bus_dmamem_free(qp->ring_desc_tag, desc, 309*844d9543SConrad Meyer qp->ring_desc_map); 310*844d9543SConrad Meyer if (qp->ring_desc_tag != NULL) 311*844d9543SConrad Meyer bus_dma_tag_destroy(qp->ring_desc_tag); 312*844d9543SConrad Meyer } 313*844d9543SConrad Meyer return (error); 314*844d9543SConrad Meyer } 315*844d9543SConrad Meyer 316*844d9543SConrad Meyer static void 317*844d9543SConrad Meyer ccp_hw_detach_queue(device_t dev, unsigned queue) 318*844d9543SConrad Meyer { 319*844d9543SConrad Meyer struct ccp_softc *sc; 320*844d9543SConrad Meyer struct ccp_queue *qp; 321*844d9543SConrad Meyer 322*844d9543SConrad Meyer sc = device_get_softc(dev); 323*844d9543SConrad Meyer qp = &sc->queues[queue]; 324*844d9543SConrad Meyer 325*844d9543SConrad Meyer /* 326*844d9543SConrad Meyer * Don't bother allocating a ring for queues the host isn't allowed to 327*844d9543SConrad Meyer * drive. 328*844d9543SConrad Meyer */ 329*844d9543SConrad Meyer if ((sc->valid_queues & (1 << queue)) == 0) 330*844d9543SConrad Meyer return; 331*844d9543SConrad Meyer 332*844d9543SConrad Meyer free(qp->completions_ring, M_CCP); 333*844d9543SConrad Meyer bus_dmamap_unload(qp->ring_desc_tag, qp->ring_desc_map); 334*844d9543SConrad Meyer bus_dmamem_free(qp->ring_desc_tag, qp->desc_ring, qp->ring_desc_map); 335*844d9543SConrad Meyer bus_dma_tag_destroy(qp->ring_desc_tag); 336*844d9543SConrad Meyer } 337*844d9543SConrad Meyer 338*844d9543SConrad Meyer static int 339*844d9543SConrad Meyer ccp_map_pci_bar(device_t dev) 340*844d9543SConrad Meyer { 341*844d9543SConrad Meyer struct ccp_softc *sc; 342*844d9543SConrad Meyer 343*844d9543SConrad Meyer sc = device_get_softc(dev); 344*844d9543SConrad Meyer 345*844d9543SConrad Meyer sc->pci_resource_id = PCIR_BAR(2); 346*844d9543SConrad Meyer sc->pci_resource = bus_alloc_resource_any(dev, SYS_RES_MEMORY, 347*844d9543SConrad Meyer &sc->pci_resource_id, RF_ACTIVE); 348*844d9543SConrad Meyer if (sc->pci_resource == NULL) { 349*844d9543SConrad Meyer device_printf(dev, "unable to allocate pci resource\n"); 350*844d9543SConrad Meyer return (ENODEV); 351*844d9543SConrad Meyer } 352*844d9543SConrad Meyer 353*844d9543SConrad Meyer sc->pci_resource_id_msix = PCIR_BAR(5); 354*844d9543SConrad Meyer sc->pci_resource_msix = bus_alloc_resource_any(dev, SYS_RES_MEMORY, 355*844d9543SConrad Meyer &sc->pci_resource_id_msix, RF_ACTIVE); 356*844d9543SConrad Meyer if (sc->pci_resource_msix == NULL) { 357*844d9543SConrad Meyer device_printf(dev, "unable to allocate pci resource msix\n"); 358*844d9543SConrad Meyer bus_release_resource(dev, SYS_RES_MEMORY, sc->pci_resource_id, 359*844d9543SConrad Meyer sc->pci_resource); 360*844d9543SConrad Meyer return (ENODEV); 361*844d9543SConrad Meyer } 362*844d9543SConrad Meyer 363*844d9543SConrad Meyer sc->pci_bus_tag = rman_get_bustag(sc->pci_resource); 364*844d9543SConrad Meyer sc->pci_bus_handle = rman_get_bushandle(sc->pci_resource); 365*844d9543SConrad Meyer return (0); 366*844d9543SConrad Meyer } 367*844d9543SConrad Meyer 368*844d9543SConrad Meyer static void 369*844d9543SConrad Meyer ccp_unmap_pci_bar(device_t dev) 370*844d9543SConrad Meyer { 371*844d9543SConrad Meyer struct ccp_softc *sc; 372*844d9543SConrad Meyer 373*844d9543SConrad Meyer sc = device_get_softc(dev); 374*844d9543SConrad Meyer 375*844d9543SConrad Meyer bus_release_resource(dev, SYS_RES_MEMORY, sc->pci_resource_id_msix, 376*844d9543SConrad Meyer sc->pci_resource_msix); 377*844d9543SConrad Meyer bus_release_resource(dev, SYS_RES_MEMORY, sc->pci_resource_id, 378*844d9543SConrad Meyer sc->pci_resource); 379*844d9543SConrad Meyer } 380*844d9543SConrad Meyer 381*844d9543SConrad Meyer const static struct ccp_error_code { 382*844d9543SConrad Meyer uint8_t ce_code; 383*844d9543SConrad Meyer const char *ce_name; 384*844d9543SConrad Meyer int ce_errno; 385*844d9543SConrad Meyer const char *ce_desc; 386*844d9543SConrad Meyer } ccp_error_codes[] = { 387*844d9543SConrad Meyer { 0x01, "ILLEGAL_ENGINE", EIO, "Requested engine was invalid" }, 388*844d9543SConrad Meyer { 0x03, "ILLEGAL_FUNCTION_TYPE", EIO, 389*844d9543SConrad Meyer "A non-supported function type was specified" }, 390*844d9543SConrad Meyer { 0x04, "ILLEGAL_FUNCTION_MODE", EIO, 391*844d9543SConrad Meyer "A non-supported function mode was specified" }, 392*844d9543SConrad Meyer { 0x05, "ILLEGAL_FUNCTION_ENCRYPT", EIO, 393*844d9543SConrad Meyer "A CMAC type was specified when ENCRYPT was not specified" }, 394*844d9543SConrad Meyer { 0x06, "ILLEGAL_FUNCTION_SIZE", EIO, 395*844d9543SConrad Meyer "A non-supported function size was specified.\n" 396*844d9543SConrad Meyer "AES-CFB: Size was not 127 or 7;\n" 397*844d9543SConrad Meyer "3DES-CFB: Size was not 7;\n" 398*844d9543SConrad Meyer "RSA: See supported size table (7.4.2);\n" 399*844d9543SConrad Meyer "ECC: Size was greater than 576 bits." }, 400*844d9543SConrad Meyer { 0x07, "Zlib_MISSING_INIT_EOM", EIO, 401*844d9543SConrad Meyer "Zlib command does not have INIT and EOM set" }, 402*844d9543SConrad Meyer { 0x08, "ILLEGAL_FUNCTION_RSVD", EIO, 403*844d9543SConrad Meyer "Reserved bits in a function specification were not 0" }, 404*844d9543SConrad Meyer { 0x09, "ILLEGAL_BUFFER_LENGTH", EIO, 405*844d9543SConrad Meyer "The buffer length specified was not correct for the selected engine" 406*844d9543SConrad Meyer }, 407*844d9543SConrad Meyer { 0x0A, "VLSB_FAULT", EIO, "Illegal VLSB segment mapping:\n" 408*844d9543SConrad Meyer "Undefined VLSB segment mapping or\n" 409*844d9543SConrad Meyer "mapping to unsupported LSB segment id" }, 410*844d9543SConrad Meyer { 0x0B, "ILLEGAL_MEM_ADDR", EFAULT, 411*844d9543SConrad Meyer "The specified source/destination buffer access was illegal:\n" 412*844d9543SConrad Meyer "Data buffer located in a LSB location disallowed by the LSB protection masks; or\n" 413*844d9543SConrad Meyer "Data buffer not completely contained within a single segment; or\n" 414*844d9543SConrad Meyer "Pointer with Fixed=1 is not 32-bit aligned; or\n" 415*844d9543SConrad Meyer "Pointer with Fixed=1 attempted to reference non-AXI1 (local) memory." 416*844d9543SConrad Meyer }, 417*844d9543SConrad Meyer { 0x0C, "ILLEGAL_MEM_SEL", EIO, 418*844d9543SConrad Meyer "A src_mem, dst_mem, or key_mem field was illegal:\n" 419*844d9543SConrad Meyer "A field was set to a reserved value; or\n" 420*844d9543SConrad Meyer "A public command attempted to reference AXI1 (local) or GART memory; or\n" 421*844d9543SConrad Meyer "A Zlib command attmpted to use the LSB." }, 422*844d9543SConrad Meyer { 0x0D, "ILLEGAL_CONTEXT_ADDR", EIO, 423*844d9543SConrad Meyer "The specified context location was illegal:\n" 424*844d9543SConrad Meyer "Context located in a LSB location disallowed by the LSB protection masks; or\n" 425*844d9543SConrad Meyer "Context not completely contained within a single segment." }, 426*844d9543SConrad Meyer { 0x0E, "ILLEGAL_KEY_ADDR", EIO, 427*844d9543SConrad Meyer "The specified key location was illegal:\n" 428*844d9543SConrad Meyer "Key located in a LSB location disallowed by the LSB protection masks; or\n" 429*844d9543SConrad Meyer "Key not completely contained within a single segment." }, 430*844d9543SConrad Meyer { 0x12, "CMD_TIMEOUT", EIO, "A command timeout violation occurred" }, 431*844d9543SConrad Meyer /* XXX Could fill out these descriptions too */ 432*844d9543SConrad Meyer { 0x13, "IDMA0_AXI_SLVERR", EIO, "" }, 433*844d9543SConrad Meyer { 0x14, "IDMA0_AXI_DECERR", EIO, "" }, 434*844d9543SConrad Meyer { 0x16, "IDMA1_AXI_SLVERR", EIO, "" }, 435*844d9543SConrad Meyer { 0x17, "IDMA1_AXI_DECERR", EIO, "" }, 436*844d9543SConrad Meyer { 0x19, "ZLIBVHB_AXI_SLVERR", EIO, "" }, 437*844d9543SConrad Meyer { 0x1A, "ZLIBVHB_AXI_DECERR", EIO, "" }, 438*844d9543SConrad Meyer { 0x1C, "ZLIB_UNEXPECTED_EOM", EIO, "" }, 439*844d9543SConrad Meyer { 0x1D, "ZLIB_EXTRA_DATA", EIO, "" }, 440*844d9543SConrad Meyer { 0x1E, "ZLIB_BTYPE", EIO, "" }, 441*844d9543SConrad Meyer { 0x20, "ZLIB_UNDEFINED_DISTANCE_SYMBOL", EIO, "" }, 442*844d9543SConrad Meyer { 0x21, "ZLIB_CODE_LENGTH_SYMBOL", EIO, "" }, 443*844d9543SConrad Meyer { 0x22, "ZLIB_VHB_ILLEGAL_FETCH", EIO, "" }, 444*844d9543SConrad Meyer { 0x23, "ZLIB_UNCOMPRESSED_LEN", EIO, "" }, 445*844d9543SConrad Meyer { 0x24, "ZLIB_LIMIT_REACHED", EIO, "" }, 446*844d9543SConrad Meyer { 0x25, "ZLIB_CHECKSUM_MISMATCH", EIO, "" }, 447*844d9543SConrad Meyer { 0x26, "ODMA0_AXI_SLVERR", EIO, "" }, 448*844d9543SConrad Meyer { 0x27, "ODMA0_AXI_DECERR", EIO, "" }, 449*844d9543SConrad Meyer { 0x29, "ODMA1_AXI_SLVERR", EIO, "" }, 450*844d9543SConrad Meyer { 0x2A, "ODMA1_AXI_DECERR", EIO, "" }, 451*844d9543SConrad Meyer { 0x2B, "LSB_PARITY_ERR", EIO, 452*844d9543SConrad Meyer "A read from the LSB encountered a parity error" }, 453*844d9543SConrad Meyer }; 454*844d9543SConrad Meyer 455*844d9543SConrad Meyer static void 456*844d9543SConrad Meyer ccp_intr_handle_error(struct ccp_queue *qp, const struct ccp_desc *desc) 457*844d9543SConrad Meyer { 458*844d9543SConrad Meyer struct ccp_completion_ctx *cctx; 459*844d9543SConrad Meyer const struct ccp_error_code *ec; 460*844d9543SConrad Meyer struct ccp_softc *sc; 461*844d9543SConrad Meyer uint32_t status, error, esource, faultblock; 462*844d9543SConrad Meyer unsigned q, idx; 463*844d9543SConrad Meyer int errno; 464*844d9543SConrad Meyer 465*844d9543SConrad Meyer sc = qp->cq_softc; 466*844d9543SConrad Meyer q = qp->cq_qindex; 467*844d9543SConrad Meyer 468*844d9543SConrad Meyer status = ccp_read_queue_4(sc, q, CMD_Q_STATUS_BASE); 469*844d9543SConrad Meyer 470*844d9543SConrad Meyer error = status & STATUS_ERROR_MASK; 471*844d9543SConrad Meyer 472*844d9543SConrad Meyer /* Decode error status */ 473*844d9543SConrad Meyer ec = NULL; 474*844d9543SConrad Meyer for (idx = 0; idx < nitems(ccp_error_codes); idx++) 475*844d9543SConrad Meyer if (ccp_error_codes[idx].ce_code == error) { 476*844d9543SConrad Meyer ec = &ccp_error_codes[idx]; 477*844d9543SConrad Meyer break; 478*844d9543SConrad Meyer } 479*844d9543SConrad Meyer 480*844d9543SConrad Meyer esource = (status >> STATUS_ERRORSOURCE_SHIFT) & 481*844d9543SConrad Meyer STATUS_ERRORSOURCE_MASK; 482*844d9543SConrad Meyer faultblock = (status >> STATUS_VLSB_FAULTBLOCK_SHIFT) & 483*844d9543SConrad Meyer STATUS_VLSB_FAULTBLOCK_MASK; 484*844d9543SConrad Meyer device_printf(sc->dev, "Error: %s (%u) Source: %u Faulting LSB block: %u\n", 485*844d9543SConrad Meyer (ec != NULL) ? ec->ce_name : "(reserved)", error, esource, 486*844d9543SConrad Meyer faultblock); 487*844d9543SConrad Meyer if (ec != NULL) 488*844d9543SConrad Meyer device_printf(sc->dev, "Error description: %s\n", ec->ce_desc); 489*844d9543SConrad Meyer 490*844d9543SConrad Meyer /* TODO Could format the desc nicely here */ 491*844d9543SConrad Meyer idx = desc - qp->desc_ring; 492*844d9543SConrad Meyer DPRINTF(sc->dev, "Bad descriptor index: %u contents: %32D\n", idx, 493*844d9543SConrad Meyer (const void *)desc, " "); 494*844d9543SConrad Meyer 495*844d9543SConrad Meyer /* 496*844d9543SConrad Meyer * TODO Per § 14.4 "Error Handling," DMA_Status, DMA_Read/Write_Status, 497*844d9543SConrad Meyer * Zlib Decompress status may be interesting. 498*844d9543SConrad Meyer */ 499*844d9543SConrad Meyer 500*844d9543SConrad Meyer while (true) { 501*844d9543SConrad Meyer /* Keep unused descriptors zero for next use. */ 502*844d9543SConrad Meyer memset(&qp->desc_ring[idx], 0, sizeof(qp->desc_ring[idx])); 503*844d9543SConrad Meyer 504*844d9543SConrad Meyer cctx = &qp->completions_ring[idx]; 505*844d9543SConrad Meyer 506*844d9543SConrad Meyer /* 507*844d9543SConrad Meyer * Restart procedure described in § 14.2.5. Could be used by HoC if we 508*844d9543SConrad Meyer * used that. 509*844d9543SConrad Meyer * 510*844d9543SConrad Meyer * Advance HEAD_LO past bad descriptor + any remaining in 511*844d9543SConrad Meyer * transaction manually, then restart queue. 512*844d9543SConrad Meyer */ 513*844d9543SConrad Meyer idx = (idx + 1) % (1 << sc->ring_size_order); 514*844d9543SConrad Meyer 515*844d9543SConrad Meyer /* Callback function signals end of transaction */ 516*844d9543SConrad Meyer if (cctx->callback_fn != NULL) { 517*844d9543SConrad Meyer if (ec == NULL) 518*844d9543SConrad Meyer errno = EIO; 519*844d9543SConrad Meyer else 520*844d9543SConrad Meyer errno = ec->ce_errno; 521*844d9543SConrad Meyer /* TODO More specific error code */ 522*844d9543SConrad Meyer cctx->callback_fn(qp, cctx->session, cctx->callback_arg, errno); 523*844d9543SConrad Meyer cctx->callback_fn = NULL; 524*844d9543SConrad Meyer break; 525*844d9543SConrad Meyer } 526*844d9543SConrad Meyer } 527*844d9543SConrad Meyer 528*844d9543SConrad Meyer qp->cq_head = idx; 529*844d9543SConrad Meyer qp->cq_waiting = false; 530*844d9543SConrad Meyer wakeup(&qp->cq_tail); 531*844d9543SConrad Meyer DPRINTF(sc->dev, "%s: wrote sw head:%u\n", __func__, qp->cq_head); 532*844d9543SConrad Meyer ccp_write_queue_4(sc, q, CMD_Q_HEAD_LO_BASE, 533*844d9543SConrad Meyer (uint32_t)qp->desc_ring_bus_addr + (idx * Q_DESC_SIZE)); 534*844d9543SConrad Meyer ccp_write_queue_4(sc, q, CMD_Q_CONTROL_BASE, qp->qcontrol); 535*844d9543SConrad Meyer DPRINTF(sc->dev, "%s: Restarted queue\n", __func__); 536*844d9543SConrad Meyer } 537*844d9543SConrad Meyer 538*844d9543SConrad Meyer static void 539*844d9543SConrad Meyer ccp_intr_run_completions(struct ccp_queue *qp, uint32_t ints) 540*844d9543SConrad Meyer { 541*844d9543SConrad Meyer struct ccp_completion_ctx *cctx; 542*844d9543SConrad Meyer struct ccp_softc *sc; 543*844d9543SConrad Meyer const struct ccp_desc *desc; 544*844d9543SConrad Meyer uint32_t headlo, idx; 545*844d9543SConrad Meyer unsigned q, completed; 546*844d9543SConrad Meyer 547*844d9543SConrad Meyer sc = qp->cq_softc; 548*844d9543SConrad Meyer q = qp->cq_qindex; 549*844d9543SConrad Meyer 550*844d9543SConrad Meyer mtx_lock(&qp->cq_lock); 551*844d9543SConrad Meyer 552*844d9543SConrad Meyer /* 553*844d9543SConrad Meyer * Hardware HEAD_LO points to the first incomplete descriptor. Process 554*844d9543SConrad Meyer * any submitted and completed descriptors, up to but not including 555*844d9543SConrad Meyer * HEAD_LO. 556*844d9543SConrad Meyer */ 557*844d9543SConrad Meyer headlo = ccp_read_queue_4(sc, q, CMD_Q_HEAD_LO_BASE); 558*844d9543SConrad Meyer idx = (headlo - (uint32_t)qp->desc_ring_bus_addr) / Q_DESC_SIZE; 559*844d9543SConrad Meyer 560*844d9543SConrad Meyer DPRINTF(sc->dev, "%s: hw head:%u sw head:%u\n", __func__, idx, 561*844d9543SConrad Meyer qp->cq_head); 562*844d9543SConrad Meyer completed = 0; 563*844d9543SConrad Meyer while (qp->cq_head != idx) { 564*844d9543SConrad Meyer DPRINTF(sc->dev, "%s: completing:%u\n", __func__, qp->cq_head); 565*844d9543SConrad Meyer 566*844d9543SConrad Meyer cctx = &qp->completions_ring[qp->cq_head]; 567*844d9543SConrad Meyer if (cctx->callback_fn != NULL) { 568*844d9543SConrad Meyer cctx->callback_fn(qp, cctx->session, 569*844d9543SConrad Meyer cctx->callback_arg, 0); 570*844d9543SConrad Meyer cctx->callback_fn = NULL; 571*844d9543SConrad Meyer } 572*844d9543SConrad Meyer 573*844d9543SConrad Meyer /* Keep unused descriptors zero for next use. */ 574*844d9543SConrad Meyer memset(&qp->desc_ring[qp->cq_head], 0, 575*844d9543SConrad Meyer sizeof(qp->desc_ring[qp->cq_head])); 576*844d9543SConrad Meyer 577*844d9543SConrad Meyer qp->cq_head = (qp->cq_head + 1) % (1 << sc->ring_size_order); 578*844d9543SConrad Meyer completed++; 579*844d9543SConrad Meyer } 580*844d9543SConrad Meyer if (completed > 0) { 581*844d9543SConrad Meyer qp->cq_waiting = false; 582*844d9543SConrad Meyer wakeup(&qp->cq_tail); 583*844d9543SConrad Meyer } 584*844d9543SConrad Meyer 585*844d9543SConrad Meyer DPRINTF(sc->dev, "%s: wrote sw head:%u\n", __func__, qp->cq_head); 586*844d9543SConrad Meyer 587*844d9543SConrad Meyer /* 588*844d9543SConrad Meyer * Desc points to the first incomplete descriptor, at the time we read 589*844d9543SConrad Meyer * HEAD_LO. If there was an error flagged in interrupt status, the HW 590*844d9543SConrad Meyer * will not proceed past the erroneous descriptor by itself. 591*844d9543SConrad Meyer */ 592*844d9543SConrad Meyer desc = &qp->desc_ring[idx]; 593*844d9543SConrad Meyer if ((ints & INT_ERROR) != 0) 594*844d9543SConrad Meyer ccp_intr_handle_error(qp, desc); 595*844d9543SConrad Meyer 596*844d9543SConrad Meyer mtx_unlock(&qp->cq_lock); 597*844d9543SConrad Meyer } 598*844d9543SConrad Meyer 599*844d9543SConrad Meyer static void 600*844d9543SConrad Meyer ccp_intr_handler(void *arg) 601*844d9543SConrad Meyer { 602*844d9543SConrad Meyer struct ccp_softc *sc = arg; 603*844d9543SConrad Meyer size_t i; 604*844d9543SConrad Meyer uint32_t ints; 605*844d9543SConrad Meyer 606*844d9543SConrad Meyer DPRINTF(sc->dev, "%s: interrupt\n", __func__); 607*844d9543SConrad Meyer 608*844d9543SConrad Meyer /* 609*844d9543SConrad Meyer * We get one global interrupt per PCI device, shared over all of 610*844d9543SConrad Meyer * its queues. Scan each valid queue on interrupt for flags indicating 611*844d9543SConrad Meyer * activity. 612*844d9543SConrad Meyer */ 613*844d9543SConrad Meyer for (i = 0; i < nitems(sc->queues); i++) { 614*844d9543SConrad Meyer if ((sc->valid_queues & (1 << i)) == 0) 615*844d9543SConrad Meyer continue; 616*844d9543SConrad Meyer 617*844d9543SConrad Meyer ints = ccp_read_queue_4(sc, i, CMD_Q_INTERRUPT_STATUS_BASE); 618*844d9543SConrad Meyer if (ints == 0) 619*844d9543SConrad Meyer continue; 620*844d9543SConrad Meyer 621*844d9543SConrad Meyer #if 0 622*844d9543SConrad Meyer DPRINTF(sc->dev, "%s: %x interrupts on queue %zu\n", __func__, 623*844d9543SConrad Meyer (unsigned)ints, i); 624*844d9543SConrad Meyer #endif 625*844d9543SConrad Meyer /* Write back 1s to clear interrupt status bits. */ 626*844d9543SConrad Meyer ccp_write_queue_4(sc, i, CMD_Q_INTERRUPT_STATUS_BASE, ints); 627*844d9543SConrad Meyer 628*844d9543SConrad Meyer /* 629*844d9543SConrad Meyer * If there was an error, we still need to run completions on 630*844d9543SConrad Meyer * any descriptors prior to the error. The completions handler 631*844d9543SConrad Meyer * invoked below will also handle the error descriptor. 632*844d9543SConrad Meyer */ 633*844d9543SConrad Meyer if ((ints & (INT_COMPLETION | INT_ERROR)) != 0) 634*844d9543SConrad Meyer ccp_intr_run_completions(&sc->queues[i], ints); 635*844d9543SConrad Meyer 636*844d9543SConrad Meyer if ((ints & INT_QUEUE_STOPPED) != 0) 637*844d9543SConrad Meyer device_printf(sc->dev, "%s: queue %zu stopped\n", 638*844d9543SConrad Meyer __func__, i); 639*844d9543SConrad Meyer } 640*844d9543SConrad Meyer 641*844d9543SConrad Meyer /* Re-enable interrupts after processing */ 642*844d9543SConrad Meyer for (i = 0; i < nitems(sc->queues); i++) { 643*844d9543SConrad Meyer if ((sc->valid_queues & (1 << i)) == 0) 644*844d9543SConrad Meyer continue; 645*844d9543SConrad Meyer ccp_write_queue_4(sc, i, CMD_Q_INT_ENABLE_BASE, 646*844d9543SConrad Meyer INT_COMPLETION | INT_ERROR | INT_QUEUE_STOPPED); 647*844d9543SConrad Meyer } 648*844d9543SConrad Meyer } 649*844d9543SConrad Meyer 650*844d9543SConrad Meyer static int 651*844d9543SConrad Meyer ccp_intr_filter(void *arg) 652*844d9543SConrad Meyer { 653*844d9543SConrad Meyer struct ccp_softc *sc = arg; 654*844d9543SConrad Meyer size_t i; 655*844d9543SConrad Meyer 656*844d9543SConrad Meyer /* TODO: Split individual queues into separate taskqueues? */ 657*844d9543SConrad Meyer for (i = 0; i < nitems(sc->queues); i++) { 658*844d9543SConrad Meyer if ((sc->valid_queues & (1 << i)) == 0) 659*844d9543SConrad Meyer continue; 660*844d9543SConrad Meyer 661*844d9543SConrad Meyer /* Mask interrupt until task completes */ 662*844d9543SConrad Meyer ccp_write_queue_4(sc, i, CMD_Q_INT_ENABLE_BASE, 0); 663*844d9543SConrad Meyer } 664*844d9543SConrad Meyer 665*844d9543SConrad Meyer return (FILTER_SCHEDULE_THREAD); 666*844d9543SConrad Meyer } 667*844d9543SConrad Meyer 668*844d9543SConrad Meyer static int 669*844d9543SConrad Meyer ccp_setup_interrupts(struct ccp_softc *sc) 670*844d9543SConrad Meyer { 671*844d9543SConrad Meyer uint32_t nvec; 672*844d9543SConrad Meyer int rid, error, n, ridcopy; 673*844d9543SConrad Meyer 674*844d9543SConrad Meyer n = pci_msix_count(sc->dev); 675*844d9543SConrad Meyer if (n < 1) { 676*844d9543SConrad Meyer device_printf(sc->dev, "%s: msix_count: %d\n", __func__, n); 677*844d9543SConrad Meyer return (ENXIO); 678*844d9543SConrad Meyer } 679*844d9543SConrad Meyer 680*844d9543SConrad Meyer nvec = n; 681*844d9543SConrad Meyer error = pci_alloc_msix(sc->dev, &nvec); 682*844d9543SConrad Meyer if (error != 0) { 683*844d9543SConrad Meyer device_printf(sc->dev, "%s: alloc_msix error: %d\n", __func__, 684*844d9543SConrad Meyer error); 685*844d9543SConrad Meyer return (error); 686*844d9543SConrad Meyer } 687*844d9543SConrad Meyer if (nvec < 1) { 688*844d9543SConrad Meyer device_printf(sc->dev, "%s: alloc_msix: 0 vectors\n", 689*844d9543SConrad Meyer __func__); 690*844d9543SConrad Meyer return (ENXIO); 691*844d9543SConrad Meyer } 692*844d9543SConrad Meyer if (nvec > nitems(sc->intr_res)) { 693*844d9543SConrad Meyer device_printf(sc->dev, "%s: too many vectors: %u\n", __func__, 694*844d9543SConrad Meyer nvec); 695*844d9543SConrad Meyer nvec = nitems(sc->intr_res); 696*844d9543SConrad Meyer } 697*844d9543SConrad Meyer 698*844d9543SConrad Meyer for (rid = 1; rid < 1 + nvec; rid++) { 699*844d9543SConrad Meyer ridcopy = rid; 700*844d9543SConrad Meyer sc->intr_res[rid - 1] = bus_alloc_resource_any(sc->dev, 701*844d9543SConrad Meyer SYS_RES_IRQ, &ridcopy, RF_ACTIVE); 702*844d9543SConrad Meyer if (sc->intr_res[rid - 1] == NULL) { 703*844d9543SConrad Meyer device_printf(sc->dev, "%s: Failed to alloc IRQ resource\n", 704*844d9543SConrad Meyer __func__); 705*844d9543SConrad Meyer return (ENXIO); 706*844d9543SConrad Meyer } 707*844d9543SConrad Meyer 708*844d9543SConrad Meyer sc->intr_tag[rid - 1] = NULL; 709*844d9543SConrad Meyer error = bus_setup_intr(sc->dev, sc->intr_res[rid - 1], 710*844d9543SConrad Meyer INTR_MPSAFE | INTR_TYPE_MISC, ccp_intr_filter, 711*844d9543SConrad Meyer ccp_intr_handler, sc, &sc->intr_tag[rid - 1]); 712*844d9543SConrad Meyer if (error != 0) 713*844d9543SConrad Meyer device_printf(sc->dev, "%s: setup_intr: %d\n", 714*844d9543SConrad Meyer __func__, error); 715*844d9543SConrad Meyer } 716*844d9543SConrad Meyer sc->intr_count = nvec; 717*844d9543SConrad Meyer 718*844d9543SConrad Meyer return (error); 719*844d9543SConrad Meyer } 720*844d9543SConrad Meyer 721*844d9543SConrad Meyer static void 722*844d9543SConrad Meyer ccp_release_interrupts(struct ccp_softc *sc) 723*844d9543SConrad Meyer { 724*844d9543SConrad Meyer unsigned i; 725*844d9543SConrad Meyer 726*844d9543SConrad Meyer for (i = 0; i < sc->intr_count; i++) { 727*844d9543SConrad Meyer if (sc->intr_tag[i] != NULL) 728*844d9543SConrad Meyer bus_teardown_intr(sc->dev, sc->intr_res[i], 729*844d9543SConrad Meyer sc->intr_tag[i]); 730*844d9543SConrad Meyer if (sc->intr_res[i] != NULL) 731*844d9543SConrad Meyer bus_release_resource(sc->dev, SYS_RES_IRQ, 732*844d9543SConrad Meyer rman_get_rid(sc->intr_res[i]), sc->intr_res[i]); 733*844d9543SConrad Meyer } 734*844d9543SConrad Meyer 735*844d9543SConrad Meyer pci_release_msi(sc->dev); 736*844d9543SConrad Meyer } 737*844d9543SConrad Meyer 738*844d9543SConrad Meyer int 739*844d9543SConrad Meyer ccp_hw_attach(device_t dev) 740*844d9543SConrad Meyer { 741*844d9543SConrad Meyer struct ccp_softc *sc; 742*844d9543SConrad Meyer uint64_t lsbmask; 743*844d9543SConrad Meyer uint32_t version, lsbmasklo, lsbmaskhi; 744*844d9543SConrad Meyer unsigned queue_idx, j; 745*844d9543SConrad Meyer int error; 746*844d9543SConrad Meyer bool bars_mapped, interrupts_setup; 747*844d9543SConrad Meyer 748*844d9543SConrad Meyer queue_idx = 0; 749*844d9543SConrad Meyer bars_mapped = interrupts_setup = false; 750*844d9543SConrad Meyer sc = device_get_softc(dev); 751*844d9543SConrad Meyer 752*844d9543SConrad Meyer error = ccp_map_pci_bar(dev); 753*844d9543SConrad Meyer if (error != 0) { 754*844d9543SConrad Meyer device_printf(dev, "%s: couldn't map BAR(s)\n", __func__); 755*844d9543SConrad Meyer goto out; 756*844d9543SConrad Meyer } 757*844d9543SConrad Meyer bars_mapped = true; 758*844d9543SConrad Meyer 759*844d9543SConrad Meyer error = pci_enable_busmaster(dev); 760*844d9543SConrad Meyer if (error != 0) { 761*844d9543SConrad Meyer device_printf(dev, "%s: couldn't enable busmaster\n", 762*844d9543SConrad Meyer __func__); 763*844d9543SConrad Meyer goto out; 764*844d9543SConrad Meyer } 765*844d9543SConrad Meyer 766*844d9543SConrad Meyer sc->ring_size_order = g_ccp_ring_order; 767*844d9543SConrad Meyer if (sc->ring_size_order < 6 || sc->ring_size_order > 16) { 768*844d9543SConrad Meyer device_printf(dev, "bogus hw.ccp.ring_order\n"); 769*844d9543SConrad Meyer error = EINVAL; 770*844d9543SConrad Meyer goto out; 771*844d9543SConrad Meyer } 772*844d9543SConrad Meyer sc->valid_queues = ccp_read_4(sc, CMD_QUEUE_MASK_OFFSET); 773*844d9543SConrad Meyer 774*844d9543SConrad Meyer version = ccp_read_4(sc, VERSION_REG); 775*844d9543SConrad Meyer if ((version & VERSION_NUM_MASK) < 5) { 776*844d9543SConrad Meyer device_printf(dev, 777*844d9543SConrad Meyer "driver supports version 5 and later hardware\n"); 778*844d9543SConrad Meyer error = ENXIO; 779*844d9543SConrad Meyer goto out; 780*844d9543SConrad Meyer } 781*844d9543SConrad Meyer 782*844d9543SConrad Meyer error = ccp_setup_interrupts(sc); 783*844d9543SConrad Meyer if (error != 0) 784*844d9543SConrad Meyer goto out; 785*844d9543SConrad Meyer interrupts_setup = true; 786*844d9543SConrad Meyer 787*844d9543SConrad Meyer sc->hw_version = version & VERSION_NUM_MASK; 788*844d9543SConrad Meyer sc->num_queues = (version >> VERSION_NUMVQM_SHIFT) & 789*844d9543SConrad Meyer VERSION_NUMVQM_MASK; 790*844d9543SConrad Meyer sc->num_lsb_entries = (version >> VERSION_LSBSIZE_SHIFT) & 791*844d9543SConrad Meyer VERSION_LSBSIZE_MASK; 792*844d9543SConrad Meyer sc->hw_features = version & VERSION_CAP_MASK; 793*844d9543SConrad Meyer 794*844d9543SConrad Meyer /* 795*844d9543SConrad Meyer * Copy private LSB mask to public registers to enable access to LSB 796*844d9543SConrad Meyer * from all queues allowed by BIOS. 797*844d9543SConrad Meyer */ 798*844d9543SConrad Meyer lsbmasklo = ccp_read_4(sc, LSB_PRIVATE_MASK_LO_OFFSET); 799*844d9543SConrad Meyer lsbmaskhi = ccp_read_4(sc, LSB_PRIVATE_MASK_HI_OFFSET); 800*844d9543SConrad Meyer ccp_write_4(sc, LSB_PUBLIC_MASK_LO_OFFSET, lsbmasklo); 801*844d9543SConrad Meyer ccp_write_4(sc, LSB_PUBLIC_MASK_HI_OFFSET, lsbmaskhi); 802*844d9543SConrad Meyer 803*844d9543SConrad Meyer lsbmask = ((uint64_t)lsbmaskhi << 30) | lsbmasklo; 804*844d9543SConrad Meyer 805*844d9543SConrad Meyer for (; queue_idx < nitems(sc->queues); queue_idx++) { 806*844d9543SConrad Meyer error = ccp_hw_attach_queue(dev, lsbmask, queue_idx); 807*844d9543SConrad Meyer if (error != 0) { 808*844d9543SConrad Meyer device_printf(dev, "%s: couldn't attach queue %u\n", 809*844d9543SConrad Meyer __func__, queue_idx); 810*844d9543SConrad Meyer goto out; 811*844d9543SConrad Meyer } 812*844d9543SConrad Meyer } 813*844d9543SConrad Meyer ccp_assign_lsb_regions(sc, lsbmask); 814*844d9543SConrad Meyer 815*844d9543SConrad Meyer out: 816*844d9543SConrad Meyer if (error != 0) { 817*844d9543SConrad Meyer if (interrupts_setup) 818*844d9543SConrad Meyer ccp_release_interrupts(sc); 819*844d9543SConrad Meyer for (j = 0; j < queue_idx; j++) 820*844d9543SConrad Meyer ccp_hw_detach_queue(dev, j); 821*844d9543SConrad Meyer if (sc->ring_size_order != 0) 822*844d9543SConrad Meyer pci_disable_busmaster(dev); 823*844d9543SConrad Meyer if (bars_mapped) 824*844d9543SConrad Meyer ccp_unmap_pci_bar(dev); 825*844d9543SConrad Meyer } 826*844d9543SConrad Meyer return (error); 827*844d9543SConrad Meyer } 828*844d9543SConrad Meyer 829*844d9543SConrad Meyer void 830*844d9543SConrad Meyer ccp_hw_detach(device_t dev) 831*844d9543SConrad Meyer { 832*844d9543SConrad Meyer struct ccp_softc *sc; 833*844d9543SConrad Meyer unsigned i; 834*844d9543SConrad Meyer 835*844d9543SConrad Meyer sc = device_get_softc(dev); 836*844d9543SConrad Meyer 837*844d9543SConrad Meyer for (i = 0; i < nitems(sc->queues); i++) 838*844d9543SConrad Meyer ccp_hw_detach_queue(dev, i); 839*844d9543SConrad Meyer 840*844d9543SConrad Meyer ccp_release_interrupts(sc); 841*844d9543SConrad Meyer pci_disable_busmaster(dev); 842*844d9543SConrad Meyer ccp_unmap_pci_bar(dev); 843*844d9543SConrad Meyer } 844*844d9543SConrad Meyer 845*844d9543SConrad Meyer static int __must_check 846*844d9543SConrad Meyer ccp_passthrough(struct ccp_queue *qp, bus_addr_t dst, 847*844d9543SConrad Meyer enum ccp_memtype dst_type, bus_addr_t src, enum ccp_memtype src_type, 848*844d9543SConrad Meyer bus_size_t len, enum ccp_passthru_byteswap swapmode, 849*844d9543SConrad Meyer enum ccp_passthru_bitwise bitmode, bool interrupt, 850*844d9543SConrad Meyer const struct ccp_completion_ctx *cctx) 851*844d9543SConrad Meyer { 852*844d9543SConrad Meyer struct ccp_desc *desc; 853*844d9543SConrad Meyer 854*844d9543SConrad Meyer if (ccp_queue_get_ring_space(qp) == 0) 855*844d9543SConrad Meyer return (EAGAIN); 856*844d9543SConrad Meyer 857*844d9543SConrad Meyer desc = &qp->desc_ring[qp->cq_tail]; 858*844d9543SConrad Meyer 859*844d9543SConrad Meyer memset(desc, 0, sizeof(*desc)); 860*844d9543SConrad Meyer desc->engine = CCP_ENGINE_PASSTHRU; 861*844d9543SConrad Meyer 862*844d9543SConrad Meyer desc->pt.ioc = interrupt; 863*844d9543SConrad Meyer desc->pt.byteswap = swapmode; 864*844d9543SConrad Meyer desc->pt.bitwise = bitmode; 865*844d9543SConrad Meyer desc->length = len; 866*844d9543SConrad Meyer 867*844d9543SConrad Meyer desc->src_lo = (uint32_t)src; 868*844d9543SConrad Meyer desc->src_hi = src >> 32; 869*844d9543SConrad Meyer desc->src_mem = src_type; 870*844d9543SConrad Meyer 871*844d9543SConrad Meyer desc->dst_lo = (uint32_t)dst; 872*844d9543SConrad Meyer desc->dst_hi = dst >> 32; 873*844d9543SConrad Meyer desc->dst_mem = dst_type; 874*844d9543SConrad Meyer 875*844d9543SConrad Meyer if (bitmode != CCP_PASSTHRU_BITWISE_NOOP) 876*844d9543SConrad Meyer desc->lsb_ctx_id = ccp_queue_lsb_entry(qp, LSB_ENTRY_KEY); 877*844d9543SConrad Meyer 878*844d9543SConrad Meyer if (cctx != NULL) 879*844d9543SConrad Meyer memcpy(&qp->completions_ring[qp->cq_tail], cctx, sizeof(*cctx)); 880*844d9543SConrad Meyer 881*844d9543SConrad Meyer qp->cq_tail = (qp->cq_tail + 1) % (1 << qp->cq_softc->ring_size_order); 882*844d9543SConrad Meyer return (0); 883*844d9543SConrad Meyer } 884*844d9543SConrad Meyer 885*844d9543SConrad Meyer static int __must_check 886*844d9543SConrad Meyer ccp_passthrough_sgl(struct ccp_queue *qp, bus_addr_t lsb_addr, bool tolsb, 887*844d9543SConrad Meyer struct sglist *sgl, bus_size_t len, bool interrupt, 888*844d9543SConrad Meyer const struct ccp_completion_ctx *cctx) 889*844d9543SConrad Meyer { 890*844d9543SConrad Meyer struct sglist_seg *seg; 891*844d9543SConrad Meyer size_t i, remain, nb; 892*844d9543SConrad Meyer int error; 893*844d9543SConrad Meyer 894*844d9543SConrad Meyer remain = len; 895*844d9543SConrad Meyer for (i = 0; i < sgl->sg_nseg && remain != 0; i++) { 896*844d9543SConrad Meyer seg = &sgl->sg_segs[i]; 897*844d9543SConrad Meyer /* crd_len is int, so 32-bit min() is ok. */ 898*844d9543SConrad Meyer nb = min(remain, seg->ss_len); 899*844d9543SConrad Meyer 900*844d9543SConrad Meyer if (tolsb) 901*844d9543SConrad Meyer error = ccp_passthrough(qp, lsb_addr, CCP_MEMTYPE_SB, 902*844d9543SConrad Meyer seg->ss_paddr, CCP_MEMTYPE_SYSTEM, nb, 903*844d9543SConrad Meyer CCP_PASSTHRU_BYTESWAP_NOOP, 904*844d9543SConrad Meyer CCP_PASSTHRU_BITWISE_NOOP, 905*844d9543SConrad Meyer (nb == remain) && interrupt, cctx); 906*844d9543SConrad Meyer else 907*844d9543SConrad Meyer error = ccp_passthrough(qp, seg->ss_paddr, 908*844d9543SConrad Meyer CCP_MEMTYPE_SYSTEM, lsb_addr, CCP_MEMTYPE_SB, nb, 909*844d9543SConrad Meyer CCP_PASSTHRU_BYTESWAP_NOOP, 910*844d9543SConrad Meyer CCP_PASSTHRU_BITWISE_NOOP, 911*844d9543SConrad Meyer (nb == remain) && interrupt, cctx); 912*844d9543SConrad Meyer if (error != 0) 913*844d9543SConrad Meyer return (error); 914*844d9543SConrad Meyer 915*844d9543SConrad Meyer remain -= nb; 916*844d9543SConrad Meyer } 917*844d9543SConrad Meyer return (0); 918*844d9543SConrad Meyer } 919*844d9543SConrad Meyer 920*844d9543SConrad Meyer /* 921*844d9543SConrad Meyer * Note that these vectors are in reverse of the usual order. 922*844d9543SConrad Meyer */ 923*844d9543SConrad Meyer const struct SHA_vectors { 924*844d9543SConrad Meyer uint32_t SHA1[8]; 925*844d9543SConrad Meyer uint32_t SHA224[8]; 926*844d9543SConrad Meyer uint32_t SHA256[8]; 927*844d9543SConrad Meyer uint64_t SHA384[8]; 928*844d9543SConrad Meyer uint64_t SHA512[8]; 929*844d9543SConrad Meyer } SHA_H __aligned(PAGE_SIZE) = { 930*844d9543SConrad Meyer .SHA1 = { 931*844d9543SConrad Meyer 0xc3d2e1f0ul, 932*844d9543SConrad Meyer 0x10325476ul, 933*844d9543SConrad Meyer 0x98badcfeul, 934*844d9543SConrad Meyer 0xefcdab89ul, 935*844d9543SConrad Meyer 0x67452301ul, 936*844d9543SConrad Meyer 0, 937*844d9543SConrad Meyer 0, 938*844d9543SConrad Meyer 0, 939*844d9543SConrad Meyer }, 940*844d9543SConrad Meyer .SHA224 = { 941*844d9543SConrad Meyer 0xbefa4fa4ul, 942*844d9543SConrad Meyer 0x64f98fa7ul, 943*844d9543SConrad Meyer 0x68581511ul, 944*844d9543SConrad Meyer 0xffc00b31ul, 945*844d9543SConrad Meyer 0xf70e5939ul, 946*844d9543SConrad Meyer 0x3070dd17ul, 947*844d9543SConrad Meyer 0x367cd507ul, 948*844d9543SConrad Meyer 0xc1059ed8ul, 949*844d9543SConrad Meyer }, 950*844d9543SConrad Meyer .SHA256 = { 951*844d9543SConrad Meyer 0x5be0cd19ul, 952*844d9543SConrad Meyer 0x1f83d9abul, 953*844d9543SConrad Meyer 0x9b05688cul, 954*844d9543SConrad Meyer 0x510e527ful, 955*844d9543SConrad Meyer 0xa54ff53aul, 956*844d9543SConrad Meyer 0x3c6ef372ul, 957*844d9543SConrad Meyer 0xbb67ae85ul, 958*844d9543SConrad Meyer 0x6a09e667ul, 959*844d9543SConrad Meyer }, 960*844d9543SConrad Meyer .SHA384 = { 961*844d9543SConrad Meyer 0x47b5481dbefa4fa4ull, 962*844d9543SConrad Meyer 0xdb0c2e0d64f98fa7ull, 963*844d9543SConrad Meyer 0x8eb44a8768581511ull, 964*844d9543SConrad Meyer 0x67332667ffc00b31ull, 965*844d9543SConrad Meyer 0x152fecd8f70e5939ull, 966*844d9543SConrad Meyer 0x9159015a3070dd17ull, 967*844d9543SConrad Meyer 0x629a292a367cd507ull, 968*844d9543SConrad Meyer 0xcbbb9d5dc1059ed8ull, 969*844d9543SConrad Meyer }, 970*844d9543SConrad Meyer .SHA512 = { 971*844d9543SConrad Meyer 0x5be0cd19137e2179ull, 972*844d9543SConrad Meyer 0x1f83d9abfb41bd6bull, 973*844d9543SConrad Meyer 0x9b05688c2b3e6c1full, 974*844d9543SConrad Meyer 0x510e527fade682d1ull, 975*844d9543SConrad Meyer 0xa54ff53a5f1d36f1ull, 976*844d9543SConrad Meyer 0x3c6ef372fe94f82bull, 977*844d9543SConrad Meyer 0xbb67ae8584caa73bull, 978*844d9543SConrad Meyer 0x6a09e667f3bcc908ull, 979*844d9543SConrad Meyer }, 980*844d9543SConrad Meyer }; 981*844d9543SConrad Meyer /* 982*844d9543SConrad Meyer * Ensure vectors do not cross a page boundary. 983*844d9543SConrad Meyer * 984*844d9543SConrad Meyer * Disabled due to a new Clang error: "expression is not an integral constant 985*844d9543SConrad Meyer * expression." GCC (cross toolchain) seems to handle this assertion with 986*844d9543SConrad Meyer * _Static_assert just fine. 987*844d9543SConrad Meyer */ 988*844d9543SConrad Meyer #if 0 989*844d9543SConrad Meyer CTASSERT(PAGE_SIZE - ((uintptr_t)&SHA_H % PAGE_SIZE) >= sizeof(SHA_H)); 990*844d9543SConrad Meyer #endif 991*844d9543SConrad Meyer 992*844d9543SConrad Meyer const struct SHA_Defn { 993*844d9543SConrad Meyer enum sha_version version; 994*844d9543SConrad Meyer const void *H_vectors; 995*844d9543SConrad Meyer size_t H_size; 996*844d9543SConrad Meyer struct auth_hash *axf; 997*844d9543SConrad Meyer enum ccp_sha_type engine_type; 998*844d9543SConrad Meyer } SHA_definitions[] = { 999*844d9543SConrad Meyer { 1000*844d9543SConrad Meyer .version = SHA1, 1001*844d9543SConrad Meyer .H_vectors = SHA_H.SHA1, 1002*844d9543SConrad Meyer .H_size = sizeof(SHA_H.SHA1), 1003*844d9543SConrad Meyer .axf = &auth_hash_hmac_sha1, 1004*844d9543SConrad Meyer .engine_type = CCP_SHA_TYPE_1, 1005*844d9543SConrad Meyer }, 1006*844d9543SConrad Meyer #if 0 1007*844d9543SConrad Meyer { 1008*844d9543SConrad Meyer .version = SHA2_224, 1009*844d9543SConrad Meyer .H_vectors = SHA_H.SHA224, 1010*844d9543SConrad Meyer .H_size = sizeof(SHA_H.SHA224), 1011*844d9543SConrad Meyer .axf = &auth_hash_hmac_sha2_224, 1012*844d9543SConrad Meyer .engine_type = CCP_SHA_TYPE_224, 1013*844d9543SConrad Meyer }, 1014*844d9543SConrad Meyer #endif 1015*844d9543SConrad Meyer { 1016*844d9543SConrad Meyer .version = SHA2_256, 1017*844d9543SConrad Meyer .H_vectors = SHA_H.SHA256, 1018*844d9543SConrad Meyer .H_size = sizeof(SHA_H.SHA256), 1019*844d9543SConrad Meyer .axf = &auth_hash_hmac_sha2_256, 1020*844d9543SConrad Meyer .engine_type = CCP_SHA_TYPE_256, 1021*844d9543SConrad Meyer }, 1022*844d9543SConrad Meyer { 1023*844d9543SConrad Meyer .version = SHA2_384, 1024*844d9543SConrad Meyer .H_vectors = SHA_H.SHA384, 1025*844d9543SConrad Meyer .H_size = sizeof(SHA_H.SHA384), 1026*844d9543SConrad Meyer .axf = &auth_hash_hmac_sha2_384, 1027*844d9543SConrad Meyer .engine_type = CCP_SHA_TYPE_384, 1028*844d9543SConrad Meyer }, 1029*844d9543SConrad Meyer { 1030*844d9543SConrad Meyer .version = SHA2_512, 1031*844d9543SConrad Meyer .H_vectors = SHA_H.SHA512, 1032*844d9543SConrad Meyer .H_size = sizeof(SHA_H.SHA512), 1033*844d9543SConrad Meyer .axf = &auth_hash_hmac_sha2_512, 1034*844d9543SConrad Meyer .engine_type = CCP_SHA_TYPE_512, 1035*844d9543SConrad Meyer }, 1036*844d9543SConrad Meyer }; 1037*844d9543SConrad Meyer 1038*844d9543SConrad Meyer static int __must_check 1039*844d9543SConrad Meyer ccp_sha_single_desc(struct ccp_queue *qp, const struct SHA_Defn *defn, 1040*844d9543SConrad Meyer vm_paddr_t addr, size_t len, bool start, bool end, uint64_t msgbits) 1041*844d9543SConrad Meyer { 1042*844d9543SConrad Meyer struct ccp_desc *desc; 1043*844d9543SConrad Meyer 1044*844d9543SConrad Meyer if (ccp_queue_get_ring_space(qp) == 0) 1045*844d9543SConrad Meyer return (EAGAIN); 1046*844d9543SConrad Meyer 1047*844d9543SConrad Meyer desc = &qp->desc_ring[qp->cq_tail]; 1048*844d9543SConrad Meyer 1049*844d9543SConrad Meyer memset(desc, 0, sizeof(*desc)); 1050*844d9543SConrad Meyer desc->engine = CCP_ENGINE_SHA; 1051*844d9543SConrad Meyer desc->som = start; 1052*844d9543SConrad Meyer desc->eom = end; 1053*844d9543SConrad Meyer 1054*844d9543SConrad Meyer desc->sha.type = defn->engine_type; 1055*844d9543SConrad Meyer desc->length = len; 1056*844d9543SConrad Meyer 1057*844d9543SConrad Meyer if (end) { 1058*844d9543SConrad Meyer desc->sha_len_lo = (uint32_t)msgbits; 1059*844d9543SConrad Meyer desc->sha_len_hi = msgbits >> 32; 1060*844d9543SConrad Meyer } 1061*844d9543SConrad Meyer 1062*844d9543SConrad Meyer desc->src_lo = (uint32_t)addr; 1063*844d9543SConrad Meyer desc->src_hi = addr >> 32; 1064*844d9543SConrad Meyer desc->src_mem = CCP_MEMTYPE_SYSTEM; 1065*844d9543SConrad Meyer 1066*844d9543SConrad Meyer desc->lsb_ctx_id = ccp_queue_lsb_entry(qp, LSB_ENTRY_SHA); 1067*844d9543SConrad Meyer 1068*844d9543SConrad Meyer qp->cq_tail = (qp->cq_tail + 1) % (1 << qp->cq_softc->ring_size_order); 1069*844d9543SConrad Meyer return (0); 1070*844d9543SConrad Meyer } 1071*844d9543SConrad Meyer 1072*844d9543SConrad Meyer static int __must_check 1073*844d9543SConrad Meyer ccp_sha(struct ccp_queue *qp, enum sha_version version, struct sglist *sgl_src, 1074*844d9543SConrad Meyer struct sglist *sgl_dst, const struct ccp_completion_ctx *cctx) 1075*844d9543SConrad Meyer { 1076*844d9543SConrad Meyer const struct SHA_Defn *defn; 1077*844d9543SConrad Meyer struct sglist_seg *seg; 1078*844d9543SConrad Meyer size_t i, msgsize, remaining, nb; 1079*844d9543SConrad Meyer uint32_t lsbaddr; 1080*844d9543SConrad Meyer int error; 1081*844d9543SConrad Meyer 1082*844d9543SConrad Meyer for (i = 0; i < nitems(SHA_definitions); i++) 1083*844d9543SConrad Meyer if (SHA_definitions[i].version == version) 1084*844d9543SConrad Meyer break; 1085*844d9543SConrad Meyer if (i == nitems(SHA_definitions)) 1086*844d9543SConrad Meyer return (EINVAL); 1087*844d9543SConrad Meyer defn = &SHA_definitions[i]; 1088*844d9543SConrad Meyer 1089*844d9543SConrad Meyer /* XXX validate input ??? */ 1090*844d9543SConrad Meyer 1091*844d9543SConrad Meyer /* Load initial SHA state into LSB */ 1092*844d9543SConrad Meyer /* XXX ensure H_vectors don't span page boundaries */ 1093*844d9543SConrad Meyer error = ccp_passthrough(qp, ccp_queue_lsb_address(qp, LSB_ENTRY_SHA), 1094*844d9543SConrad Meyer CCP_MEMTYPE_SB, pmap_kextract((vm_offset_t)defn->H_vectors), 1095*844d9543SConrad Meyer CCP_MEMTYPE_SYSTEM, roundup2(defn->H_size, LSB_ENTRY_SIZE), 1096*844d9543SConrad Meyer CCP_PASSTHRU_BYTESWAP_NOOP, CCP_PASSTHRU_BITWISE_NOOP, false, 1097*844d9543SConrad Meyer NULL); 1098*844d9543SConrad Meyer if (error != 0) 1099*844d9543SConrad Meyer return (error); 1100*844d9543SConrad Meyer 1101*844d9543SConrad Meyer /* Execute series of SHA updates on correctly sized buffers */ 1102*844d9543SConrad Meyer msgsize = 0; 1103*844d9543SConrad Meyer for (i = 0; i < sgl_src->sg_nseg; i++) { 1104*844d9543SConrad Meyer seg = &sgl_src->sg_segs[i]; 1105*844d9543SConrad Meyer msgsize += seg->ss_len; 1106*844d9543SConrad Meyer error = ccp_sha_single_desc(qp, defn, seg->ss_paddr, 1107*844d9543SConrad Meyer seg->ss_len, i == 0, i == sgl_src->sg_nseg - 1, 1108*844d9543SConrad Meyer msgsize << 3); 1109*844d9543SConrad Meyer if (error != 0) 1110*844d9543SConrad Meyer return (error); 1111*844d9543SConrad Meyer } 1112*844d9543SConrad Meyer 1113*844d9543SConrad Meyer /* Copy result out to sgl_dst */ 1114*844d9543SConrad Meyer remaining = roundup2(defn->H_size, LSB_ENTRY_SIZE); 1115*844d9543SConrad Meyer lsbaddr = ccp_queue_lsb_address(qp, LSB_ENTRY_SHA); 1116*844d9543SConrad Meyer for (i = 0; i < sgl_dst->sg_nseg; i++) { 1117*844d9543SConrad Meyer seg = &sgl_dst->sg_segs[i]; 1118*844d9543SConrad Meyer /* crd_len is int, so 32-bit min() is ok. */ 1119*844d9543SConrad Meyer nb = min(remaining, seg->ss_len); 1120*844d9543SConrad Meyer 1121*844d9543SConrad Meyer error = ccp_passthrough(qp, seg->ss_paddr, CCP_MEMTYPE_SYSTEM, 1122*844d9543SConrad Meyer lsbaddr, CCP_MEMTYPE_SB, nb, CCP_PASSTHRU_BYTESWAP_NOOP, 1123*844d9543SConrad Meyer CCP_PASSTHRU_BITWISE_NOOP, 1124*844d9543SConrad Meyer (cctx != NULL) ? (nb == remaining) : false, 1125*844d9543SConrad Meyer (nb == remaining) ? cctx : NULL); 1126*844d9543SConrad Meyer if (error != 0) 1127*844d9543SConrad Meyer return (error); 1128*844d9543SConrad Meyer 1129*844d9543SConrad Meyer remaining -= nb; 1130*844d9543SConrad Meyer lsbaddr += nb; 1131*844d9543SConrad Meyer if (remaining == 0) 1132*844d9543SConrad Meyer break; 1133*844d9543SConrad Meyer } 1134*844d9543SConrad Meyer 1135*844d9543SConrad Meyer return (0); 1136*844d9543SConrad Meyer } 1137*844d9543SConrad Meyer 1138*844d9543SConrad Meyer static void 1139*844d9543SConrad Meyer byteswap256(uint64_t *buffer) 1140*844d9543SConrad Meyer { 1141*844d9543SConrad Meyer uint64_t t; 1142*844d9543SConrad Meyer 1143*844d9543SConrad Meyer t = bswap64(buffer[3]); 1144*844d9543SConrad Meyer buffer[3] = bswap64(buffer[0]); 1145*844d9543SConrad Meyer buffer[0] = t; 1146*844d9543SConrad Meyer 1147*844d9543SConrad Meyer t = bswap64(buffer[2]); 1148*844d9543SConrad Meyer buffer[2] = bswap64(buffer[1]); 1149*844d9543SConrad Meyer buffer[1] = t; 1150*844d9543SConrad Meyer } 1151*844d9543SConrad Meyer 1152*844d9543SConrad Meyer /* 1153*844d9543SConrad Meyer * Translate CCP internal LSB hash format into a standard hash ouput. 1154*844d9543SConrad Meyer * 1155*844d9543SConrad Meyer * Manipulates input buffer with byteswap256 operation. 1156*844d9543SConrad Meyer */ 1157*844d9543SConrad Meyer static void 1158*844d9543SConrad Meyer ccp_sha_copy_result(char *output, char *buffer, enum sha_version version) 1159*844d9543SConrad Meyer { 1160*844d9543SConrad Meyer const struct SHA_Defn *defn; 1161*844d9543SConrad Meyer size_t i; 1162*844d9543SConrad Meyer 1163*844d9543SConrad Meyer for (i = 0; i < nitems(SHA_definitions); i++) 1164*844d9543SConrad Meyer if (SHA_definitions[i].version == version) 1165*844d9543SConrad Meyer break; 1166*844d9543SConrad Meyer if (i == nitems(SHA_definitions)) 1167*844d9543SConrad Meyer panic("bogus sha version auth_mode %u\n", (unsigned)version); 1168*844d9543SConrad Meyer 1169*844d9543SConrad Meyer defn = &SHA_definitions[i]; 1170*844d9543SConrad Meyer 1171*844d9543SConrad Meyer /* Swap 256bit manually -- DMA engine can, but with limitations */ 1172*844d9543SConrad Meyer byteswap256((void *)buffer); 1173*844d9543SConrad Meyer if (defn->axf->hashsize > LSB_ENTRY_SIZE) 1174*844d9543SConrad Meyer byteswap256((void *)(buffer + LSB_ENTRY_SIZE)); 1175*844d9543SConrad Meyer 1176*844d9543SConrad Meyer switch (defn->version) { 1177*844d9543SConrad Meyer case SHA1: 1178*844d9543SConrad Meyer memcpy(output, buffer + 12, defn->axf->hashsize); 1179*844d9543SConrad Meyer break; 1180*844d9543SConrad Meyer #if 0 1181*844d9543SConrad Meyer case SHA2_224: 1182*844d9543SConrad Meyer memcpy(output, buffer + XXX, defn->axf->hashsize); 1183*844d9543SConrad Meyer break; 1184*844d9543SConrad Meyer #endif 1185*844d9543SConrad Meyer case SHA2_256: 1186*844d9543SConrad Meyer memcpy(output, buffer, defn->axf->hashsize); 1187*844d9543SConrad Meyer break; 1188*844d9543SConrad Meyer case SHA2_384: 1189*844d9543SConrad Meyer memcpy(output, 1190*844d9543SConrad Meyer buffer + LSB_ENTRY_SIZE * 3 - defn->axf->hashsize, 1191*844d9543SConrad Meyer defn->axf->hashsize - LSB_ENTRY_SIZE); 1192*844d9543SConrad Meyer memcpy(output + defn->axf->hashsize - LSB_ENTRY_SIZE, buffer, 1193*844d9543SConrad Meyer LSB_ENTRY_SIZE); 1194*844d9543SConrad Meyer break; 1195*844d9543SConrad Meyer case SHA2_512: 1196*844d9543SConrad Meyer memcpy(output, buffer + LSB_ENTRY_SIZE, LSB_ENTRY_SIZE); 1197*844d9543SConrad Meyer memcpy(output + LSB_ENTRY_SIZE, buffer, LSB_ENTRY_SIZE); 1198*844d9543SConrad Meyer break; 1199*844d9543SConrad Meyer } 1200*844d9543SConrad Meyer } 1201*844d9543SConrad Meyer 1202*844d9543SConrad Meyer static void 1203*844d9543SConrad Meyer ccp_do_hmac_done(struct ccp_queue *qp, struct ccp_session *s, 1204*844d9543SConrad Meyer struct cryptop *crp, struct cryptodesc *crd, int error) 1205*844d9543SConrad Meyer { 1206*844d9543SConrad Meyer char ihash[SHA2_512_HASH_LEN /* max hash len */]; 1207*844d9543SConrad Meyer union authctx auth_ctx; 1208*844d9543SConrad Meyer struct auth_hash *axf; 1209*844d9543SConrad Meyer 1210*844d9543SConrad Meyer axf = s->hmac.auth_hash; 1211*844d9543SConrad Meyer 1212*844d9543SConrad Meyer s->pending--; 1213*844d9543SConrad Meyer 1214*844d9543SConrad Meyer if (error != 0) { 1215*844d9543SConrad Meyer crp->crp_etype = error; 1216*844d9543SConrad Meyer goto out; 1217*844d9543SConrad Meyer } 1218*844d9543SConrad Meyer 1219*844d9543SConrad Meyer /* Do remaining outer hash over small inner hash in software */ 1220*844d9543SConrad Meyer axf->Init(&auth_ctx); 1221*844d9543SConrad Meyer axf->Update(&auth_ctx, s->hmac.opad, axf->blocksize); 1222*844d9543SConrad Meyer ccp_sha_copy_result(ihash, s->hmac.ipad, s->hmac.auth_mode); 1223*844d9543SConrad Meyer #if 0 1224*844d9543SConrad Meyer INSECURE_DEBUG(dev, "%s sha intermediate=%64D\n", __func__, 1225*844d9543SConrad Meyer (u_char *)ihash, " "); 1226*844d9543SConrad Meyer #endif 1227*844d9543SConrad Meyer axf->Update(&auth_ctx, ihash, axf->hashsize); 1228*844d9543SConrad Meyer axf->Final(s->hmac.ipad, &auth_ctx); 1229*844d9543SConrad Meyer 1230*844d9543SConrad Meyer crypto_copyback(crp->crp_flags, crp->crp_buf, crd->crd_inject, 1231*844d9543SConrad Meyer s->hmac.hash_len, s->hmac.ipad); 1232*844d9543SConrad Meyer 1233*844d9543SConrad Meyer /* Avoid leaking key material */ 1234*844d9543SConrad Meyer explicit_bzero(&auth_ctx, sizeof(auth_ctx)); 1235*844d9543SConrad Meyer explicit_bzero(s->hmac.ipad, sizeof(s->hmac.ipad)); 1236*844d9543SConrad Meyer explicit_bzero(s->hmac.opad, sizeof(s->hmac.opad)); 1237*844d9543SConrad Meyer 1238*844d9543SConrad Meyer out: 1239*844d9543SConrad Meyer crypto_done(crp); 1240*844d9543SConrad Meyer } 1241*844d9543SConrad Meyer 1242*844d9543SConrad Meyer static void 1243*844d9543SConrad Meyer ccp_hmac_done(struct ccp_queue *qp, struct ccp_session *s, void *vcrp, 1244*844d9543SConrad Meyer int error) 1245*844d9543SConrad Meyer { 1246*844d9543SConrad Meyer struct cryptodesc *crd; 1247*844d9543SConrad Meyer struct cryptop *crp; 1248*844d9543SConrad Meyer 1249*844d9543SConrad Meyer crp = vcrp; 1250*844d9543SConrad Meyer crd = crp->crp_desc; 1251*844d9543SConrad Meyer ccp_do_hmac_done(qp, s, crp, crd, error); 1252*844d9543SConrad Meyer } 1253*844d9543SConrad Meyer 1254*844d9543SConrad Meyer static int __must_check 1255*844d9543SConrad Meyer ccp_do_hmac(struct ccp_queue *qp, struct ccp_session *s, struct cryptop *crp, 1256*844d9543SConrad Meyer struct cryptodesc *crd, const struct ccp_completion_ctx *cctx) 1257*844d9543SConrad Meyer { 1258*844d9543SConrad Meyer device_t dev; 1259*844d9543SConrad Meyer struct auth_hash *axf; 1260*844d9543SConrad Meyer int error; 1261*844d9543SConrad Meyer 1262*844d9543SConrad Meyer dev = qp->cq_softc->dev; 1263*844d9543SConrad Meyer axf = s->hmac.auth_hash; 1264*844d9543SConrad Meyer 1265*844d9543SConrad Meyer /* 1266*844d9543SConrad Meyer * Populate the SGL describing inside hash contents. We want to hash 1267*844d9543SConrad Meyer * the ipad (key XOR fixed bit pattern) concatenated with the user 1268*844d9543SConrad Meyer * data. 1269*844d9543SConrad Meyer */ 1270*844d9543SConrad Meyer sglist_reset(qp->cq_sg_ulptx); 1271*844d9543SConrad Meyer error = sglist_append(qp->cq_sg_ulptx, s->hmac.ipad, axf->blocksize); 1272*844d9543SConrad Meyer if (error != 0) 1273*844d9543SConrad Meyer return (error); 1274*844d9543SConrad Meyer error = sglist_append_sglist(qp->cq_sg_ulptx, qp->cq_sg_crp, 1275*844d9543SConrad Meyer crd->crd_skip, crd->crd_len); 1276*844d9543SConrad Meyer if (error != 0) { 1277*844d9543SConrad Meyer DPRINTF(dev, "%s: sglist too short\n", __func__); 1278*844d9543SConrad Meyer return (error); 1279*844d9543SConrad Meyer } 1280*844d9543SConrad Meyer /* Populate SGL for output -- just reuse hmac.ipad buffer. */ 1281*844d9543SConrad Meyer sglist_reset(qp->cq_sg_dst); 1282*844d9543SConrad Meyer error = sglist_append(qp->cq_sg_dst, s->hmac.ipad, 1283*844d9543SConrad Meyer roundup2(axf->hashsize, LSB_ENTRY_SIZE)); 1284*844d9543SConrad Meyer if (error != 0) 1285*844d9543SConrad Meyer return (error); 1286*844d9543SConrad Meyer 1287*844d9543SConrad Meyer error = ccp_sha(qp, s->hmac.auth_mode, qp->cq_sg_ulptx, qp->cq_sg_dst, 1288*844d9543SConrad Meyer cctx); 1289*844d9543SConrad Meyer if (error != 0) { 1290*844d9543SConrad Meyer DPRINTF(dev, "%s: ccp_sha error\n", __func__); 1291*844d9543SConrad Meyer return (error); 1292*844d9543SConrad Meyer } 1293*844d9543SConrad Meyer return (0); 1294*844d9543SConrad Meyer } 1295*844d9543SConrad Meyer 1296*844d9543SConrad Meyer int __must_check 1297*844d9543SConrad Meyer ccp_hmac(struct ccp_queue *qp, struct ccp_session *s, struct cryptop *crp) 1298*844d9543SConrad Meyer { 1299*844d9543SConrad Meyer struct ccp_completion_ctx ctx; 1300*844d9543SConrad Meyer struct cryptodesc *crd; 1301*844d9543SConrad Meyer 1302*844d9543SConrad Meyer crd = crp->crp_desc; 1303*844d9543SConrad Meyer 1304*844d9543SConrad Meyer ctx.callback_fn = ccp_hmac_done; 1305*844d9543SConrad Meyer ctx.callback_arg = crp; 1306*844d9543SConrad Meyer ctx.session = s; 1307*844d9543SConrad Meyer 1308*844d9543SConrad Meyer return (ccp_do_hmac(qp, s, crp, crd, &ctx)); 1309*844d9543SConrad Meyer } 1310*844d9543SConrad Meyer 1311*844d9543SConrad Meyer static void 1312*844d9543SConrad Meyer ccp_byteswap(char *data, size_t len) 1313*844d9543SConrad Meyer { 1314*844d9543SConrad Meyer size_t i; 1315*844d9543SConrad Meyer char t; 1316*844d9543SConrad Meyer 1317*844d9543SConrad Meyer len--; 1318*844d9543SConrad Meyer for (i = 0; i < len; i++, len--) { 1319*844d9543SConrad Meyer t = data[i]; 1320*844d9543SConrad Meyer data[i] = data[len]; 1321*844d9543SConrad Meyer data[len] = t; 1322*844d9543SConrad Meyer } 1323*844d9543SConrad Meyer } 1324*844d9543SConrad Meyer 1325*844d9543SConrad Meyer static void 1326*844d9543SConrad Meyer ccp_blkcipher_done(struct ccp_queue *qp, struct ccp_session *s, void *vcrp, 1327*844d9543SConrad Meyer int error) 1328*844d9543SConrad Meyer { 1329*844d9543SConrad Meyer struct cryptop *crp; 1330*844d9543SConrad Meyer 1331*844d9543SConrad Meyer explicit_bzero(&s->blkcipher, sizeof(s->blkcipher)); 1332*844d9543SConrad Meyer 1333*844d9543SConrad Meyer crp = vcrp; 1334*844d9543SConrad Meyer 1335*844d9543SConrad Meyer s->pending--; 1336*844d9543SConrad Meyer 1337*844d9543SConrad Meyer if (error != 0) 1338*844d9543SConrad Meyer crp->crp_etype = error; 1339*844d9543SConrad Meyer 1340*844d9543SConrad Meyer DPRINTF(qp->cq_softc->dev, "%s: qp=%p crp=%p\n", __func__, qp, crp); 1341*844d9543SConrad Meyer crypto_done(crp); 1342*844d9543SConrad Meyer } 1343*844d9543SConrad Meyer 1344*844d9543SConrad Meyer static void 1345*844d9543SConrad Meyer ccp_collect_iv(struct ccp_session *s, struct cryptop *crp, 1346*844d9543SConrad Meyer struct cryptodesc *crd) 1347*844d9543SConrad Meyer { 1348*844d9543SConrad Meyer 1349*844d9543SConrad Meyer if (crd->crd_flags & CRD_F_ENCRYPT) { 1350*844d9543SConrad Meyer if (crd->crd_flags & CRD_F_IV_EXPLICIT) 1351*844d9543SConrad Meyer memcpy(s->blkcipher.iv, crd->crd_iv, 1352*844d9543SConrad Meyer s->blkcipher.iv_len); 1353*844d9543SConrad Meyer else 1354*844d9543SConrad Meyer arc4rand(s->blkcipher.iv, s->blkcipher.iv_len, 0); 1355*844d9543SConrad Meyer if ((crd->crd_flags & CRD_F_IV_PRESENT) == 0) 1356*844d9543SConrad Meyer crypto_copyback(crp->crp_flags, crp->crp_buf, 1357*844d9543SConrad Meyer crd->crd_inject, s->blkcipher.iv_len, 1358*844d9543SConrad Meyer s->blkcipher.iv); 1359*844d9543SConrad Meyer } else { 1360*844d9543SConrad Meyer if (crd->crd_flags & CRD_F_IV_EXPLICIT) 1361*844d9543SConrad Meyer memcpy(s->blkcipher.iv, crd->crd_iv, 1362*844d9543SConrad Meyer s->blkcipher.iv_len); 1363*844d9543SConrad Meyer else 1364*844d9543SConrad Meyer crypto_copydata(crp->crp_flags, crp->crp_buf, 1365*844d9543SConrad Meyer crd->crd_inject, s->blkcipher.iv_len, 1366*844d9543SConrad Meyer s->blkcipher.iv); 1367*844d9543SConrad Meyer } 1368*844d9543SConrad Meyer 1369*844d9543SConrad Meyer /* 1370*844d9543SConrad Meyer * If the input IV is 12 bytes, append an explicit counter of 1. 1371*844d9543SConrad Meyer */ 1372*844d9543SConrad Meyer if (crd->crd_alg == CRYPTO_AES_NIST_GCM_16 && 1373*844d9543SConrad Meyer s->blkcipher.iv_len == 12) { 1374*844d9543SConrad Meyer *(uint32_t *)&s->blkcipher.iv[12] = htobe32(1); 1375*844d9543SConrad Meyer s->blkcipher.iv_len = AES_BLOCK_LEN; 1376*844d9543SConrad Meyer } 1377*844d9543SConrad Meyer 1378*844d9543SConrad Meyer if (crd->crd_alg == CRYPTO_AES_XTS && s->blkcipher.iv_len != AES_BLOCK_LEN) { 1379*844d9543SConrad Meyer DPRINTF(NULL, "got ivlen != 16: %u\n", s->blkcipher.iv_len); 1380*844d9543SConrad Meyer if (s->blkcipher.iv_len < AES_BLOCK_LEN) 1381*844d9543SConrad Meyer memset(&s->blkcipher.iv[s->blkcipher.iv_len], 0, 1382*844d9543SConrad Meyer AES_BLOCK_LEN - s->blkcipher.iv_len); 1383*844d9543SConrad Meyer s->blkcipher.iv_len = AES_BLOCK_LEN; 1384*844d9543SConrad Meyer } 1385*844d9543SConrad Meyer 1386*844d9543SConrad Meyer /* Reverse order of IV material for HW */ 1387*844d9543SConrad Meyer INSECURE_DEBUG(NULL, "%s: IV: %16D len: %u\n", __func__, 1388*844d9543SConrad Meyer s->blkcipher.iv, " ", s->blkcipher.iv_len); 1389*844d9543SConrad Meyer 1390*844d9543SConrad Meyer /* 1391*844d9543SConrad Meyer * For unknown reasons, XTS mode expects the IV in the reverse byte 1392*844d9543SConrad Meyer * order to every other AES mode. 1393*844d9543SConrad Meyer */ 1394*844d9543SConrad Meyer if (crd->crd_alg != CRYPTO_AES_XTS) 1395*844d9543SConrad Meyer ccp_byteswap(s->blkcipher.iv, s->blkcipher.iv_len); 1396*844d9543SConrad Meyer } 1397*844d9543SConrad Meyer 1398*844d9543SConrad Meyer static int __must_check 1399*844d9543SConrad Meyer ccp_do_pst_to_lsb(struct ccp_queue *qp, uint32_t lsbaddr, const void *src, 1400*844d9543SConrad Meyer size_t len) 1401*844d9543SConrad Meyer { 1402*844d9543SConrad Meyer int error; 1403*844d9543SConrad Meyer 1404*844d9543SConrad Meyer sglist_reset(qp->cq_sg_ulptx); 1405*844d9543SConrad Meyer error = sglist_append(qp->cq_sg_ulptx, __DECONST(void *, src), len); 1406*844d9543SConrad Meyer if (error != 0) 1407*844d9543SConrad Meyer return (error); 1408*844d9543SConrad Meyer 1409*844d9543SConrad Meyer error = ccp_passthrough_sgl(qp, lsbaddr, true, qp->cq_sg_ulptx, len, 1410*844d9543SConrad Meyer false, NULL); 1411*844d9543SConrad Meyer return (error); 1412*844d9543SConrad Meyer } 1413*844d9543SConrad Meyer 1414*844d9543SConrad Meyer static int __must_check 1415*844d9543SConrad Meyer ccp_do_xts(struct ccp_queue *qp, struct ccp_session *s, struct cryptop *crp, 1416*844d9543SConrad Meyer struct cryptodesc *crd, enum ccp_cipher_dir dir, 1417*844d9543SConrad Meyer const struct ccp_completion_ctx *cctx) 1418*844d9543SConrad Meyer { 1419*844d9543SConrad Meyer struct ccp_desc *desc; 1420*844d9543SConrad Meyer device_t dev; 1421*844d9543SConrad Meyer unsigned i; 1422*844d9543SConrad Meyer enum ccp_xts_unitsize usize; 1423*844d9543SConrad Meyer 1424*844d9543SConrad Meyer /* IV and Key data are already loaded */ 1425*844d9543SConrad Meyer 1426*844d9543SConrad Meyer dev = qp->cq_softc->dev; 1427*844d9543SConrad Meyer 1428*844d9543SConrad Meyer for (i = 0; i < nitems(ccp_xts_unitsize_map); i++) 1429*844d9543SConrad Meyer if (ccp_xts_unitsize_map[i].cxu_size == crd->crd_len) { 1430*844d9543SConrad Meyer usize = ccp_xts_unitsize_map[i].cxu_id; 1431*844d9543SConrad Meyer break; 1432*844d9543SConrad Meyer } 1433*844d9543SConrad Meyer if (i >= nitems(ccp_xts_unitsize_map)) 1434*844d9543SConrad Meyer return (EINVAL); 1435*844d9543SConrad Meyer 1436*844d9543SConrad Meyer for (i = 0; i < qp->cq_sg_ulptx->sg_nseg; i++) { 1437*844d9543SConrad Meyer struct sglist_seg *seg; 1438*844d9543SConrad Meyer 1439*844d9543SConrad Meyer seg = &qp->cq_sg_ulptx->sg_segs[i]; 1440*844d9543SConrad Meyer 1441*844d9543SConrad Meyer desc = &qp->desc_ring[qp->cq_tail]; 1442*844d9543SConrad Meyer desc->engine = CCP_ENGINE_XTS_AES; 1443*844d9543SConrad Meyer desc->som = (i == 0); 1444*844d9543SConrad Meyer desc->eom = (i == qp->cq_sg_ulptx->sg_nseg - 1); 1445*844d9543SConrad Meyer desc->ioc = (desc->eom && cctx != NULL); 1446*844d9543SConrad Meyer DPRINTF(dev, "%s: XTS %u: som:%d eom:%d ioc:%d dir:%d\n", 1447*844d9543SConrad Meyer __func__, qp->cq_tail, (int)desc->som, (int)desc->eom, 1448*844d9543SConrad Meyer (int)desc->ioc, (int)dir); 1449*844d9543SConrad Meyer 1450*844d9543SConrad Meyer if (desc->ioc) 1451*844d9543SConrad Meyer memcpy(&qp->completions_ring[qp->cq_tail], cctx, 1452*844d9543SConrad Meyer sizeof(*cctx)); 1453*844d9543SConrad Meyer 1454*844d9543SConrad Meyer desc->aes_xts.encrypt = dir; 1455*844d9543SConrad Meyer desc->aes_xts.type = s->blkcipher.cipher_type; 1456*844d9543SConrad Meyer desc->aes_xts.size = usize; 1457*844d9543SConrad Meyer 1458*844d9543SConrad Meyer DPRINTF(dev, "XXX %s: XTS %u: type:%u size:%u\n", __func__, 1459*844d9543SConrad Meyer qp->cq_tail, (unsigned)desc->aes_xts.type, 1460*844d9543SConrad Meyer (unsigned)desc->aes_xts.size); 1461*844d9543SConrad Meyer 1462*844d9543SConrad Meyer desc->length = seg->ss_len; 1463*844d9543SConrad Meyer desc->src_lo = (uint32_t)seg->ss_paddr; 1464*844d9543SConrad Meyer desc->src_hi = (seg->ss_paddr >> 32); 1465*844d9543SConrad Meyer desc->src_mem = CCP_MEMTYPE_SYSTEM; 1466*844d9543SConrad Meyer 1467*844d9543SConrad Meyer /* Crypt in-place */ 1468*844d9543SConrad Meyer desc->dst_lo = desc->src_lo; 1469*844d9543SConrad Meyer desc->dst_hi = desc->src_hi; 1470*844d9543SConrad Meyer desc->dst_mem = desc->src_mem; 1471*844d9543SConrad Meyer 1472*844d9543SConrad Meyer desc->key_lo = ccp_queue_lsb_address(qp, LSB_ENTRY_KEY); 1473*844d9543SConrad Meyer desc->key_hi = 0; 1474*844d9543SConrad Meyer desc->key_mem = CCP_MEMTYPE_SB; 1475*844d9543SConrad Meyer 1476*844d9543SConrad Meyer desc->lsb_ctx_id = ccp_queue_lsb_entry(qp, LSB_ENTRY_IV); 1477*844d9543SConrad Meyer 1478*844d9543SConrad Meyer qp->cq_tail = (qp->cq_tail + 1) % 1479*844d9543SConrad Meyer (1 << qp->cq_softc->ring_size_order); 1480*844d9543SConrad Meyer } 1481*844d9543SConrad Meyer return (0); 1482*844d9543SConrad Meyer } 1483*844d9543SConrad Meyer 1484*844d9543SConrad Meyer static int __must_check 1485*844d9543SConrad Meyer ccp_do_blkcipher(struct ccp_queue *qp, struct ccp_session *s, 1486*844d9543SConrad Meyer struct cryptop *crp, struct cryptodesc *crd, 1487*844d9543SConrad Meyer const struct ccp_completion_ctx *cctx) 1488*844d9543SConrad Meyer { 1489*844d9543SConrad Meyer struct ccp_desc *desc; 1490*844d9543SConrad Meyer char *keydata; 1491*844d9543SConrad Meyer device_t dev; 1492*844d9543SConrad Meyer enum ccp_cipher_dir dir; 1493*844d9543SConrad Meyer int error; 1494*844d9543SConrad Meyer size_t keydata_len; 1495*844d9543SConrad Meyer unsigned i, j; 1496*844d9543SConrad Meyer 1497*844d9543SConrad Meyer dev = qp->cq_softc->dev; 1498*844d9543SConrad Meyer 1499*844d9543SConrad Meyer if (s->blkcipher.key_len == 0 || crd->crd_len == 0) { 1500*844d9543SConrad Meyer DPRINTF(dev, "%s: empty\n", __func__); 1501*844d9543SConrad Meyer return (EINVAL); 1502*844d9543SConrad Meyer } 1503*844d9543SConrad Meyer if ((crd->crd_len % AES_BLOCK_LEN) != 0) { 1504*844d9543SConrad Meyer DPRINTF(dev, "%s: len modulo: %d\n", __func__, crd->crd_len); 1505*844d9543SConrad Meyer return (EINVAL); 1506*844d9543SConrad Meyer } 1507*844d9543SConrad Meyer 1508*844d9543SConrad Meyer /* 1509*844d9543SConrad Meyer * Individual segments must be multiples of AES block size for the HW 1510*844d9543SConrad Meyer * to process it. Non-compliant inputs aren't bogus, just not doable 1511*844d9543SConrad Meyer * on this hardware. 1512*844d9543SConrad Meyer */ 1513*844d9543SConrad Meyer for (i = 0; i < qp->cq_sg_crp->sg_nseg; i++) 1514*844d9543SConrad Meyer if ((qp->cq_sg_crp->sg_segs[i].ss_len % AES_BLOCK_LEN) != 0) { 1515*844d9543SConrad Meyer DPRINTF(dev, "%s: seg modulo: %zu\n", __func__, 1516*844d9543SConrad Meyer qp->cq_sg_crp->sg_segs[i].ss_len); 1517*844d9543SConrad Meyer return (EINVAL); 1518*844d9543SConrad Meyer } 1519*844d9543SConrad Meyer 1520*844d9543SConrad Meyer /* Gather IV/nonce data */ 1521*844d9543SConrad Meyer ccp_collect_iv(s, crp, crd); 1522*844d9543SConrad Meyer 1523*844d9543SConrad Meyer if ((crd->crd_flags & CRD_F_ENCRYPT) != 0) 1524*844d9543SConrad Meyer dir = CCP_CIPHER_DIR_ENCRYPT; 1525*844d9543SConrad Meyer else 1526*844d9543SConrad Meyer dir = CCP_CIPHER_DIR_DECRYPT; 1527*844d9543SConrad Meyer 1528*844d9543SConrad Meyer /* Set up passthrough op(s) to copy IV into LSB */ 1529*844d9543SConrad Meyer error = ccp_do_pst_to_lsb(qp, ccp_queue_lsb_address(qp, LSB_ENTRY_IV), 1530*844d9543SConrad Meyer s->blkcipher.iv, s->blkcipher.iv_len); 1531*844d9543SConrad Meyer if (error != 0) 1532*844d9543SConrad Meyer return (error); 1533*844d9543SConrad Meyer 1534*844d9543SConrad Meyer /* 1535*844d9543SConrad Meyer * Initialize keydata and keydata_len for GCC. The default case of the 1536*844d9543SConrad Meyer * following switch is impossible to reach, but GCC doesn't know that. 1537*844d9543SConrad Meyer */ 1538*844d9543SConrad Meyer keydata_len = 0; 1539*844d9543SConrad Meyer keydata = NULL; 1540*844d9543SConrad Meyer 1541*844d9543SConrad Meyer switch (crd->crd_alg) { 1542*844d9543SConrad Meyer case CRYPTO_AES_XTS: 1543*844d9543SConrad Meyer for (j = 0; j < nitems(ccp_xts_unitsize_map); j++) 1544*844d9543SConrad Meyer if (ccp_xts_unitsize_map[j].cxu_size == crd->crd_len) 1545*844d9543SConrad Meyer break; 1546*844d9543SConrad Meyer /* Input buffer must be a supported UnitSize */ 1547*844d9543SConrad Meyer if (j >= nitems(ccp_xts_unitsize_map)) { 1548*844d9543SConrad Meyer device_printf(dev, "%s: rejected block size: %u\n", 1549*844d9543SConrad Meyer __func__, crd->crd_len); 1550*844d9543SConrad Meyer return (EOPNOTSUPP); 1551*844d9543SConrad Meyer } 1552*844d9543SConrad Meyer /* FALLTHROUGH */ 1553*844d9543SConrad Meyer case CRYPTO_AES_CBC: 1554*844d9543SConrad Meyer case CRYPTO_AES_ICM: 1555*844d9543SConrad Meyer keydata = s->blkcipher.enckey; 1556*844d9543SConrad Meyer keydata_len = s->blkcipher.key_len; 1557*844d9543SConrad Meyer break; 1558*844d9543SConrad Meyer } 1559*844d9543SConrad Meyer 1560*844d9543SConrad Meyer INSECURE_DEBUG(dev, "%s: KEY(%zu): %16D\n", __func__, keydata_len, 1561*844d9543SConrad Meyer keydata, " "); 1562*844d9543SConrad Meyer if (crd->crd_alg == CRYPTO_AES_XTS) 1563*844d9543SConrad Meyer INSECURE_DEBUG(dev, "%s: KEY(XTS): %64D\n", __func__, keydata, " "); 1564*844d9543SConrad Meyer 1565*844d9543SConrad Meyer /* Reverse order of key material for HW */ 1566*844d9543SConrad Meyer ccp_byteswap(keydata, keydata_len); 1567*844d9543SConrad Meyer 1568*844d9543SConrad Meyer /* Store key material into LSB to avoid page boundaries */ 1569*844d9543SConrad Meyer if (crd->crd_alg == CRYPTO_AES_XTS) { 1570*844d9543SConrad Meyer /* 1571*844d9543SConrad Meyer * XTS mode uses 2 256-bit vectors for the primary key and the 1572*844d9543SConrad Meyer * tweak key. For 128-bit keys, the vectors are zero-padded. 1573*844d9543SConrad Meyer * 1574*844d9543SConrad Meyer * After byteswapping the combined OCF-provided K1:K2 vector 1575*844d9543SConrad Meyer * above, we need to reverse the order again so the hardware 1576*844d9543SConrad Meyer * gets the swapped keys in the order K1':K2'. 1577*844d9543SConrad Meyer */ 1578*844d9543SConrad Meyer error = ccp_do_pst_to_lsb(qp, 1579*844d9543SConrad Meyer ccp_queue_lsb_address(qp, LSB_ENTRY_KEY + 1), keydata, 1580*844d9543SConrad Meyer keydata_len / 2); 1581*844d9543SConrad Meyer if (error != 0) 1582*844d9543SConrad Meyer return (error); 1583*844d9543SConrad Meyer error = ccp_do_pst_to_lsb(qp, 1584*844d9543SConrad Meyer ccp_queue_lsb_address(qp, LSB_ENTRY_KEY), 1585*844d9543SConrad Meyer keydata + (keydata_len / 2), keydata_len / 2); 1586*844d9543SConrad Meyer 1587*844d9543SConrad Meyer /* Zero-pad 128 bit keys */ 1588*844d9543SConrad Meyer if (keydata_len == 32) { 1589*844d9543SConrad Meyer if (error != 0) 1590*844d9543SConrad Meyer return (error); 1591*844d9543SConrad Meyer error = ccp_do_pst_to_lsb(qp, 1592*844d9543SConrad Meyer ccp_queue_lsb_address(qp, LSB_ENTRY_KEY) + 1593*844d9543SConrad Meyer keydata_len / 2, g_zeroes, keydata_len / 2); 1594*844d9543SConrad Meyer if (error != 0) 1595*844d9543SConrad Meyer return (error); 1596*844d9543SConrad Meyer error = ccp_do_pst_to_lsb(qp, 1597*844d9543SConrad Meyer ccp_queue_lsb_address(qp, LSB_ENTRY_KEY + 1) + 1598*844d9543SConrad Meyer keydata_len / 2, g_zeroes, keydata_len / 2); 1599*844d9543SConrad Meyer } 1600*844d9543SConrad Meyer } else 1601*844d9543SConrad Meyer error = ccp_do_pst_to_lsb(qp, 1602*844d9543SConrad Meyer ccp_queue_lsb_address(qp, LSB_ENTRY_KEY), keydata, 1603*844d9543SConrad Meyer keydata_len); 1604*844d9543SConrad Meyer if (error != 0) 1605*844d9543SConrad Meyer return (error); 1606*844d9543SConrad Meyer 1607*844d9543SConrad Meyer /* 1608*844d9543SConrad Meyer * Point SGLs at the subset of cryptop buffer contents representing the 1609*844d9543SConrad Meyer * data. 1610*844d9543SConrad Meyer */ 1611*844d9543SConrad Meyer sglist_reset(qp->cq_sg_ulptx); 1612*844d9543SConrad Meyer error = sglist_append_sglist(qp->cq_sg_ulptx, qp->cq_sg_crp, 1613*844d9543SConrad Meyer crd->crd_skip, crd->crd_len); 1614*844d9543SConrad Meyer if (error != 0) 1615*844d9543SConrad Meyer return (error); 1616*844d9543SConrad Meyer 1617*844d9543SConrad Meyer INSECURE_DEBUG(dev, "%s: Contents: %16D\n", __func__, 1618*844d9543SConrad Meyer (void *)PHYS_TO_DMAP(qp->cq_sg_ulptx->sg_segs[0].ss_paddr), " "); 1619*844d9543SConrad Meyer 1620*844d9543SConrad Meyer DPRINTF(dev, "%s: starting AES ops @ %u\n", __func__, qp->cq_tail); 1621*844d9543SConrad Meyer 1622*844d9543SConrad Meyer if (ccp_queue_get_ring_space(qp) < qp->cq_sg_ulptx->sg_nseg) 1623*844d9543SConrad Meyer return (EAGAIN); 1624*844d9543SConrad Meyer 1625*844d9543SConrad Meyer if (crd->crd_alg == CRYPTO_AES_XTS) 1626*844d9543SConrad Meyer return (ccp_do_xts(qp, s, crp, crd, dir, cctx)); 1627*844d9543SConrad Meyer 1628*844d9543SConrad Meyer for (i = 0; i < qp->cq_sg_ulptx->sg_nseg; i++) { 1629*844d9543SConrad Meyer struct sglist_seg *seg; 1630*844d9543SConrad Meyer 1631*844d9543SConrad Meyer seg = &qp->cq_sg_ulptx->sg_segs[i]; 1632*844d9543SConrad Meyer 1633*844d9543SConrad Meyer desc = &qp->desc_ring[qp->cq_tail]; 1634*844d9543SConrad Meyer desc->engine = CCP_ENGINE_AES; 1635*844d9543SConrad Meyer desc->som = (i == 0); 1636*844d9543SConrad Meyer desc->eom = (i == qp->cq_sg_ulptx->sg_nseg - 1); 1637*844d9543SConrad Meyer desc->ioc = (desc->eom && cctx != NULL); 1638*844d9543SConrad Meyer DPRINTF(dev, "%s: AES %u: som:%d eom:%d ioc:%d dir:%d\n", 1639*844d9543SConrad Meyer __func__, qp->cq_tail, (int)desc->som, (int)desc->eom, 1640*844d9543SConrad Meyer (int)desc->ioc, (int)dir); 1641*844d9543SConrad Meyer 1642*844d9543SConrad Meyer if (desc->ioc) 1643*844d9543SConrad Meyer memcpy(&qp->completions_ring[qp->cq_tail], cctx, 1644*844d9543SConrad Meyer sizeof(*cctx)); 1645*844d9543SConrad Meyer 1646*844d9543SConrad Meyer desc->aes.encrypt = dir; 1647*844d9543SConrad Meyer desc->aes.mode = s->blkcipher.cipher_mode; 1648*844d9543SConrad Meyer desc->aes.type = s->blkcipher.cipher_type; 1649*844d9543SConrad Meyer if (crd->crd_alg == CRYPTO_AES_ICM) 1650*844d9543SConrad Meyer /* 1651*844d9543SConrad Meyer * Size of CTR value in bits, - 1. ICM mode uses all 1652*844d9543SConrad Meyer * 128 bits as counter. 1653*844d9543SConrad Meyer */ 1654*844d9543SConrad Meyer desc->aes.size = 127; 1655*844d9543SConrad Meyer 1656*844d9543SConrad Meyer DPRINTF(dev, "%s: AES %u: mode:%u type:%u size:%u\n", __func__, 1657*844d9543SConrad Meyer qp->cq_tail, (unsigned)desc->aes.mode, 1658*844d9543SConrad Meyer (unsigned)desc->aes.type, (unsigned)desc->aes.size); 1659*844d9543SConrad Meyer 1660*844d9543SConrad Meyer desc->length = seg->ss_len; 1661*844d9543SConrad Meyer desc->src_lo = (uint32_t)seg->ss_paddr; 1662*844d9543SConrad Meyer desc->src_hi = (seg->ss_paddr >> 32); 1663*844d9543SConrad Meyer desc->src_mem = CCP_MEMTYPE_SYSTEM; 1664*844d9543SConrad Meyer 1665*844d9543SConrad Meyer /* Crypt in-place */ 1666*844d9543SConrad Meyer desc->dst_lo = desc->src_lo; 1667*844d9543SConrad Meyer desc->dst_hi = desc->src_hi; 1668*844d9543SConrad Meyer desc->dst_mem = desc->src_mem; 1669*844d9543SConrad Meyer 1670*844d9543SConrad Meyer desc->key_lo = ccp_queue_lsb_address(qp, LSB_ENTRY_KEY); 1671*844d9543SConrad Meyer desc->key_hi = 0; 1672*844d9543SConrad Meyer desc->key_mem = CCP_MEMTYPE_SB; 1673*844d9543SConrad Meyer 1674*844d9543SConrad Meyer desc->lsb_ctx_id = ccp_queue_lsb_entry(qp, LSB_ENTRY_IV); 1675*844d9543SConrad Meyer 1676*844d9543SConrad Meyer qp->cq_tail = (qp->cq_tail + 1) % 1677*844d9543SConrad Meyer (1 << qp->cq_softc->ring_size_order); 1678*844d9543SConrad Meyer } 1679*844d9543SConrad Meyer return (0); 1680*844d9543SConrad Meyer } 1681*844d9543SConrad Meyer 1682*844d9543SConrad Meyer int __must_check 1683*844d9543SConrad Meyer ccp_blkcipher(struct ccp_queue *qp, struct ccp_session *s, struct cryptop *crp) 1684*844d9543SConrad Meyer { 1685*844d9543SConrad Meyer struct ccp_completion_ctx ctx; 1686*844d9543SConrad Meyer struct cryptodesc *crd; 1687*844d9543SConrad Meyer 1688*844d9543SConrad Meyer crd = crp->crp_desc; 1689*844d9543SConrad Meyer 1690*844d9543SConrad Meyer ctx.callback_fn = ccp_blkcipher_done; 1691*844d9543SConrad Meyer ctx.session = s; 1692*844d9543SConrad Meyer ctx.callback_arg = crp; 1693*844d9543SConrad Meyer 1694*844d9543SConrad Meyer return (ccp_do_blkcipher(qp, s, crp, crd, &ctx)); 1695*844d9543SConrad Meyer } 1696*844d9543SConrad Meyer 1697*844d9543SConrad Meyer static void 1698*844d9543SConrad Meyer ccp_authenc_done(struct ccp_queue *qp, struct ccp_session *s, void *vcrp, 1699*844d9543SConrad Meyer int error) 1700*844d9543SConrad Meyer { 1701*844d9543SConrad Meyer struct cryptodesc *crda; 1702*844d9543SConrad Meyer struct cryptop *crp; 1703*844d9543SConrad Meyer 1704*844d9543SConrad Meyer explicit_bzero(&s->blkcipher, sizeof(s->blkcipher)); 1705*844d9543SConrad Meyer 1706*844d9543SConrad Meyer crp = vcrp; 1707*844d9543SConrad Meyer if (s->cipher_first) 1708*844d9543SConrad Meyer crda = crp->crp_desc->crd_next; 1709*844d9543SConrad Meyer else 1710*844d9543SConrad Meyer crda = crp->crp_desc; 1711*844d9543SConrad Meyer 1712*844d9543SConrad Meyer ccp_do_hmac_done(qp, s, crp, crda, error); 1713*844d9543SConrad Meyer } 1714*844d9543SConrad Meyer 1715*844d9543SConrad Meyer int __must_check 1716*844d9543SConrad Meyer ccp_authenc(struct ccp_queue *qp, struct ccp_session *s, struct cryptop *crp, 1717*844d9543SConrad Meyer struct cryptodesc *crda, struct cryptodesc *crde) 1718*844d9543SConrad Meyer { 1719*844d9543SConrad Meyer struct ccp_completion_ctx ctx; 1720*844d9543SConrad Meyer int error; 1721*844d9543SConrad Meyer 1722*844d9543SConrad Meyer ctx.callback_fn = ccp_authenc_done; 1723*844d9543SConrad Meyer ctx.session = s; 1724*844d9543SConrad Meyer ctx.callback_arg = crp; 1725*844d9543SConrad Meyer 1726*844d9543SConrad Meyer /* Perform first operation */ 1727*844d9543SConrad Meyer if (s->cipher_first) 1728*844d9543SConrad Meyer error = ccp_do_blkcipher(qp, s, crp, crde, NULL); 1729*844d9543SConrad Meyer else 1730*844d9543SConrad Meyer error = ccp_do_hmac(qp, s, crp, crda, NULL); 1731*844d9543SConrad Meyer if (error != 0) 1732*844d9543SConrad Meyer return (error); 1733*844d9543SConrad Meyer 1734*844d9543SConrad Meyer /* Perform second operation */ 1735*844d9543SConrad Meyer if (s->cipher_first) 1736*844d9543SConrad Meyer error = ccp_do_hmac(qp, s, crp, crda, &ctx); 1737*844d9543SConrad Meyer else 1738*844d9543SConrad Meyer error = ccp_do_blkcipher(qp, s, crp, crde, &ctx); 1739*844d9543SConrad Meyer return (error); 1740*844d9543SConrad Meyer } 1741*844d9543SConrad Meyer 1742*844d9543SConrad Meyer static int __must_check 1743*844d9543SConrad Meyer ccp_do_ghash_aad(struct ccp_queue *qp, struct ccp_session *s) 1744*844d9543SConrad Meyer { 1745*844d9543SConrad Meyer struct ccp_desc *desc; 1746*844d9543SConrad Meyer struct sglist_seg *seg; 1747*844d9543SConrad Meyer unsigned i; 1748*844d9543SConrad Meyer 1749*844d9543SConrad Meyer if (ccp_queue_get_ring_space(qp) < qp->cq_sg_ulptx->sg_nseg) 1750*844d9543SConrad Meyer return (EAGAIN); 1751*844d9543SConrad Meyer 1752*844d9543SConrad Meyer for (i = 0; i < qp->cq_sg_ulptx->sg_nseg; i++) { 1753*844d9543SConrad Meyer seg = &qp->cq_sg_ulptx->sg_segs[i]; 1754*844d9543SConrad Meyer 1755*844d9543SConrad Meyer desc = &qp->desc_ring[qp->cq_tail]; 1756*844d9543SConrad Meyer 1757*844d9543SConrad Meyer desc->engine = CCP_ENGINE_AES; 1758*844d9543SConrad Meyer desc->aes.mode = CCP_AES_MODE_GHASH; 1759*844d9543SConrad Meyer desc->aes.type = s->blkcipher.cipher_type; 1760*844d9543SConrad Meyer desc->aes.encrypt = CCP_AES_MODE_GHASH_AAD; 1761*844d9543SConrad Meyer 1762*844d9543SConrad Meyer desc->som = (i == 0); 1763*844d9543SConrad Meyer desc->length = seg->ss_len; 1764*844d9543SConrad Meyer 1765*844d9543SConrad Meyer desc->src_lo = (uint32_t)seg->ss_paddr; 1766*844d9543SConrad Meyer desc->src_hi = (seg->ss_paddr >> 32); 1767*844d9543SConrad Meyer desc->src_mem = CCP_MEMTYPE_SYSTEM; 1768*844d9543SConrad Meyer 1769*844d9543SConrad Meyer desc->lsb_ctx_id = ccp_queue_lsb_entry(qp, LSB_ENTRY_IV); 1770*844d9543SConrad Meyer 1771*844d9543SConrad Meyer desc->key_lo = ccp_queue_lsb_address(qp, LSB_ENTRY_KEY); 1772*844d9543SConrad Meyer desc->key_mem = CCP_MEMTYPE_SB; 1773*844d9543SConrad Meyer 1774*844d9543SConrad Meyer qp->cq_tail = (qp->cq_tail + 1) % 1775*844d9543SConrad Meyer (1 << qp->cq_softc->ring_size_order); 1776*844d9543SConrad Meyer } 1777*844d9543SConrad Meyer return (0); 1778*844d9543SConrad Meyer } 1779*844d9543SConrad Meyer 1780*844d9543SConrad Meyer static int __must_check 1781*844d9543SConrad Meyer ccp_do_gctr(struct ccp_queue *qp, struct ccp_session *s, 1782*844d9543SConrad Meyer enum ccp_cipher_dir dir, struct sglist_seg *seg, bool som, bool eom) 1783*844d9543SConrad Meyer { 1784*844d9543SConrad Meyer struct ccp_desc *desc; 1785*844d9543SConrad Meyer 1786*844d9543SConrad Meyer if (ccp_queue_get_ring_space(qp) == 0) 1787*844d9543SConrad Meyer return (EAGAIN); 1788*844d9543SConrad Meyer 1789*844d9543SConrad Meyer desc = &qp->desc_ring[qp->cq_tail]; 1790*844d9543SConrad Meyer 1791*844d9543SConrad Meyer desc->engine = CCP_ENGINE_AES; 1792*844d9543SConrad Meyer desc->aes.mode = CCP_AES_MODE_GCTR; 1793*844d9543SConrad Meyer desc->aes.type = s->blkcipher.cipher_type; 1794*844d9543SConrad Meyer desc->aes.encrypt = dir; 1795*844d9543SConrad Meyer desc->aes.size = 8 * (seg->ss_len % GMAC_BLOCK_LEN) - 1; 1796*844d9543SConrad Meyer 1797*844d9543SConrad Meyer desc->som = som; 1798*844d9543SConrad Meyer desc->eom = eom; 1799*844d9543SConrad Meyer 1800*844d9543SConrad Meyer /* Trailing bytes will be masked off by aes.size above. */ 1801*844d9543SConrad Meyer desc->length = roundup2(seg->ss_len, GMAC_BLOCK_LEN); 1802*844d9543SConrad Meyer 1803*844d9543SConrad Meyer desc->dst_lo = desc->src_lo = (uint32_t)seg->ss_paddr; 1804*844d9543SConrad Meyer desc->dst_hi = desc->src_hi = seg->ss_paddr >> 32; 1805*844d9543SConrad Meyer desc->dst_mem = desc->src_mem = CCP_MEMTYPE_SYSTEM; 1806*844d9543SConrad Meyer 1807*844d9543SConrad Meyer desc->lsb_ctx_id = ccp_queue_lsb_entry(qp, LSB_ENTRY_IV); 1808*844d9543SConrad Meyer 1809*844d9543SConrad Meyer desc->key_lo = ccp_queue_lsb_address(qp, LSB_ENTRY_KEY); 1810*844d9543SConrad Meyer desc->key_mem = CCP_MEMTYPE_SB; 1811*844d9543SConrad Meyer 1812*844d9543SConrad Meyer qp->cq_tail = (qp->cq_tail + 1) % 1813*844d9543SConrad Meyer (1 << qp->cq_softc->ring_size_order); 1814*844d9543SConrad Meyer return (0); 1815*844d9543SConrad Meyer } 1816*844d9543SConrad Meyer 1817*844d9543SConrad Meyer static int __must_check 1818*844d9543SConrad Meyer ccp_do_ghash_final(struct ccp_queue *qp, struct ccp_session *s) 1819*844d9543SConrad Meyer { 1820*844d9543SConrad Meyer struct ccp_desc *desc; 1821*844d9543SConrad Meyer 1822*844d9543SConrad Meyer if (ccp_queue_get_ring_space(qp) == 0) 1823*844d9543SConrad Meyer return (EAGAIN); 1824*844d9543SConrad Meyer 1825*844d9543SConrad Meyer desc = &qp->desc_ring[qp->cq_tail]; 1826*844d9543SConrad Meyer 1827*844d9543SConrad Meyer desc->engine = CCP_ENGINE_AES; 1828*844d9543SConrad Meyer desc->aes.mode = CCP_AES_MODE_GHASH; 1829*844d9543SConrad Meyer desc->aes.type = s->blkcipher.cipher_type; 1830*844d9543SConrad Meyer desc->aes.encrypt = CCP_AES_MODE_GHASH_FINAL; 1831*844d9543SConrad Meyer 1832*844d9543SConrad Meyer desc->length = GMAC_BLOCK_LEN; 1833*844d9543SConrad Meyer 1834*844d9543SConrad Meyer desc->src_lo = ccp_queue_lsb_address(qp, LSB_ENTRY_GHASH_IN); 1835*844d9543SConrad Meyer desc->src_mem = CCP_MEMTYPE_SB; 1836*844d9543SConrad Meyer 1837*844d9543SConrad Meyer desc->lsb_ctx_id = ccp_queue_lsb_entry(qp, LSB_ENTRY_IV); 1838*844d9543SConrad Meyer 1839*844d9543SConrad Meyer desc->key_lo = ccp_queue_lsb_address(qp, LSB_ENTRY_KEY); 1840*844d9543SConrad Meyer desc->key_mem = CCP_MEMTYPE_SB; 1841*844d9543SConrad Meyer 1842*844d9543SConrad Meyer desc->dst_lo = ccp_queue_lsb_address(qp, LSB_ENTRY_GHASH); 1843*844d9543SConrad Meyer desc->dst_mem = CCP_MEMTYPE_SB; 1844*844d9543SConrad Meyer 1845*844d9543SConrad Meyer qp->cq_tail = (qp->cq_tail + 1) % 1846*844d9543SConrad Meyer (1 << qp->cq_softc->ring_size_order); 1847*844d9543SConrad Meyer return (0); 1848*844d9543SConrad Meyer } 1849*844d9543SConrad Meyer 1850*844d9543SConrad Meyer static void 1851*844d9543SConrad Meyer ccp_gcm_done(struct ccp_queue *qp, struct ccp_session *s, void *vcrp, 1852*844d9543SConrad Meyer int error) 1853*844d9543SConrad Meyer { 1854*844d9543SConrad Meyer char tag[GMAC_DIGEST_LEN]; 1855*844d9543SConrad Meyer struct cryptodesc *crde, *crda; 1856*844d9543SConrad Meyer struct cryptop *crp; 1857*844d9543SConrad Meyer 1858*844d9543SConrad Meyer crp = vcrp; 1859*844d9543SConrad Meyer if (s->cipher_first) { 1860*844d9543SConrad Meyer crde = crp->crp_desc; 1861*844d9543SConrad Meyer crda = crp->crp_desc->crd_next; 1862*844d9543SConrad Meyer } else { 1863*844d9543SConrad Meyer crde = crp->crp_desc->crd_next; 1864*844d9543SConrad Meyer crda = crp->crp_desc; 1865*844d9543SConrad Meyer } 1866*844d9543SConrad Meyer 1867*844d9543SConrad Meyer s->pending--; 1868*844d9543SConrad Meyer 1869*844d9543SConrad Meyer if (error != 0) { 1870*844d9543SConrad Meyer crp->crp_etype = error; 1871*844d9543SConrad Meyer goto out; 1872*844d9543SConrad Meyer } 1873*844d9543SConrad Meyer 1874*844d9543SConrad Meyer /* Encrypt is done. Decrypt needs to verify tag. */ 1875*844d9543SConrad Meyer if ((crde->crd_flags & CRD_F_ENCRYPT) != 0) 1876*844d9543SConrad Meyer goto out; 1877*844d9543SConrad Meyer 1878*844d9543SConrad Meyer /* Copy in message tag. */ 1879*844d9543SConrad Meyer crypto_copydata(crp->crp_flags, crp->crp_buf, crda->crd_inject, 1880*844d9543SConrad Meyer sizeof(tag), tag); 1881*844d9543SConrad Meyer 1882*844d9543SConrad Meyer /* Verify tag against computed GMAC */ 1883*844d9543SConrad Meyer if (timingsafe_bcmp(tag, s->gmac.final_block, s->gmac.hash_len) != 0) 1884*844d9543SConrad Meyer crp->crp_etype = EBADMSG; 1885*844d9543SConrad Meyer 1886*844d9543SConrad Meyer out: 1887*844d9543SConrad Meyer explicit_bzero(&s->blkcipher, sizeof(s->blkcipher)); 1888*844d9543SConrad Meyer explicit_bzero(&s->gmac, sizeof(s->gmac)); 1889*844d9543SConrad Meyer crypto_done(crp); 1890*844d9543SConrad Meyer } 1891*844d9543SConrad Meyer 1892*844d9543SConrad Meyer int __must_check 1893*844d9543SConrad Meyer ccp_gcm(struct ccp_queue *qp, struct ccp_session *s, struct cryptop *crp, 1894*844d9543SConrad Meyer struct cryptodesc *crda, struct cryptodesc *crde) 1895*844d9543SConrad Meyer { 1896*844d9543SConrad Meyer struct ccp_completion_ctx ctx; 1897*844d9543SConrad Meyer enum ccp_cipher_dir dir; 1898*844d9543SConrad Meyer device_t dev; 1899*844d9543SConrad Meyer unsigned i; 1900*844d9543SConrad Meyer int error; 1901*844d9543SConrad Meyer 1902*844d9543SConrad Meyer if (s->blkcipher.key_len == 0) 1903*844d9543SConrad Meyer return (EINVAL); 1904*844d9543SConrad Meyer 1905*844d9543SConrad Meyer /* 1906*844d9543SConrad Meyer * AAD is only permitted before the cipher/plain text, not 1907*844d9543SConrad Meyer * after. 1908*844d9543SConrad Meyer */ 1909*844d9543SConrad Meyer if (crda->crd_len + crda->crd_skip > crde->crd_len + crde->crd_skip) 1910*844d9543SConrad Meyer return (EINVAL); 1911*844d9543SConrad Meyer 1912*844d9543SConrad Meyer dev = qp->cq_softc->dev; 1913*844d9543SConrad Meyer 1914*844d9543SConrad Meyer if ((crde->crd_flags & CRD_F_ENCRYPT) != 0) 1915*844d9543SConrad Meyer dir = CCP_CIPHER_DIR_ENCRYPT; 1916*844d9543SConrad Meyer else 1917*844d9543SConrad Meyer dir = CCP_CIPHER_DIR_DECRYPT; 1918*844d9543SConrad Meyer 1919*844d9543SConrad Meyer /* Zero initial GHASH portion of context */ 1920*844d9543SConrad Meyer memset(s->blkcipher.iv, 0, sizeof(s->blkcipher.iv)); 1921*844d9543SConrad Meyer 1922*844d9543SConrad Meyer /* Gather IV data */ 1923*844d9543SConrad Meyer ccp_collect_iv(s, crp, crde); 1924*844d9543SConrad Meyer 1925*844d9543SConrad Meyer /* Reverse order of key material for HW */ 1926*844d9543SConrad Meyer ccp_byteswap(s->blkcipher.enckey, s->blkcipher.key_len); 1927*844d9543SConrad Meyer 1928*844d9543SConrad Meyer /* Prepare input buffer of concatenated lengths for final GHASH */ 1929*844d9543SConrad Meyer be64enc(s->gmac.final_block, (uint64_t)crda->crd_len * 8); 1930*844d9543SConrad Meyer be64enc(&s->gmac.final_block[8], (uint64_t)crde->crd_len * 8); 1931*844d9543SConrad Meyer 1932*844d9543SConrad Meyer /* Send IV + initial zero GHASH, key data, and lengths buffer to LSB */ 1933*844d9543SConrad Meyer error = ccp_do_pst_to_lsb(qp, ccp_queue_lsb_address(qp, LSB_ENTRY_IV), 1934*844d9543SConrad Meyer s->blkcipher.iv, 32); 1935*844d9543SConrad Meyer if (error != 0) 1936*844d9543SConrad Meyer return (error); 1937*844d9543SConrad Meyer error = ccp_do_pst_to_lsb(qp, ccp_queue_lsb_address(qp, LSB_ENTRY_KEY), 1938*844d9543SConrad Meyer s->blkcipher.enckey, s->blkcipher.key_len); 1939*844d9543SConrad Meyer if (error != 0) 1940*844d9543SConrad Meyer return (error); 1941*844d9543SConrad Meyer error = ccp_do_pst_to_lsb(qp, 1942*844d9543SConrad Meyer ccp_queue_lsb_address(qp, LSB_ENTRY_GHASH_IN), s->gmac.final_block, 1943*844d9543SConrad Meyer GMAC_BLOCK_LEN); 1944*844d9543SConrad Meyer if (error != 0) 1945*844d9543SConrad Meyer return (error); 1946*844d9543SConrad Meyer 1947*844d9543SConrad Meyer /* First step - compute GHASH over AAD */ 1948*844d9543SConrad Meyer if (crda->crd_len != 0) { 1949*844d9543SConrad Meyer sglist_reset(qp->cq_sg_ulptx); 1950*844d9543SConrad Meyer error = sglist_append_sglist(qp->cq_sg_ulptx, qp->cq_sg_crp, 1951*844d9543SConrad Meyer crda->crd_skip, crda->crd_len); 1952*844d9543SConrad Meyer if (error != 0) 1953*844d9543SConrad Meyer return (error); 1954*844d9543SConrad Meyer 1955*844d9543SConrad Meyer /* This engine cannot process non-block multiple AAD data. */ 1956*844d9543SConrad Meyer for (i = 0; i < qp->cq_sg_ulptx->sg_nseg; i++) 1957*844d9543SConrad Meyer if ((qp->cq_sg_ulptx->sg_segs[i].ss_len % 1958*844d9543SConrad Meyer GMAC_BLOCK_LEN) != 0) { 1959*844d9543SConrad Meyer DPRINTF(dev, "%s: AD seg modulo: %zu\n", 1960*844d9543SConrad Meyer __func__, 1961*844d9543SConrad Meyer qp->cq_sg_ulptx->sg_segs[i].ss_len); 1962*844d9543SConrad Meyer return (EINVAL); 1963*844d9543SConrad Meyer } 1964*844d9543SConrad Meyer 1965*844d9543SConrad Meyer error = ccp_do_ghash_aad(qp, s); 1966*844d9543SConrad Meyer if (error != 0) 1967*844d9543SConrad Meyer return (error); 1968*844d9543SConrad Meyer } 1969*844d9543SConrad Meyer 1970*844d9543SConrad Meyer /* Feed data piece by piece into GCTR */ 1971*844d9543SConrad Meyer sglist_reset(qp->cq_sg_ulptx); 1972*844d9543SConrad Meyer error = sglist_append_sglist(qp->cq_sg_ulptx, qp->cq_sg_crp, 1973*844d9543SConrad Meyer crde->crd_skip, crde->crd_len); 1974*844d9543SConrad Meyer if (error != 0) 1975*844d9543SConrad Meyer return (error); 1976*844d9543SConrad Meyer 1977*844d9543SConrad Meyer /* 1978*844d9543SConrad Meyer * All segments except the last must be even multiples of AES block 1979*844d9543SConrad Meyer * size for the HW to process it. Non-compliant inputs aren't bogus, 1980*844d9543SConrad Meyer * just not doable on this hardware. 1981*844d9543SConrad Meyer * 1982*844d9543SConrad Meyer * XXX: Well, the hardware will produce a valid tag for shorter final 1983*844d9543SConrad Meyer * segment inputs, but it will still write out a block-sized plaintext 1984*844d9543SConrad Meyer * or ciphertext chunk. For a typical CRP this tramples trailing data, 1985*844d9543SConrad Meyer * including the provided message tag. So, reject such inputs for now. 1986*844d9543SConrad Meyer */ 1987*844d9543SConrad Meyer for (i = 0; i < qp->cq_sg_ulptx->sg_nseg; i++) 1988*844d9543SConrad Meyer if ((qp->cq_sg_ulptx->sg_segs[i].ss_len % AES_BLOCK_LEN) != 0) { 1989*844d9543SConrad Meyer DPRINTF(dev, "%s: seg modulo: %zu\n", __func__, 1990*844d9543SConrad Meyer qp->cq_sg_ulptx->sg_segs[i].ss_len); 1991*844d9543SConrad Meyer return (EINVAL); 1992*844d9543SConrad Meyer } 1993*844d9543SConrad Meyer 1994*844d9543SConrad Meyer for (i = 0; i < qp->cq_sg_ulptx->sg_nseg; i++) { 1995*844d9543SConrad Meyer struct sglist_seg *seg; 1996*844d9543SConrad Meyer 1997*844d9543SConrad Meyer seg = &qp->cq_sg_ulptx->sg_segs[i]; 1998*844d9543SConrad Meyer error = ccp_do_gctr(qp, s, dir, seg, 1999*844d9543SConrad Meyer (i == 0 && crda->crd_len == 0), 2000*844d9543SConrad Meyer i == (qp->cq_sg_ulptx->sg_nseg - 1)); 2001*844d9543SConrad Meyer if (error != 0) 2002*844d9543SConrad Meyer return (error); 2003*844d9543SConrad Meyer } 2004*844d9543SConrad Meyer 2005*844d9543SConrad Meyer /* Send just initial IV (not GHASH!) to LSB again */ 2006*844d9543SConrad Meyer error = ccp_do_pst_to_lsb(qp, ccp_queue_lsb_address(qp, LSB_ENTRY_IV), 2007*844d9543SConrad Meyer s->blkcipher.iv, s->blkcipher.iv_len); 2008*844d9543SConrad Meyer if (error != 0) 2009*844d9543SConrad Meyer return (error); 2010*844d9543SConrad Meyer 2011*844d9543SConrad Meyer ctx.callback_fn = ccp_gcm_done; 2012*844d9543SConrad Meyer ctx.session = s; 2013*844d9543SConrad Meyer ctx.callback_arg = crp; 2014*844d9543SConrad Meyer 2015*844d9543SConrad Meyer /* Compute final hash and copy result back */ 2016*844d9543SConrad Meyer error = ccp_do_ghash_final(qp, s); 2017*844d9543SConrad Meyer if (error != 0) 2018*844d9543SConrad Meyer return (error); 2019*844d9543SConrad Meyer 2020*844d9543SConrad Meyer /* When encrypting, copy computed tag out to caller buffer. */ 2021*844d9543SConrad Meyer sglist_reset(qp->cq_sg_ulptx); 2022*844d9543SConrad Meyer if (dir == CCP_CIPHER_DIR_ENCRYPT) 2023*844d9543SConrad Meyer error = sglist_append_sglist(qp->cq_sg_ulptx, qp->cq_sg_crp, 2024*844d9543SConrad Meyer crda->crd_inject, s->gmac.hash_len); 2025*844d9543SConrad Meyer else 2026*844d9543SConrad Meyer /* 2027*844d9543SConrad Meyer * For decrypting, copy the computed tag out to our session 2028*844d9543SConrad Meyer * buffer to verify in our callback. 2029*844d9543SConrad Meyer */ 2030*844d9543SConrad Meyer error = sglist_append(qp->cq_sg_ulptx, s->gmac.final_block, 2031*844d9543SConrad Meyer s->gmac.hash_len); 2032*844d9543SConrad Meyer if (error != 0) 2033*844d9543SConrad Meyer return (error); 2034*844d9543SConrad Meyer error = ccp_passthrough_sgl(qp, 2035*844d9543SConrad Meyer ccp_queue_lsb_address(qp, LSB_ENTRY_GHASH), false, qp->cq_sg_ulptx, 2036*844d9543SConrad Meyer s->gmac.hash_len, true, &ctx); 2037*844d9543SConrad Meyer return (error); 2038*844d9543SConrad Meyer } 2039*844d9543SConrad Meyer 2040*844d9543SConrad Meyer #define MAX_TRNG_RETRIES 10 2041*844d9543SConrad Meyer u_int 2042*844d9543SConrad Meyer random_ccp_read(void *v, u_int c) 2043*844d9543SConrad Meyer { 2044*844d9543SConrad Meyer uint32_t *buf; 2045*844d9543SConrad Meyer u_int i, j; 2046*844d9543SConrad Meyer 2047*844d9543SConrad Meyer KASSERT(c % sizeof(*buf) == 0, ("%u not multiple of u_long", c)); 2048*844d9543SConrad Meyer 2049*844d9543SConrad Meyer buf = v; 2050*844d9543SConrad Meyer for (i = c; i > 0; i -= sizeof(*buf)) { 2051*844d9543SConrad Meyer for (j = 0; j < MAX_TRNG_RETRIES; j++) { 2052*844d9543SConrad Meyer *buf = ccp_read_4(g_ccp_softc, TRNG_OUT_OFFSET); 2053*844d9543SConrad Meyer if (*buf != 0) 2054*844d9543SConrad Meyer break; 2055*844d9543SConrad Meyer } 2056*844d9543SConrad Meyer if (j == MAX_TRNG_RETRIES) 2057*844d9543SConrad Meyer return (0); 2058*844d9543SConrad Meyer buf++; 2059*844d9543SConrad Meyer } 2060*844d9543SConrad Meyer return (c); 2061*844d9543SConrad Meyer 2062*844d9543SConrad Meyer } 2063*844d9543SConrad Meyer 2064*844d9543SConrad Meyer #ifdef DDB 2065*844d9543SConrad Meyer void 2066*844d9543SConrad Meyer db_ccp_show_hw(struct ccp_softc *sc) 2067*844d9543SConrad Meyer { 2068*844d9543SConrad Meyer 2069*844d9543SConrad Meyer db_printf(" queue mask: 0x%x\n", 2070*844d9543SConrad Meyer ccp_read_4(sc, CMD_QUEUE_MASK_OFFSET)); 2071*844d9543SConrad Meyer db_printf(" queue prio: 0x%x\n", 2072*844d9543SConrad Meyer ccp_read_4(sc, CMD_QUEUE_PRIO_OFFSET)); 2073*844d9543SConrad Meyer db_printf(" reqid: 0x%x\n", ccp_read_4(sc, CMD_REQID_CONFIG_OFFSET)); 2074*844d9543SConrad Meyer db_printf(" trng output: 0x%x\n", ccp_read_4(sc, TRNG_OUT_OFFSET)); 2075*844d9543SConrad Meyer db_printf(" cmd timeout: 0x%x\n", 2076*844d9543SConrad Meyer ccp_read_4(sc, CMD_CMD_TIMEOUT_OFFSET)); 2077*844d9543SConrad Meyer db_printf(" lsb public mask lo: 0x%x\n", 2078*844d9543SConrad Meyer ccp_read_4(sc, LSB_PUBLIC_MASK_LO_OFFSET)); 2079*844d9543SConrad Meyer db_printf(" lsb public mask hi: 0x%x\n", 2080*844d9543SConrad Meyer ccp_read_4(sc, LSB_PUBLIC_MASK_HI_OFFSET)); 2081*844d9543SConrad Meyer db_printf(" lsb private mask lo: 0x%x\n", 2082*844d9543SConrad Meyer ccp_read_4(sc, LSB_PRIVATE_MASK_LO_OFFSET)); 2083*844d9543SConrad Meyer db_printf(" lsb private mask hi: 0x%x\n", 2084*844d9543SConrad Meyer ccp_read_4(sc, LSB_PRIVATE_MASK_HI_OFFSET)); 2085*844d9543SConrad Meyer db_printf(" version: 0x%x\n", ccp_read_4(sc, VERSION_REG)); 2086*844d9543SConrad Meyer } 2087*844d9543SConrad Meyer 2088*844d9543SConrad Meyer void 2089*844d9543SConrad Meyer db_ccp_show_queue_hw(struct ccp_queue *qp) 2090*844d9543SConrad Meyer { 2091*844d9543SConrad Meyer const struct ccp_error_code *ec; 2092*844d9543SConrad Meyer struct ccp_softc *sc; 2093*844d9543SConrad Meyer uint32_t status, error, esource, faultblock, headlo, qcontrol; 2094*844d9543SConrad Meyer unsigned q, i; 2095*844d9543SConrad Meyer 2096*844d9543SConrad Meyer sc = qp->cq_softc; 2097*844d9543SConrad Meyer q = qp->cq_qindex; 2098*844d9543SConrad Meyer 2099*844d9543SConrad Meyer qcontrol = ccp_read_queue_4(sc, q, CMD_Q_CONTROL_BASE); 2100*844d9543SConrad Meyer db_printf(" qcontrol: 0x%x%s%s\n", qcontrol, 2101*844d9543SConrad Meyer (qcontrol & CMD_Q_RUN) ? " RUN" : "", 2102*844d9543SConrad Meyer (qcontrol & CMD_Q_HALTED) ? " HALTED" : ""); 2103*844d9543SConrad Meyer db_printf(" tail_lo: 0x%x\n", 2104*844d9543SConrad Meyer ccp_read_queue_4(sc, q, CMD_Q_TAIL_LO_BASE)); 2105*844d9543SConrad Meyer headlo = ccp_read_queue_4(sc, q, CMD_Q_HEAD_LO_BASE); 2106*844d9543SConrad Meyer db_printf(" head_lo: 0x%x\n", headlo); 2107*844d9543SConrad Meyer db_printf(" int enable: 0x%x\n", 2108*844d9543SConrad Meyer ccp_read_queue_4(sc, q, CMD_Q_INT_ENABLE_BASE)); 2109*844d9543SConrad Meyer db_printf(" interrupt status: 0x%x\n", 2110*844d9543SConrad Meyer ccp_read_queue_4(sc, q, CMD_Q_INTERRUPT_STATUS_BASE)); 2111*844d9543SConrad Meyer status = ccp_read_queue_4(sc, q, CMD_Q_STATUS_BASE); 2112*844d9543SConrad Meyer db_printf(" status: 0x%x\n", status); 2113*844d9543SConrad Meyer db_printf(" int stats: 0x%x\n", 2114*844d9543SConrad Meyer ccp_read_queue_4(sc, q, CMD_Q_INT_STATUS_BASE)); 2115*844d9543SConrad Meyer 2116*844d9543SConrad Meyer error = status & STATUS_ERROR_MASK; 2117*844d9543SConrad Meyer if (error == 0) 2118*844d9543SConrad Meyer return; 2119*844d9543SConrad Meyer 2120*844d9543SConrad Meyer esource = (status >> STATUS_ERRORSOURCE_SHIFT) & 2121*844d9543SConrad Meyer STATUS_ERRORSOURCE_MASK; 2122*844d9543SConrad Meyer faultblock = (status >> STATUS_VLSB_FAULTBLOCK_SHIFT) & 2123*844d9543SConrad Meyer STATUS_VLSB_FAULTBLOCK_MASK; 2124*844d9543SConrad Meyer 2125*844d9543SConrad Meyer ec = NULL; 2126*844d9543SConrad Meyer for (i = 0; i < nitems(ccp_error_codes); i++) 2127*844d9543SConrad Meyer if (ccp_error_codes[i].ce_code == error) 2128*844d9543SConrad Meyer break; 2129*844d9543SConrad Meyer if (i < nitems(ccp_error_codes)) 2130*844d9543SConrad Meyer ec = &ccp_error_codes[i]; 2131*844d9543SConrad Meyer 2132*844d9543SConrad Meyer db_printf(" Error: %s (%u) Source: %u Faulting LSB block: %u\n", 2133*844d9543SConrad Meyer (ec != NULL) ? ec->ce_name : "(reserved)", error, esource, 2134*844d9543SConrad Meyer faultblock); 2135*844d9543SConrad Meyer if (ec != NULL) 2136*844d9543SConrad Meyer db_printf(" Error description: %s\n", ec->ce_desc); 2137*844d9543SConrad Meyer 2138*844d9543SConrad Meyer i = (headlo - (uint32_t)qp->desc_ring_bus_addr) / Q_DESC_SIZE; 2139*844d9543SConrad Meyer db_printf(" Bad descriptor idx: %u contents:\n %32D\n", i, 2140*844d9543SConrad Meyer (void *)&qp->desc_ring[i], " "); 2141*844d9543SConrad Meyer } 2142*844d9543SConrad Meyer #endif 2143