xref: /freebsd/sys/dev/cesa/cesa.h (revision 7cc42f6d)
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3  *
4  * Copyright (C) 2009-2011 Semihalf.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  *
28  * $FreeBSD$
29  */
30 
31 #ifndef _DEV_CESA_H_
32 #define _DEV_CESA_H_
33 
34 /* Maximum number of allocated sessions */
35 #define CESA_SESSIONS			64
36 
37 /* Maximum number of queued requests */
38 #define CESA_REQUESTS			256
39 
40 /*
41  * CESA is able to process data only in CESA SRAM, which is quite small (2 kB).
42  * We have to fit a packet there, which contains SA descriptor, keys, IV
43  * and data to be processed. Every request must be converted into chain of
44  * packets and each packet can hold about 1.75 kB of data.
45  *
46  * To process each packet we need at least 1 SA descriptor and at least 4 TDMA
47  * descriptors. However there are cases when we use 2 SA and 8 TDMA descriptors
48  * per packet. Number of used TDMA descriptors can increase beyond given values
49  * if data in the request is fragmented in physical memory.
50  *
51  * The driver uses preallocated SA and TDMA descriptors pools to get best
52  * performace. Size of these pools should match expected request size. Example:
53  *
54  * Expected average request size:			1.5 kB (Ethernet MTU)
55  * Packets per average request:				(1.5 kB / 1.75 kB) = 1
56  * SA decriptors per average request (worst case):	1 * 2 = 2
57  * TDMA desctiptors per average request (worst case):	1 * 8 = 8
58  *
59  * More TDMA descriptors should be allocated, if data fragmentation is expected
60  * (for example while processing mbufs larger than MCLBYTES). The driver may use
61  * 2 additional TDMA descriptors per each discontinuity in the physical data
62  * layout.
63  */
64 
65 /* Values below are optimized for requests containing about 1.5 kB of data */
66 #define CESA_SA_DESC_PER_REQ		2
67 #define CESA_TDMA_DESC_PER_REQ		8
68 
69 #define CESA_SA_DESCRIPTORS		(CESA_SA_DESC_PER_REQ * CESA_REQUESTS)
70 #define CESA_TDMA_DESCRIPTORS		(CESA_TDMA_DESC_PER_REQ * CESA_REQUESTS)
71 
72 /* Useful constants */
73 #define CESA_HMAC_TRUNC_LEN		12
74 #define CESA_MAX_FRAGMENTS		64
75 #define CESA_SRAM_SIZE			2048
76 
77 /*
78  * CESA_MAX_HASH_LEN is maximum length of hash generated by CESA.
79  * As CESA supports MD5, SHA1 and SHA-256 this equals to 32 bytes.
80  */
81 #define CESA_MAX_HASH_LEN		32
82 #define CESA_MAX_KEY_LEN		32
83 #define CESA_MAX_IV_LEN			16
84 #define CESA_MAX_HMAC_BLOCK_LEN		64
85 #define CESA_MAX_MKEY_LEN		CESA_MAX_HMAC_BLOCK_LEN
86 #define CESA_MAX_PACKET_SIZE		(CESA_SRAM_SIZE - CESA_DATA(0))
87 #define CESA_MAX_REQUEST_SIZE		65535
88 
89 /* Locking macros */
90 #define CESA_LOCK(sc, what)		mtx_lock(&(sc)->sc_ ## what ## _lock)
91 #define CESA_UNLOCK(sc, what)		mtx_unlock(&(sc)->sc_ ## what ## _lock)
92 #define CESA_LOCK_ASSERT(sc, what)	\
93 	mtx_assert(&(sc)->sc_ ## what ## _lock, MA_OWNED)
94 
95 /* Registers read/write macros */
96 #define CESA_REG_READ(sc, reg)		\
97 	bus_read_4((sc)->sc_res[RES_CESA_REGS], (reg))
98 #define CESA_REG_WRITE(sc, reg, val)	\
99 	bus_write_4((sc)->sc_res[RES_CESA_REGS], (reg), (val))
100 
101 #define CESA_TDMA_READ(sc, reg)		\
102 	bus_read_4((sc)->sc_res[RES_TDMA_REGS], (reg))
103 #define CESA_TDMA_WRITE(sc, reg, val)	\
104 	bus_write_4((sc)->sc_res[RES_TDMA_REGS], (reg), (val))
105 
106 /* Generic allocator for objects */
107 #define CESA_GENERIC_ALLOC_LOCKED(sc, obj, pool) do {		\
108 	CESA_LOCK(sc, pool);					\
109 								\
110 	if (STAILQ_EMPTY(&(sc)->sc_free_ ## pool))		\
111 		obj = NULL;					\
112 	else {							\
113 		obj = STAILQ_FIRST(&(sc)->sc_free_ ## pool);	\
114 		STAILQ_REMOVE_HEAD(&(sc)->sc_free_ ## pool,	\
115 		    obj ## _stq);				\
116 	}							\
117 								\
118 	CESA_UNLOCK(sc, pool);					\
119 } while (0)
120 
121 #define CESA_GENERIC_FREE_LOCKED(sc, obj, pool) do {		\
122 	CESA_LOCK(sc, pool);					\
123 	STAILQ_INSERT_TAIL(&(sc)->sc_free_ ## pool, obj,	\
124 	    obj ## _stq);					\
125 	CESA_UNLOCK(sc, pool);					\
126 } while (0)
127 
128 /* CESA SRAM offset calculation macros */
129 #define CESA_SA_DATA(member)					\
130 	(sizeof(struct cesa_sa_hdesc) + offsetof(struct cesa_sa_data, member))
131 #define CESA_DATA(offset)					\
132 	(sizeof(struct cesa_sa_hdesc) + sizeof(struct cesa_sa_data) + offset)
133 
134 /* CESA memory and IRQ resources */
135 enum cesa_res_type {
136 	RES_TDMA_REGS,
137 	RES_CESA_REGS,
138 	RES_CESA_IRQ,
139 	RES_CESA_NUM
140 };
141 
142 struct cesa_tdma_hdesc {
143 	uint16_t	cthd_byte_count;
144 	uint16_t	cthd_flags;
145 	uint32_t	cthd_src;
146 	uint32_t	cthd_dst;
147 	uint32_t	cthd_next;
148 };
149 
150 struct cesa_sa_hdesc {
151 	uint32_t	cshd_config;
152 	uint16_t	cshd_enc_src;
153 	uint16_t	cshd_enc_dst;
154 	uint32_t	cshd_enc_dlen;
155 	uint32_t	cshd_enc_key;
156 	uint16_t	cshd_enc_iv;
157 	uint16_t	cshd_enc_iv_buf;
158 	uint16_t	cshd_mac_src;
159 	uint16_t	cshd_mac_total_dlen;
160 	uint16_t	cshd_mac_dst;
161 	uint16_t	cshd_mac_dlen;
162 	uint16_t	cshd_mac_iv_in;
163 	uint16_t	cshd_mac_iv_out;
164 };
165 
166 struct cesa_sa_data {
167 	uint8_t		csd_key[CESA_MAX_KEY_LEN];
168 	uint8_t		csd_iv[CESA_MAX_IV_LEN];
169 	uint8_t		csd_hiv_in[CESA_MAX_HASH_LEN];
170 	uint8_t		csd_hiv_out[CESA_MAX_HASH_LEN];
171 	uint8_t		csd_hash[CESA_MAX_HASH_LEN];
172 };
173 
174 struct cesa_dma_mem {
175 	void		*cdm_vaddr;
176 	bus_addr_t	cdm_paddr;
177 	bus_dma_tag_t	cdm_tag;
178 	bus_dmamap_t	cdm_map;
179 };
180 
181 struct cesa_tdma_desc {
182 	struct cesa_tdma_hdesc		*ctd_cthd;
183 	bus_addr_t			ctd_cthd_paddr;
184 
185 	STAILQ_ENTRY(cesa_tdma_desc)	ctd_stq;
186 };
187 
188 struct cesa_sa_desc {
189 	struct cesa_sa_hdesc		*csd_cshd;
190 	bus_addr_t			csd_cshd_paddr;
191 
192 	STAILQ_ENTRY(cesa_sa_desc)	csd_stq;
193 };
194 
195 struct cesa_session {
196 	uint32_t			cs_config;
197 	unsigned int			cs_ivlen;
198 	unsigned int			cs_hlen;
199 	unsigned int			cs_mblen;
200 	uint8_t				cs_key[CESA_MAX_KEY_LEN];
201 	uint8_t				cs_aes_dkey[CESA_MAX_KEY_LEN];
202 	uint8_t				cs_hiv_in[CESA_MAX_HASH_LEN];
203 	uint8_t				cs_hiv_out[CESA_MAX_HASH_LEN];
204 };
205 
206 struct cesa_request {
207 	struct cesa_sa_data		*cr_csd;
208 	bus_addr_t			cr_csd_paddr;
209 	struct cryptop			*cr_crp;
210 	struct cesa_session		*cr_cs;
211 	bus_dmamap_t			cr_dmap;
212 	int				cr_dmap_loaded;
213 
214 	STAILQ_HEAD(, cesa_tdma_desc)	cr_tdesc;
215 	STAILQ_HEAD(, cesa_sa_desc)	cr_sdesc;
216 
217 	STAILQ_ENTRY(cesa_request)	cr_stq;
218 };
219 
220 struct cesa_packet {
221 	STAILQ_HEAD(, cesa_tdma_desc)	cp_copyin;
222 	STAILQ_HEAD(, cesa_tdma_desc)	cp_copyout;
223 	unsigned int			cp_size;
224 	unsigned int			cp_offset;
225 };
226 
227 struct cesa_softc {
228 	device_t			sc_dev;
229 	int32_t				sc_cid;
230 	uint32_t			sc_soc_id;
231 	struct resource			*sc_res[RES_CESA_NUM];
232 	void				*sc_icookie;
233 	bus_dma_tag_t			sc_data_dtag;
234 	int				sc_error;
235 	int				sc_tperr;
236 	uint8_t				sc_cesa_engine_id;
237 
238 	struct mtx			sc_sc_lock;
239 	int				sc_blocked;
240 
241 	/* TDMA descriptors pool */
242 	struct mtx			sc_tdesc_lock;
243 	struct cesa_tdma_desc		sc_tdesc[CESA_TDMA_DESCRIPTORS];
244 	struct cesa_dma_mem		sc_tdesc_cdm;
245 	STAILQ_HEAD(, cesa_tdma_desc)	sc_free_tdesc;
246 
247 	/* SA descriptors pool */
248 	struct mtx			sc_sdesc_lock;
249 	struct cesa_sa_desc		sc_sdesc[CESA_SA_DESCRIPTORS];
250 	struct cesa_dma_mem		sc_sdesc_cdm;
251 	STAILQ_HEAD(, cesa_sa_desc)	sc_free_sdesc;
252 
253 	/* Requests pool */
254 	struct mtx			sc_requests_lock;
255 	struct cesa_request		sc_requests[CESA_REQUESTS];
256 	struct cesa_dma_mem		sc_requests_cdm;
257 	STAILQ_HEAD(, cesa_request)	sc_free_requests;
258 	STAILQ_HEAD(, cesa_request)	sc_ready_requests;
259 	STAILQ_HEAD(, cesa_request)	sc_queued_requests;
260 
261 	struct mtx			sc_sessions_lock;
262 
263 	/* CESA SRAM Address */
264 	bus_addr_t			sc_sram_base_pa;
265 	vm_offset_t			sc_sram_base_va;
266 	bus_size_t			sc_sram_size;
267 };
268 
269 struct cesa_chain_info {
270 	struct cesa_softc		*cci_sc;
271 	struct cesa_request		*cci_cr;
272 	uint32_t			cci_config;
273 	int				cci_error;
274 };
275 
276 /* CESA descriptors flags definitions */
277 #define CESA_CTHD_OWNED			(1 << 15)
278 
279 #define CESA_CSHD_MAC			(0 << 0)
280 #define CESA_CSHD_ENC			(1 << 0)
281 #define CESA_CSHD_MAC_AND_ENC		(2 << 0)
282 #define CESA_CSHD_ENC_AND_MAC		(3 << 0)
283 #define CESA_CSHD_OP_MASK		(3 << 0)
284 
285 #define CESA_CSHD_MD5			(4 << 4)
286 #define CESA_CSHD_SHA1			(5 << 4)
287 #define CESA_CSHD_SHA2_256		(1 << 4)
288 #define CESA_CSHD_MD5_HMAC		(6 << 4)
289 #define CESA_CSHD_SHA1_HMAC		(7 << 4)
290 #define CESA_CSHD_SHA2_256_HMAC		(3 << 4)
291 
292 #define CESA_CSHD_96_BIT_HMAC		(1 << 7)
293 
294 #define CESA_CSHD_DES			(1 << 8)
295 #define CESA_CSHD_3DES			(2 << 8)
296 #define CESA_CSHD_AES			(3 << 8)
297 
298 #define CESA_CSHD_DECRYPT		(1 << 12)
299 #define CESA_CSHD_CBC			(1 << 16)
300 #define CESA_CSHD_3DES_EDE		(1 << 20)
301 
302 #define CESA_CSH_AES_KLEN_128		(0 << 24)
303 #define CESA_CSH_AES_KLEN_192		(1 << 24)
304 #define CESA_CSH_AES_KLEN_256		(2 << 24)
305 #define CESA_CSH_AES_KLEN_MASK		(3 << 24)
306 
307 #define CESA_CSHD_FRAG_FIRST		(1 << 30)
308 #define CESA_CSHD_FRAG_LAST		(2U << 30)
309 #define CESA_CSHD_FRAG_MIDDLE		(3U << 30)
310 
311 /* CESA registers definitions */
312 #define CESA_ICR			0x0E20
313 #define CESA_ICR_ACCTDMA		(1 << 7)
314 #define CESA_ICR_TPERR			(1 << 12)
315 
316 #define CESA_ICM			0x0E24
317 #define CESA_ICM_ACCTDMA		CESA_ICR_ACCTDMA
318 #define CESA_ICM_TPERR			CESA_ICR_TPERR
319 
320 /* CESA TDMA registers definitions */
321 #define CESA_TDMA_ND			0x0830
322 
323 #define CESA_TDMA_CR			0x0840
324 #define CESA_TDMA_CR_DBL128		(4 << 0)
325 #define CESA_TDMA_CR_ORDEN		(1 << 4)
326 #define CESA_TDMA_CR_SBL128		(4 << 6)
327 #define CESA_TDMA_CR_NBS		(1 << 11)
328 #define CESA_TDMA_CR_ENABLE		(1 << 12)
329 #define CESA_TDMA_CR_FETCHND		(1 << 13)
330 #define CESA_TDMA_CR_ACTIVE		(1 << 14)
331 #define CESA_TDMA_NUM_OUTSTAND		(2 << 16)
332 
333 #define CESA_TDMA_ECR			0x08C8
334 #define CESA_TDMA_ECR_MISS		(1 << 0)
335 #define CESA_TDMA_ECR_DOUBLE_HIT	(1 << 1)
336 #define CESA_TDMA_ECR_BOTH_HIT		(1 << 2)
337 #define CESA_TDMA_ECR_DATA_ERROR	(1 << 3)
338 
339 #define CESA_TDMA_EMR			0x08CC
340 #define CESA_TDMA_EMR_MISS		CESA_TDMA_ECR_MISS
341 #define CESA_TDMA_EMR_DOUBLE_HIT	CESA_TDMA_ECR_DOUBLE_HIT
342 #define CESA_TDMA_EMR_BOTH_HIT		CESA_TDMA_ECR_BOTH_HIT
343 #define CESA_TDMA_EMR_DATA_ERROR	CESA_TDMA_ECR_DATA_ERROR
344 
345 /* CESA SA registers definitions */
346 #define CESA_SA_CMD			0x0E00
347 #define CESA_SA_CMD_ACTVATE		(1 << 0)
348 #define CESA_SA_CMD_SHA2		(1 << 31)
349 
350 #define CESA_SA_DPR			0x0E04
351 
352 #define CESA_SA_CR			0x0E08
353 #define CESA_SA_CR_WAIT_FOR_TDMA	(1 << 7)
354 #define CESA_SA_CR_ACTIVATE_TDMA	(1 << 9)
355 #define CESA_SA_CR_MULTI_MODE		(1 << 11)
356 
357 #define CESA_SA_SR			0x0E0C
358 #define CESA_SA_SR_ACTIVE		(1 << 0)
359 
360 #define CESA_TDMA_SIZE			0x1000
361 #define CESA_CESA_SIZE			0x1000
362 #define CESA0_TDMA_ADDR			0x90000
363 #define CESA0_CESA_ADDR			0x9D000
364 #define CESA1_TDMA_ADDR			0x92000
365 #define CESA1_CESA_ADDR			0x9F000
366 #endif
367