summaryrefslogtreecommitdiffstats
path: root/sys/dev/sec/sec.h
blob: fecfd86cb98d187a11052992bd9d1a67176b2cea (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
/*-
 * Copyright (C) 2008-2009 Semihalf, Piotr Ziecik
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * $FreeBSD$
 */

#ifndef	_SEC_H
#define _SEC_H

/*
 * Each SEC channel can hold up to 24 descriptors. All 4 channels can be
 * simultaneously active holding 96 descriptors. Each descriptor can use 0 or
 * more link table entries depending of size and granulation of input/output
 * data. One link table entry is needed for each 65535 bytes of data.
 */

/* Driver settings */
#define SEC_TIMEOUT			100000
#define SEC_MAX_SESSIONS		256
#define SEC_DESCRIPTORS			256	/* Must be power of 2 */
#define SEC_LT_ENTRIES			1024	/* Must be power of 2 */
#define SEC_MAX_IV_LEN			16
#define SEC_MAX_KEY_LEN			64

/* SEC information */
#define SEC_20_ID			0x0000000000000040ULL
#define SEC_30_ID			0x0030030000000000ULL
#define SEC_31_ID			0x0030030100000000ULL
#define SEC_CHANNELS			4
#define SEC_POINTERS			7
#define SEC_MAX_DMA_BLOCK_SIZE		0xFFFF
#define SEC_MAX_FIFO_LEVEL		24
#define SEC_DMA_ALIGNMENT		8

#define __packed__			__attribute__ ((__packed__))

struct sec_softc;
struct sec_session;

/* SEC descriptor definition */
struct sec_hw_desc_ptr {
	u_int		shdp_length		: 16;
	u_int		shdp_j			: 1;
	u_int		shdp_extent		: 7;
	u_int		__padding0		: 4;
	uint64_t	shdp_ptr		: 36;
} __packed__;

struct sec_hw_desc {
	union __packed__ {
		struct __packed__ {
			u_int	eu_sel0		: 4;
			u_int	mode0		: 8;
			u_int	eu_sel1		: 4;
			u_int	mode1		: 8;
			u_int	desc_type	: 5;
			u_int	__padding0	: 1;
			u_int	dir		: 1;
			u_int	dn		: 1;
			u_int	__padding1	: 32;
		} request;
		struct __packed__ {
			u_int	done		: 8;
			u_int	__padding0	: 27;
			u_int	iccr0		: 2;
			u_int	__padding1	: 6;
			u_int	iccr1		: 2;
			u_int	__padding2	: 19;
		} feedback;
	} shd_control;

	struct sec_hw_desc_ptr	shd_pointer[SEC_POINTERS];

	/* Data below is mapped to descriptor pointers */
	uint8_t			shd_iv[SEC_MAX_IV_LEN];
	uint8_t			shd_key[SEC_MAX_KEY_LEN];
	uint8_t			shd_mkey[SEC_MAX_KEY_LEN];
} __packed__;

#define shd_eu_sel0		shd_control.request.eu_sel0
#define shd_mode0		shd_control.request.mode0
#define shd_eu_sel1		shd_control.request.eu_sel1
#define shd_mode1		shd_control.request.mode1
#define shd_desc_type		shd_control.request.desc_type
#define shd_dir			shd_control.request.dir
#define shd_dn			shd_control.request.dn
#define shd_done		shd_control.feedback.done
#define shd_iccr0		shd_control.feedback.iccr0
#define shd_iccr1		shd_control.feedback.iccr1

/* SEC link table entries definition */
struct sec_hw_lt {
	u_int			shl_length	: 16;
	u_int			__padding0	: 6;
	u_int			shl_r		: 1;
	u_int			shl_n		: 1;
	u_int			__padding1	: 4;
	uint64_t		shl_ptr		: 36;
} __packed__;

struct sec_dma_mem {
	void			*dma_vaddr;
	bus_addr_t		dma_paddr;
	bus_dma_tag_t		dma_tag;
	bus_dmamap_t		dma_map;
	u_int			dma_is_map;
};

struct sec_desc {
	struct sec_hw_desc	*sd_desc;
	bus_addr_t		sd_desc_paddr;
	struct sec_dma_mem	sd_ptr_dmem[SEC_POINTERS];
	struct cryptop		*sd_crp;
	u_int			sd_lt_used;
	u_int			sd_error;
};

struct sec_lt {
	struct sec_hw_lt	*sl_lt;
	bus_addr_t		sl_lt_paddr;
};

struct sec_eu_methods {
	int	(*sem_newsession)(struct sec_softc *sc,
	    struct sec_session *ses, struct cryptoini *enc,
	    struct cryptoini *mac);
	int	(*sem_make_desc)(struct sec_softc *sc,
	    struct sec_session *ses, struct sec_desc *desc,
	    struct cryptop *crp, int buftype);
};

struct sec_session {
	u_int			ss_used;
	struct sec_eu_methods	*ss_eu;
	uint8_t			ss_key[SEC_MAX_KEY_LEN];
	uint8_t			ss_mkey[SEC_MAX_KEY_LEN];
	u_int			ss_klen;
	u_int			ss_mklen;
	u_int			ss_ivlen;
};

struct sec_desc_map_info {
	struct sec_softc	*sdmi_sc;
	bus_size_t		sdmi_size;
	bus_size_t		sdmi_offset;
	struct sec_lt		*sdmi_lt_first;
	struct sec_lt		*sdmi_lt_last;
	u_int			sdmi_lt_used;
};

struct sec_softc {
	device_t		sc_dev;
	int32_t			sc_cid;
	int			sc_blocked;
	int			sc_shutdown;
	u_int			sc_version;

	uint64_t		sc_int_error_mask;
	uint64_t		sc_channel_idle_mask;

	struct sec_session	sc_sessions[SEC_MAX_SESSIONS];

	struct mtx		sc_controller_lock;
	struct mtx		sc_descriptors_lock;
	struct mtx		sc_sessions_lock;

	struct sec_desc		sc_desc[SEC_DESCRIPTORS];
	u_int			sc_free_desc_get_cnt;
	u_int			sc_free_desc_put_cnt;
	u_int			sc_ready_desc_get_cnt;
	u_int			sc_ready_desc_put_cnt;
	u_int			sc_queued_desc_get_cnt;
	u_int			sc_queued_desc_put_cnt;

	struct sec_lt		sc_lt[SEC_LT_ENTRIES + 1];
	u_int			sc_lt_alloc_cnt;
	u_int			sc_lt_free_cnt;

	struct sec_dma_mem	sc_desc_dmem;	/* descriptors DMA memory */
	struct sec_dma_mem	sc_lt_dmem;	/* link tables DMA memory */

	struct resource		*sc_rres;	/* register resource */
        int			sc_rrid;	/* register rid */
	struct {
		bus_space_tag_t	bst;
		bus_space_handle_t bsh;
	} sc_bas;

	struct resource		*sc_pri_ires;	/* primary irq resource */
	void			*sc_pri_ihand;	/* primary irq handler */
	int			sc_pri_irid;	/* primary irq resource id */

	struct resource		*sc_sec_ires;	/* secondary irq resource */
	void			*sc_sec_ihand;	/* secondary irq handler */
	int			sc_sec_irid;	/* secondary irq resource id */
};

/* Locking macros */
#define SEC_LOCK(sc, what)						\
	mtx_lock(&(sc)->sc_ ## what ## _lock)
#define SEC_UNLOCK(sc, what)						\
	mtx_unlock(&(sc)->sc_ ## what ## _lock)
#define SEC_LOCK_ASSERT(sc, what)					\
	mtx_assert(&(sc)->sc_ ## what ## _lock, MA_OWNED)

/* Read/Write definitions */
#define SEC_READ(sc, reg)						\
	bus_space_read_8((sc)->sc_bas.bst, (sc)->sc_bas.bsh, (reg))
#define SEC_WRITE(sc, reg, val)						\
	bus_space_write_8((sc)->sc_bas.bst, (sc)->sc_bas.bsh, (reg), (val))

/* Base allocation macros (warning: wrap must be 2^n) */
#define SEC_CNT_INIT(sc, cnt, wrap)					\
	(((sc)->cnt) = ((wrap) - 1))
#define SEC_ADD(sc, cnt, wrap, val)					\
	((sc)->cnt = (((sc)->cnt) + (val)) & ((wrap) - 1))
#define SEC_INC(sc, cnt, wrap)						\
	SEC_ADD(sc, cnt, wrap, 1)
#define SEC_DEC(sc, cnt, wrap)						\
	SEC_ADD(sc, cnt, wrap, -1)
#define SEC_GET_GENERIC(sc, tab, cnt, wrap)				\
	((sc)->tab[SEC_INC(sc, cnt, wrap)])
#define SEC_PUT_GENERIC(sc, tab, cnt, wrap, val)			\
	((sc)->tab[SEC_INC(sc, cnt, wrap)] = val)

/* Interface for descriptors */
#define SEC_GET_FREE_DESC(sc)						\
	&SEC_GET_GENERIC(sc, sc_desc, sc_free_desc_get_cnt, SEC_DESCRIPTORS)

#define SEC_PUT_BACK_FREE_DESC(sc)					\
	SEC_DEC(sc, sc_free_desc_get_cnt, SEC_DESCRIPTORS)

#define SEC_DESC_FREE2READY(sc)						\
	SEC_INC(sc, sc_ready_desc_put_cnt, SEC_DESCRIPTORS)

#define SEC_GET_READY_DESC(sc)						\
	&SEC_GET_GENERIC(sc, sc_desc, sc_ready_desc_get_cnt, SEC_DESCRIPTORS)

#define SEC_PUT_BACK_READY_DESC(sc)					\
	SEC_DEC(sc, sc_ready_desc_get_cnt, SEC_DESCRIPTORS)

#define SEC_DESC_READY2QUEUED(sc)					\
	SEC_INC(sc, sc_queued_desc_put_cnt, SEC_DESCRIPTORS)

#define SEC_GET_QUEUED_DESC(sc)						\
	&SEC_GET_GENERIC(sc, sc_desc, sc_queued_desc_get_cnt, SEC_DESCRIPTORS)

#define SEC_PUT_BACK_QUEUED_DESC(sc)					\
	SEC_DEC(sc, sc_queued_desc_get_cnt, SEC_DESCRIPTORS)

#define SEC_DESC_QUEUED2FREE(sc)					\
	SEC_INC(sc, sc_free_desc_put_cnt, SEC_DESCRIPTORS)

#define SEC_FREE_DESC_CNT(sc)						\
	(((sc)->sc_free_desc_put_cnt - (sc)->sc_free_desc_get_cnt - 1)	\
	& (SEC_DESCRIPTORS - 1))

#define SEC_READY_DESC_CNT(sc)						\
	(((sc)->sc_ready_desc_put_cnt - (sc)->sc_ready_desc_get_cnt) &	\
	(SEC_DESCRIPTORS - 1))

#define SEC_QUEUED_DESC_CNT(sc)						\
	(((sc)->sc_queued_desc_put_cnt - (sc)->sc_queued_desc_get_cnt)	\
	& (SEC_DESCRIPTORS - 1))

#define SEC_DESC_SYNC(sc, mode) do {					\
	sec_sync_dma_mem(&((sc)->sc_desc_dmem), (mode));		\
	sec_sync_dma_mem(&((sc)->sc_lt_dmem), (mode));			\
} while (0)

#define SEC_DESC_SYNC_POINTERS(desc, mode) do {				\
	u_int i;							\
	for (i = 0; i < SEC_POINTERS; i++)				\
		sec_sync_dma_mem(&((desc)->sd_ptr_dmem[i]), (mode));	\
} while (0)

#define SEC_DESC_FREE_POINTERS(desc) do {				\
	u_int i;							\
	for (i = 0; i < SEC_POINTERS; i++)				\
		sec_free_dma_mem(&(desc)->sd_ptr_dmem[i]);		\
} while (0);

#define SEC_DESC_PUT_BACK_LT(sc, desc)					\
	SEC_PUT_BACK_LT(sc, (desc)->sd_lt_used)

#define SEC_DESC_FREE_LT(sc, desc)					\
	SEC_FREE_LT(sc, (desc)->sd_lt_used)

/* Interface for link tables */
#define SEC_ALLOC_LT_ENTRY(sc)						\
	&SEC_GET_GENERIC(sc, sc_lt, sc_lt_alloc_cnt, SEC_LT_ENTRIES)

#define SEC_PUT_BACK_LT(sc, num)					\
	SEC_ADD(sc, sc_lt_alloc_cnt, SEC_LT_ENTRIES, -(num))

#define SEC_FREE_LT(sc, num)						\
	SEC_ADD(sc, sc_lt_free_cnt, SEC_LT_ENTRIES, num)

#define SEC_FREE_LT_CNT(sc)						\
	(((sc)->sc_lt_free_cnt - (sc)->sc_lt_alloc_cnt - 1)		\
	& (SEC_LT_ENTRIES - 1))

/* DMA Maping defines */
#define SEC_MEMORY		0
#define SEC_UIO			1
#define SEC_MBUF		2

/* Size of SEC registers area */
#define SEC_IO_SIZE		0x10000

/* SEC Controller registers */
#define SEC_IER			0x1008
#define SEC_INT_CH_DN(n)	(1ULL << (((n) * 2) + 32))
#define SEC_INT_CH_ERR(n)	(1ULL << (((n) * 2) + 33))
#define SEC_INT_ITO		(1ULL << 55)

#define SEC_ISR			0x1010
#define SEC_ICR			0x1018
#define SEC_ID			0x1020

#define SEC_EUASR		0x1028
#define SEC_EUASR_RNGU(r)	(((r) >> 0) & 0xF)
#define SEC_EUASR_PKEU(r)	(((r) >> 8) & 0xF)
#define SEC_EUASR_KEU(r)	(((r) >> 16) & 0xF)
#define SEC_EUASR_CRCU(r)	(((r) >> 20) & 0xF)
#define SEC_EUASR_DEU(r)	(((r) >> 32) & 0xF)
#define SEC_EUASR_AESU(r)	(((r) >> 40) & 0xF)
#define SEC_EUASR_MDEU(r)	(((r) >> 48) & 0xF)
#define SEC_EUASR_AFEU(r)	(((r) >> 56) & 0xF)

#define SEC_MCR			0x1030
#define SEC_MCR_SWR		(1ULL << 32)

/* SEC Channel registers */
#define SEC_CHAN_CCR(n)		(((n) * 0x100) + 0x1108)
#define SEC_CHAN_CCR_CDIE	(1ULL << 1)
#define SEC_CHAN_CCR_NT		(1ULL << 2)
#define SEC_CHAN_CCR_AWSE	(1ULL << 3)
#define SEC_CHAN_CCR_CDWE	(1ULL << 4)
#define SEC_CHAN_CCR_BS		(1ULL << 8)
#define SEC_CHAN_CCR_WGN	(1ULL << 13)
#define SEC_CHAN_CCR_R		(1ULL << 32)
#define SEC_CHAN_CCR_CON	(1ULL << 33)

#define SEC_CHAN_CSR(n)		(((n) * 0x100) + 0x1110)
#define SEC_CHAN_CSR2_FFLVL_M	0x1FULL
#define SEC_CHAN_CSR2_FFLVL_S	56
#define SEC_CHAN_CSR2_GSTATE_M	0x0FULL
#define SEC_CHAN_CSR2_GSTATE_S	48
#define SEC_CHAN_CSR2_PSTATE_M	0x0FULL
#define SEC_CHAN_CSR2_PSTATE_S	40
#define SEC_CHAN_CSR2_MSTATE_M	0x3FULL
#define SEC_CHAN_CSR2_MSTATE_S	32
#define SEC_CHAN_CSR3_FFLVL_M	0x1FULL
#define SEC_CHAN_CSR3_FFLVL_S	24
#define SEC_CHAN_CSR3_MSTATE_M	0x1FFULL
#define SEC_CHAN_CSR3_MSTATE_S	32
#define SEC_CHAN_CSR3_PSTATE_M	0x7FULL
#define SEC_CHAN_CSR3_PSTATE_S	48
#define SEC_CHAN_CSR3_GSTATE_M	0x7FULL
#define SEC_CHAN_CSR3_GSTATE_S	56

#define SEC_CHAN_CDPR(n)	(((n) * 0x100) + 0x1140)
#define SEC_CHAN_FF(n)		(((n) * 0x100) + 0x1148)

/* SEC Execution Units numbers */
#define SEC_EU_NONE		0x0
#define SEC_EU_AFEU		0x1
#define SEC_EU_DEU		0x2
#define SEC_EU_MDEU_A		0x3
#define SEC_EU_MDEU_B		0xB
#define SEC_EU_RNGU		0x4
#define SEC_EU_PKEU		0x5
#define SEC_EU_AESU		0x6
#define SEC_EU_KEU		0x7
#define SEC_EU_CRCU		0x8

/* SEC descriptor types */
#define SEC_DT_COMMON_NONSNOOP	0x02
#define SEC_DT_HMAC_SNOOP	0x04

/* SEC AESU declarations and definitions */
#define SEC_AESU_MODE_ED	(1ULL << 0)
#define SEC_AESU_MODE_CBC	(1ULL << 1)

/* SEC DEU declarations and definitions */
#define SEC_DEU_MODE_ED		(1ULL << 0)
#define SEC_DEU_MODE_TS		(1ULL << 1)
#define SEC_DEU_MODE_CBC	(1ULL << 2)

/* SEC MDEU declarations and definitions */
#define SEC_HMAC_HASH_LEN	12
#define SEC_MDEU_MODE_SHA1	0x00	/* MDEU A */
#define SEC_MDEU_MODE_SHA384	0x00	/* MDEU B */
#define SEC_MDEU_MODE_SHA256	0x01
#define SEC_MDEU_MODE_MD5	0x02	/* MDEU A */
#define SEC_MDEU_MODE_SHA512	0x02	/* MDEU B */
#define SEC_MDEU_MODE_SHA224	0x03
#define SEC_MDEU_MODE_PD	(1ULL << 2)
#define SEC_MDEU_MODE_HMAC	(1ULL << 3)
#define SEC_MDEU_MODE_INIT	(1ULL << 4)
#define SEC_MDEU_MODE_SMAC	(1ULL << 5)
#define SEC_MDEU_MODE_CICV	(1ULL << 6)
#define SEC_MDEU_MODE_CONT	(1ULL << 7)

#endif
OpenPOWER on IntegriCloud