1 /* 2 * Copyright 2026 Justin Hibbits <jhibbits@FreeBSD.org> 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 */ 6 7 #ifndef DPAA_SEC_VAR_H 8 #define DPAA_SEC_VAR_H 9 10 #include <sys/param.h> 11 #include <sys/bus.h> 12 #include <sys/callout.h> 13 #include <sys/kernel.h> 14 #include <sys/lock.h> 15 #include <sys/malloc.h> 16 #include <sys/module.h> 17 #include <sys/mutex.h> 18 #include <sys/queue.h> 19 #include <sys/rman.h> 20 #include <sys/smp.h> 21 22 #include <machine/atomic.h> 23 #include <machine/bus.h> 24 #include <machine/resource.h> 25 26 #include <vm/vm.h> 27 #include <vm/pmap.h> 28 29 #include <sys/endian.h> 30 31 #include <dev/ofw/ofw_bus.h> 32 #include <dev/ofw/ofw_bus_subr.h> 33 #include <opencrypto/cryptodev.h> 34 #include <opencrypto/xform_auth.h> 35 36 #include "dpaa_common.h" 37 38 #include "cryptodev_if.h" 39 40 /* A job descriptor can have up to 64 words */ 41 #define SEC_MAX_DESC_WORDS 64 42 43 /* Arbitrary limit */ 44 #define SEC_MAX_SEGMENTS 64 45 #define SEC_MAX_SIZE ((SEC_MAX_SEGMENTS - 1) * PAGE_SIZE) 46 47 #define SEC_MAX_DIGEST 64 /* SHA-512 */ 48 #define SEC_CCM_CTX_LEN 56 49 50 /* 51 * SEC's output ring entry: 8-byte descriptor phys addr 52 * echoed from the input ring, followed by a 4-byte job termination 53 * status word. Entries are packed. 54 */ 55 struct sec_or_entry { 56 uint64_t desc_addr; 57 uint32_t status; 58 } __packed; 59 60 _Static_assert(sizeof(struct sec_or_entry) == 12, "OR entry size"); 61 62 struct sec_job; 63 struct sec_session; 64 65 /* 66 * One Job Ring. Rings are independent all the way down: separate 67 * register block, separate completion interrupt, separate lock. 68 * Spreading jobs across them keeps submitters off each other's locks. 69 * The rings themselves live in DMA-safe memory from bus_dmamem_alloc. 70 */ 71 struct sec_jr { 72 struct sec_softc *jr_sc; /* for the interrupt handler */ 73 phandle_t jr_node; /* FDT node for this JR */ 74 uint32_t jr_off; /* JR base within sc_rres */ 75 76 bus_dma_tag_t jr_ring_tag; 77 bus_dmamap_t jr_map; /* covers both rings */ 78 uint64_t *jr_ir; /* input, JR_RING_SIZE * 8B */ 79 vm_paddr_t jr_ir_pa; 80 struct sec_or_entry *jr_or; /* output ring */ 81 vm_paddr_t jr_or_pa; 82 uint32_t jr_ir_head; /* next slot driver writes */ 83 uint32_t jr_or_tail; /* next slot driver reads */ 84 85 /* Completion IRQ, separate from the SEC top-level error IRQ. */ 86 struct resource *jr_ires; 87 int jr_irid; 88 void *jr_icookie; 89 90 /* 91 * Jobs handed to the ring and not yet seen on the output ring. 92 * jr_lock covers this and both ring indices, and is held only for 93 * the ring manipulation itself, never across a job. When the ring 94 * fills, jr_blocked records that opencrypto needs a 95 * crypto_unblock() once slots free up. 96 */ 97 uint32_t jr_inflight; 98 int jr_blocked; 99 100 /* 101 * Outstanding jobs in submission order, so the watchdog only has 102 * to look at the head to find the oldest. jr_flushing marks the 103 * window between asking SEC to flush the ring and clearing HALT. 104 */ 105 TAILQ_HEAD(, sec_job) jr_active; 106 struct callout jr_wdog; 107 bool jr_flushing; 108 bool jr_dying; 109 110 struct mtx jr_lock; 111 }; 112 113 struct sec_softc { 114 device_t sc_dev; 115 struct resource *sc_rres; /* CCSR MMIO for SEC */ 116 int sc_rrid; 117 struct resource *sc_ires; /* SEC error IRQ */ 118 int sc_irid; 119 void *sc_icookie; 120 bus_dma_tag_t sc_dmatag; /* for crypto payloads */ 121 int32_t sc_cid; /* opencrypto driver id */ 122 int sc_version; 123 124 struct sec_jr *sc_jr; /* Job rings */ 125 u_int sc_njr; 126 }; 127 128 /* 129 * Per-request state. The job descriptor at the head becomes the 130 * address we push into the input ring. SEC echoes that same address 131 * in the output ring, and PHYS_TO_DMAP() gives us the struct back. 132 */ 133 134 struct sec_job { 135 uint32_t jd[SEC_MAX_DESC_WORDS]; 136 struct dpaa_sgte in_sgt[1 + SEC_MAX_SEGMENTS]; 137 struct dpaa_sgte out_sgt[SEC_MAX_SEGMENTS]; 138 /* Driver-private (SEC does not touch anything below). */ 139 struct cryptop *crp; 140 struct sec_session *sess; 141 bus_dmamap_t map; 142 TAILQ_ENTRY(sec_job) job_link; 143 int job_deadline; /* ticks */ 144 /* Also holds the expanded 16-byte XTS tweak; see sec_xts_tweak(). */ 145 uint8_t iv[AES_BLOCK_LEN]; 146 uint8_t ccm_ctx[SEC_CCM_CTX_LEN]; 147 uint8_t ccm_alen[2]; 148 uint8_t digest[SEC_MAX_DIGEST]; 149 int nsegs; 150 bus_dma_segment_t segs[SEC_MAX_SEGMENTS]; 151 }; 152 153 int sec_init_rings(struct sec_softc *sc); 154 int sec_destroy_rings(struct sec_softc *sc); 155 int sec_jr_submit_job(struct sec_softc *sc, struct sec_jr *jr, 156 struct sec_job *job); 157 void sec_jr_teardown(struct sec_softc *sc, struct sec_jr *jr); 158 void sec_complete_one(struct sec_softc *sc, uint64_t desc_pa, uint32_t status); 159 160 MALLOC_DECLARE(M_SEC); 161 162 #endif 163