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