xref: /freebsd/sys/dev/safexcel/safexcel_var.h (revision bfcc09ddd422c95a1a2e4e794b63ee54c4902398)
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3  *
4  * Copyright (c) 2020 Rubicon Communications, LLC (Netgate)
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  *
26  * $FreeBSD$
27  */
28 
29 #ifndef _SAFEXCEL_VAR_H_
30 #define	_SAFEXCEL_VAR_H_
31 
32 #include <sys/counter.h>
33 
34 #define	SAFEXCEL_MAX_RINGS			4
35 #define	SAFEXCEL_MAX_BATCH_SIZE			64
36 #define	SAFEXCEL_MAX_FRAGMENTS			64
37 #define	SAFEXCEL_MAX_IV_LEN			16
38 #define	SAFEXCEL_MAX_REQUEST_SIZE		65535
39 
40 #define	SAFEXCEL_RING_SIZE			512
41 #define	SAFEXCEL_MAX_ITOKENS			4
42 #define	SAFEXCEL_MAX_ATOKENS			16
43 #define	SAFEXCEL_FETCH_COUNT			1
44 #define	SAFEXCEL_MAX_KEY_LEN			32
45 #define	SAFEXCEL_MAX_RING_AIC			14
46 
47 /*
48  * Context Record format.
49  *
50  * In this driver the context control words are always set in the control data.
51  * This helps optimize fetching of the context record.  This is configured by
52  * setting SAFEXCEL_OPTION_CTX_CTRL_IN_CMD.
53  */
54 struct safexcel_context_record {
55 	uint32_t control0;	/* Unused. */
56 	uint32_t control1;	/* Unused. */
57 	uint32_t data[40];	/* Key material. */
58 } __packed;
59 
60 /* Processing Engine Control Data format. */
61 struct safexcel_control_data {
62 	uint32_t packet_length	: 17;
63 	uint32_t options	: 13;
64 	uint32_t type		: 2;
65 
66 	uint16_t application_id;
67 	uint16_t rsvd;
68 
69 	uint32_t context_lo;
70 	uint32_t context_hi;
71 
72 	uint32_t control0;
73 	uint32_t control1;
74 
75 	/* Inline instructions or IV. */
76 	uint32_t token[SAFEXCEL_MAX_ITOKENS];
77 } __packed;
78 
79 /*
80  * Basic Command Descriptor.
81  *
82  * The Processing Engine and driver cooperate to maintain a set of command
83  * rings, representing outstanding crypto operation requests.  Each descriptor
84  * corresponds to an input data segment, and thus a single crypto(9) request may
85  * span several contiguous command descriptors.
86  *
87  * The first command descriptor for a request stores the input token, which
88  * encodes data specific to the requested operation, such as the encryption
89  * mode.  For some operations data is passed outside the descriptor, in a
90  * context record (e.g., encryption keys), or in an "additional token data"
91  * region (e.g., instructions).
92  */
93 struct safexcel_cmd_descr {
94 	uint32_t particle_size	: 17;
95 	uint32_t rsvd0		: 5;
96 	uint32_t last_seg	: 1;
97 	uint32_t first_seg	: 1;
98 	uint32_t additional_cdata_size : 8;
99 	uint32_t rsvd1;
100 
101 	uint32_t data_lo;
102 	uint32_t data_hi;
103 
104 	uint32_t atok_lo;
105 	uint32_t atok_hi;
106 
107 	struct safexcel_control_data control_data;
108 } __packed;
109 
110 /* Context control word 0 fields. */
111 #define	SAFEXCEL_CONTROL0_TYPE_NULL_OUT		0x0
112 #define	SAFEXCEL_CONTROL0_TYPE_NULL_IN		0x1
113 #define	SAFEXCEL_CONTROL0_TYPE_HASH_OUT		0x2
114 #define	SAFEXCEL_CONTROL0_TYPE_HASH_IN		0x3
115 #define	SAFEXCEL_CONTROL0_TYPE_CRYPTO_OUT	0x4
116 #define	SAFEXCEL_CONTROL0_TYPE_CRYPTO_IN	0x5
117 #define	SAFEXCEL_CONTROL0_TYPE_ENCRYPT_HASH_OUT	0x6
118 #define	SAFEXCEL_CONTROL0_TYPE_DECRYPT_HASH_IN	0x7
119 #define	SAFEXCEL_CONTROL0_TYPE_HASH_ENCRYPT_OUT	0xe
120 #define	SAFEXCEL_CONTROL0_TYPE_HASH_DECRYPT_IN	0xf
121 #define	SAFEXCEL_CONTROL0_RESTART_HASH		(1 << 4)
122 #define	SAFEXCEL_CONTROL0_NO_FINISH_HASH	(1 << 5)
123 #define	SAFEXCEL_CONTROL0_SIZE(n)		(((n) & 0xff) << 8)
124 #define	SAFEXCEL_CONTROL0_KEY_EN		(1 << 16)
125 #define	SAFEXCEL_CONTROL0_CRYPTO_ALG_AES128	(0x5 << 17)
126 #define	SAFEXCEL_CONTROL0_CRYPTO_ALG_AES192	(0x6 << 17)
127 #define	SAFEXCEL_CONTROL0_CRYPTO_ALG_AES256	(0x7 << 17)
128 #define	SAFEXCEL_CONTROL0_DIGEST_PRECOMPUTED	(0x1 << 21)
129 #define	SAFEXCEL_CONTROL0_DIGEST_CCM		(0x2 << 21)
130 #define	SAFEXCEL_CONTROL0_DIGEST_GMAC		(0x2 << 21)
131 #define	SAFEXCEL_CONTROL0_DIGEST_HMAC		(0x3 << 21)
132 #define	SAFEXCEL_CONTROL0_HASH_ALG_SHA1		(0x2 << 23)
133 #define	SAFEXCEL_CONTROL0_HASH_ALG_SHA224	(0x4 << 23)
134 #define	SAFEXCEL_CONTROL0_HASH_ALG_SHA256	(0x3 << 23)
135 #define	SAFEXCEL_CONTROL0_HASH_ALG_SHA384	(0x6 << 23)
136 #define	SAFEXCEL_CONTROL0_HASH_ALG_SHA512	(0x5 << 23)
137 #define	SAFEXCEL_CONTROL0_HASH_ALG_XCBC128	(0x1 << 23)
138 #define	SAFEXCEL_CONTROL0_HASH_ALG_XCBC192	(0x2 << 23)
139 #define	SAFEXCEL_CONTROL0_HASH_ALG_XCBC256	(0x3 << 23)
140 #define	SAFEXCEL_CONTROL0_HASH_ALG_GHASH	(0x4 << 23)
141 #define	SAFEXCEL_CONTROL0_INV_FR		(0x5 << 24)
142 #define	SAFEXCEL_CONTROL0_INV_TR		(0x6 << 24)
143 
144 /* Context control word 1 fields. */
145 #define	SAFEXCEL_CONTROL1_CRYPTO_MODE_ECB	0x0
146 #define	SAFEXCEL_CONTROL1_CRYPTO_MODE_CBC	0x1
147 #define	SAFEXCEL_CONTROL1_CRYPTO_MODE_ICM	0x3
148 #define	SAFEXCEL_CONTROL1_CRYPTO_MODE_OFB	0x4
149 #define	SAFEXCEL_CONTROL1_CRYPTO_MODE_CFB128	0x5
150 #define	SAFEXCEL_CONTROL1_CRYPTO_MODE_CTR	0x6
151 #define	SAFEXCEL_CONTROL1_CRYPTO_MODE_XTS	0x7
152 #define	SAFEXCEL_CONTROL1_CRYPTO_MODE_CCM	(0x6 | (1 << 17))
153 #define	SAFEXCEL_CONTROL1_CRYPTO_MODE_GCM	(0x6 | (1 << 17))
154 #define	SAFEXCEL_CONTROL1_IV0			(1u << 5)
155 #define	SAFEXCEL_CONTROL1_IV1			(1u << 6)
156 #define	SAFEXCEL_CONTROL1_IV2			(1u << 7)
157 #define	SAFEXCEL_CONTROL1_IV3			(1u << 8)
158 #define	SAFEXCEL_CONTROL1_DIGEST_CNT		(1u << 9)
159 #define	SAFEXCEL_CONTROL1_COUNTER_MODE		(1u << 10)
160 #define	SAFEXCEL_CONTROL1_ENCRYPT_HASH_RES	(1u << 17)
161 #define	SAFEXCEL_CONTROL1_HASH_STORE		(1u << 19)
162 
163 /* Control options. */
164 #define	SAFEXCEL_OPTION_IP			(1u << 0) /* must be set */
165 #define	SAFEXCEL_OPTION_CP			(1u << 1) /* 64-bit ctx addr */
166 #define	SAFEXCEL_OPTION_RC_AUTO			(2u << 3) /* auto ctx reuse */
167 #define	SAFEXCEL_OPTION_CTX_CTRL_IN_CMD		(1u << 8) /* ctx ctrl */
168 #define	SAFEXCEL_OPTION_4_TOKEN_IV_CMD		0xe00     /* IV in bypass */
169 
170 struct safexcel_res_data {
171 	uint32_t packet_length	: 17;
172 	uint32_t error_code	: 15;
173 
174 	uint32_t bypass_length	: 4;
175 	uint32_t e15		: 1;
176 	uint32_t rsvd0		: 16;
177 	uint32_t hash_bytes	: 1;
178 	uint32_t hash_length	: 6;
179 	uint32_t generic_bytes	: 1;
180 	uint32_t checksum	: 1;
181 	uint32_t next_header	: 1;
182 	uint32_t length		: 1;
183 
184 	uint16_t application_id;
185 	uint16_t rsvd1;
186 
187 	uint32_t rsvd2;
188 };
189 
190 /* Basic Result Descriptor format */
191 struct safexcel_res_descr {
192 	uint32_t particle_size	: 17;
193 	uint32_t rsvd0		: 3;
194 	uint32_t descriptor_overflow : 1;
195 	uint32_t buffer_overflow : 1;
196 	uint32_t last_seg	: 1;
197 	uint32_t first_seg	: 1;
198 	uint32_t result_size	: 8;
199 
200 	uint32_t rsvd1;
201 
202 	uint32_t data_lo;
203 	uint32_t data_hi;
204 
205 	struct safexcel_res_data result_data;
206 } __packed;
207 
208 /* Result data error codes. */
209 #define	SAFEXCEL_RESULT_ERR_PACKET_LEN		(1u << 0)
210 #define	SAFEXCEL_RESULT_ERR_TOKEN_ERROR		(1u << 1)
211 #define	SAFEXCEL_RESULT_ERR_BYPASS		(1u << 2)
212 #define	SAFEXCEL_RESULT_ERR_CRYPTO_BLOCK_SIZE	(1u << 3)
213 #define	SAFEXCEL_RESULT_ERR_HASH_BLOCK_SIZE	(1u << 4)
214 #define	SAFEXCEL_RESULT_ERR_INVALID_CMD		(1u << 5)
215 #define	SAFEXCEL_RESULT_ERR_PROHIBITED_ALGO	(1u << 6)
216 #define	SAFEXCEL_RESULT_ERR_HASH_INPUT_OVERFLOW	(1u << 7)
217 #define	SAFEXCEL_RESULT_ERR_TTL_UNDERFLOW	(1u << 8)
218 #define	SAFEXCEL_RESULT_ERR_AUTH_FAILED		(1u << 9)
219 #define	SAFEXCEL_RESULT_ERR_SEQNO_CHECK_FAILED	(1u << 10)
220 #define	SAFEXCEL_RESULT_ERR_SPI_CHECK		(1u << 11)
221 #define	SAFEXCEL_RESULT_ERR_CHECKSUM		(1u << 12)
222 #define	SAFEXCEL_RESULT_ERR_PAD_VERIFICATION	(1u << 13)
223 #define	SAFEXCEL_RESULT_ERR_TIMEOUT		(1u << 14)
224 #define	SAFEXCEL_RESULT_ERR_OUTPUT_DMA		(1u << 15)
225 
226 /*
227  * The EIP-96 (crypto transform engine) is programmed using a set of
228  * data processing instructions with the encodings defined below.
229  */
230 struct safexcel_instr {
231 	uint32_t length : 17;		/* bytes to be processed */
232 	uint32_t status : 2;		/* stream status */
233 	uint32_t instructions : 9;
234 	uint32_t opcode : 4;
235 } __packed;
236 
237 /* Type 1, operational data instructions. */
238 #define	SAFEXCEL_INSTR_OPCODE_DIRECTION		0x0
239 #define	SAFEXCEL_INSTR_OPCODE_PRE_CHECKSUM	0x1
240 #define	SAFEXCEL_INSTR_OPCODE_INSERT		0x2
241 #define	SAFEXCEL_INSTR_OPCODE_INSERT_CTX	0x9
242 #define	SAFEXCEL_INSTR_OPCODE_REPLACE		0x3
243 #define	SAFEXCEL_INSTR_OPCODE_RETRIEVE		0x4
244 #define	SAFEXCEL_INSTR_OPCODE_MUTE		0x5
245 /* Type 2, IP header instructions. */
246 #define	SAFEXCEL_INSTR_OPCODE_IPV4		0x7
247 #define	SAFEXCEL_INSTR_OPCODE_IPV4_CHECKSUM	0x6
248 #define	SAFEXCEL_INSTR_OPCODE_IPV6		0x8
249 /* Type 3, postprocessing instructions. */
250 #define	SAFEXCEL_INSTR_OPCODE_INSERT_REMOVE_RESULT 0xa
251 #define	SAFEXCEL_INSTR_OPCODE_REPLACE_BYTE	0xb
252 /* Type 4, result instructions. */
253 #define	SAFEXCEL_INSTR_OPCODE_VERIFY_FIELDS	0xd
254 /* Type 5, context control instructions. */
255 #define	SAFEXCEL_INSTR_OPCODE_CONTEXT_ACCESS	0xe
256 /* Type 6, context control instructions. */
257 #define	SAFEXCEL_INSTR_OPCODE_BYPASS_TOKEN_DATA	0xf
258 
259 /* Status bits for type 1 and 2 instructions. */
260 #define	SAFEXCEL_INSTR_STATUS_LAST_HASH		(1u << 0)
261 #define	SAFEXCEL_INSTR_STATUS_LAST_PACKET	(1u << 1)
262 /* Status bits for type 3 instructions. */
263 #define	SAFEXCEL_INSTR_STATUS_NO_CKSUM_MOD	(1u << 0)
264 
265 /* Instruction-dependent flags. */
266 #define	SAFEXCEL_INSTR_INSERT_HASH_DIGEST	0x1c
267 #define	SAFEXCEL_INSTR_INSERT_IMMEDIATE		0x1b
268 #define	SAFEXCEL_INSTR_DEST_OUTPUT		(1u << 5)
269 #define	SAFEXCEL_INSTR_DEST_HASH		(1u << 6)
270 #define	SAFEXCEL_INSTR_DEST_CRYPTO		(1u << 7)
271 #define	SAFEXCEL_INSTR_INS_LAST			(1u << 8)
272 
273 #define	SAFEXCEL_INSTR_VERIFY_HASH		(1u << 16)
274 #define	SAFEXCEL_INSTR_VERIFY_PADDING		(1u << 5)
275 
276 #define	SAFEXCEL_TOKEN_TYPE_BYPASS	0x0
277 #define	SAFEXCEL_TOKEN_TYPE_AUTONOMOUS	0x3
278 
279 #define	SAFEXCEL_CONTEXT_SMALL		0x2
280 #define	SAFEXCEL_CONTEXT_LARGE		0x3
281 
282 struct safexcel_reg_offsets {
283 	uint32_t hia_aic;
284 	uint32_t hia_aic_g;
285 	uint32_t hia_aic_r;
286 	uint32_t hia_aic_xdr;
287 	uint32_t hia_dfe;
288 	uint32_t hia_dfe_thr;
289 	uint32_t hia_dse;
290 	uint32_t hia_dse_thr;
291 	uint32_t hia_gen_cfg;
292 	uint32_t pe;
293 };
294 
295 struct safexcel_config {
296 	uint32_t	hdw;		/* Host interface Data Width. */
297 	uint32_t	aic_rings;	/* Number of AIC rings. */
298 	uint32_t	pes;		/* Number of PEs. */
299 	uint32_t	rings;		/* Number of rings. */
300 
301 	uint32_t	cd_size;	/* CDR descriptor size. */
302 	uint32_t	cd_offset;	/* CDR offset (size + alignment). */
303 
304 	uint32_t	rd_size;	/* RDR descriptor size. */
305 	uint32_t	rd_offset;	/* RDR offset. */
306 
307 	uint32_t	atok_offset;	/* Additional token offset. */
308 
309 	uint32_t	caps;		/* Device capabilities. */
310 };
311 
312 #define	SAFEXCEL_DPRINTF(sc, lvl, ...) do {				\
313 	if ((sc)->sc_debug >= (lvl))					\
314 		device_printf((sc)->sc_dev, __VA_ARGS__);		\
315 } while (0)
316 
317 struct safexcel_dma_mem {
318 	caddr_t		vaddr;
319 	bus_addr_t	paddr;
320 	bus_dma_tag_t	tag;
321 	bus_dmamap_t	map;
322 };
323 
324 struct safexcel_cmd_descr_ring {
325 	struct safexcel_dma_mem		dma;
326 	struct safexcel_cmd_descr	*desc;
327 	int				write;
328 	int				read;
329 };
330 
331 struct safexcel_res_descr_ring {
332 	struct safexcel_dma_mem		dma;
333 	struct safexcel_res_descr	*desc;
334 	int				write;
335 	int				read;
336 };
337 
338 struct safexcel_context_template {
339 	struct safexcel_context_record	ctx;
340 	int				len;
341 };
342 
343 struct safexcel_session {
344 	crypto_session_t	cses;
345 	uint32_t		alg;		/* cipher algorithm */
346 	uint32_t		digest;		/* digest type */
347 	uint32_t		hash;		/* hash algorithm */
348 	uint32_t		mode;		/* cipher mode of operation */
349 	unsigned int		digestlen;	/* digest length */
350 	unsigned int		statelen;	/* HMAC hash state length */
351 
352 	struct safexcel_context_template encctx, decctx;
353 };
354 
355 struct safexcel_softc;
356 
357 struct safexcel_request {
358 	STAILQ_ENTRY(safexcel_request)	link;
359 	bool				dmap_loaded;
360 	int				ringidx;
361 	bus_dmamap_t			dmap;
362 	int				error;
363 	int				cdescs, rdescs;
364 	uint8_t				iv[SAFEXCEL_MAX_IV_LEN];
365 	struct safexcel_cmd_descr	*cdesc;
366 	struct safexcel_dma_mem		ctx;
367 	struct safexcel_session		*sess;
368 	struct cryptop			*crp;
369 	struct safexcel_softc		*sc;
370 };
371 
372 struct safexcel_ring {
373 	struct mtx			mtx;
374 	struct sglist			*cmd_data;
375 	struct safexcel_cmd_descr_ring	cdr;
376 	struct sglist			*res_data;
377 	struct safexcel_res_descr_ring	rdr;
378 
379 	/* Shadows the command descriptor ring. */
380 	struct safexcel_request		requests[SAFEXCEL_RING_SIZE];
381 
382 	/* Count of requests pending submission. */
383 	int				pending;
384 	int				pending_cdesc, pending_rdesc;
385 
386 	/* Count of outstanding requests. */
387 	int				queued;
388 
389 	/* Requests were deferred due to a resource shortage. */
390 	int				blocked;
391 
392 	struct safexcel_dma_mem		dma_atok;
393 	bus_dma_tag_t   		data_dtag;
394 
395 	char				lockname[32];
396 };
397 
398 struct safexcel_intr_handle {
399 	struct safexcel_softc		*sc;
400 	void				*handle;
401 	int				ring;
402 };
403 
404 struct safexcel_softc {
405 	device_t			sc_dev;
406 	uint32_t			sc_type;	/* EIP-97 or 197 */
407 	int				sc_debug;
408 
409 	struct resource			*sc_res;
410 	struct resource			*sc_intr[SAFEXCEL_MAX_RINGS];
411 	struct safexcel_intr_handle	sc_ih[SAFEXCEL_MAX_RINGS];
412 
413 	counter_u64_t			sc_req_alloc_failures;
414 	counter_u64_t			sc_cdesc_alloc_failures;
415 	counter_u64_t			sc_rdesc_alloc_failures;
416 
417 	struct safexcel_ring 		sc_ring[SAFEXCEL_MAX_RINGS];
418 
419 	int32_t				sc_cid;
420 	struct safexcel_reg_offsets 	sc_offsets;
421 	struct safexcel_config		sc_config;
422 };
423 
424 #define	SAFEXCEL_WRITE(sc, off, val)	bus_write_4((sc)->sc_res, (off), (val))
425 #define	SAFEXCEL_READ(sc, off)		bus_read_4((sc)->sc_res, (off))
426 
427 #define	SAFEXCEL_ADDR_LO(addr)		((uint64_t)(addr) & 0xffffffffu)
428 #define	SAFEXCEL_ADDR_HI(addr)		(((uint64_t)(addr) >> 32) & 0xffffffffu)
429 
430 #endif /* _SAFEXCEL_VAR_H_ */
431