xref: /freebsd/sys/dev/dpaa/sec_var.h (revision 73bb247927470cb2f96cb06fc00a24019cca2607)
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