1/*-
2 * Copyright (C) 2008-2009 Semihalf, Piotr Ziecik
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
15 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
17 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
18 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
19 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
21 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
22 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
23 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 *
25 * $FreeBSD$
26 */
27
28#ifndef	_SEC_H
29#define _SEC_H
30
31/*
32 * Each SEC channel can hold up to 24 descriptors. All 4 channels can be
33 * simultaneously active holding 96 descriptors. Each descriptor can use 0 or
34 * more link table entries depending of size and granulation of input/output
35 * data. One link table entry is needed for each 65535 bytes of data.
36 */
37
38/* Driver settings */
39#define SEC_TIMEOUT			100000
40#define SEC_MAX_SESSIONS		256
41#define SEC_DESCRIPTORS			256	/* Must be power of 2 */
42#define SEC_LT_ENTRIES			1024	/* Must be power of 2 */
43#define SEC_MAX_IV_LEN			16
44#define SEC_MAX_KEY_LEN			64
45
46/* SEC information */
47#define SEC_20_ID			0x0000000000000040ULL
48#define SEC_30_ID			0x0030030000000000ULL
49#define SEC_31_ID			0x0030030100000000ULL
50#define SEC_CHANNELS			4
51#define SEC_POINTERS			7
52#define SEC_MAX_DMA_BLOCK_SIZE		0xFFFF
53#define SEC_MAX_FIFO_LEVEL		24
54#define SEC_DMA_ALIGNMENT		8
55
56#define __packed__			__attribute__ ((__packed__))
57
58struct sec_softc;
59struct sec_session;
60
61/* SEC descriptor definition */
62struct sec_hw_desc_ptr {
63	u_int		shdp_length		: 16;
64	u_int		shdp_j			: 1;
65	u_int		shdp_extent		: 7;
66	u_int		__padding0		: 4;
67	uint64_t	shdp_ptr		: 36;
68} __packed__;
69
70struct sec_hw_desc {
71	union __packed__ {
72		struct __packed__ {
73			u_int	eu_sel0		: 4;
74			u_int	mode0		: 8;
75			u_int	eu_sel1		: 4;
76			u_int	mode1		: 8;
77			u_int	desc_type	: 5;
78			u_int	__padding0	: 1;
79			u_int	dir		: 1;
80			u_int	dn		: 1;
81			u_int	__padding1	: 32;
82		} request;
83		struct __packed__ {
84			u_int	done		: 8;
85			u_int	__padding0	: 27;
86			u_int	iccr0		: 2;
87			u_int	__padding1	: 6;
88			u_int	iccr1		: 2;
89			u_int	__padding2	: 19;
90		} feedback;
91	} shd_control;
92
93	struct sec_hw_desc_ptr	shd_pointer[SEC_POINTERS];
94
95	/* Data below is mapped to descriptor pointers */
96	uint8_t			shd_iv[SEC_MAX_IV_LEN];
97	uint8_t			shd_key[SEC_MAX_KEY_LEN];
98	uint8_t			shd_mkey[SEC_MAX_KEY_LEN];
99} __packed__;
100
101#define shd_eu_sel0		shd_control.request.eu_sel0
102#define shd_mode0		shd_control.request.mode0
103#define shd_eu_sel1		shd_control.request.eu_sel1
104#define shd_mode1		shd_control.request.mode1
105#define shd_desc_type		shd_control.request.desc_type
106#define shd_dir			shd_control.request.dir
107#define shd_dn			shd_control.request.dn
108#define shd_done		shd_control.feedback.done
109#define shd_iccr0		shd_control.feedback.iccr0
110#define shd_iccr1		shd_control.feedback.iccr1
111
112/* SEC link table entries definition */
113struct sec_hw_lt {
114	u_int			shl_length	: 16;
115	u_int			__padding0	: 6;
116	u_int			shl_r		: 1;
117	u_int			shl_n		: 1;
118	u_int			__padding1	: 4;
119	uint64_t		shl_ptr		: 36;
120} __packed__;
121
122struct sec_dma_mem {
123	void			*dma_vaddr;
124	bus_addr_t		dma_paddr;
125	bus_dma_tag_t		dma_tag;
126	bus_dmamap_t		dma_map;
127	u_int			dma_is_map;
128};
129
130struct sec_desc {
131	struct sec_hw_desc	*sd_desc;
132	bus_addr_t		sd_desc_paddr;
133	struct sec_dma_mem	sd_ptr_dmem[SEC_POINTERS];
134	struct cryptop		*sd_crp;
135	u_int			sd_lt_used;
136	u_int			sd_error;
137};
138
139struct sec_lt {
140	struct sec_hw_lt	*sl_lt;
141	bus_addr_t		sl_lt_paddr;
142};
143
144struct sec_eu_methods {
145	int	(*sem_newsession)(struct sec_softc *sc,
146	    struct sec_session *ses, struct cryptoini *enc,
147	    struct cryptoini *mac);
148	int	(*sem_make_desc)(struct sec_softc *sc,
149	    struct sec_session *ses, struct sec_desc *desc,
150	    struct cryptop *crp, int buftype);
151};
152
153struct sec_session {
154	u_int			ss_used;
155	struct sec_eu_methods	*ss_eu;
156	uint8_t			ss_key[SEC_MAX_KEY_LEN];
157	uint8_t			ss_mkey[SEC_MAX_KEY_LEN];
158	u_int			ss_klen;
159	u_int			ss_mklen;
160	u_int			ss_ivlen;
161};
162
163struct sec_desc_map_info {
164	struct sec_softc	*sdmi_sc;
165	bus_size_t		sdmi_size;
166	bus_size_t		sdmi_offset;
167	struct sec_lt		*sdmi_lt_first;
168	struct sec_lt		*sdmi_lt_last;
169	u_int			sdmi_lt_used;
170};
171
172struct sec_softc {
173	device_t		sc_dev;
174	int32_t			sc_cid;
175	int			sc_blocked;
176	int			sc_shutdown;
177	u_int			sc_version;
178
179	uint64_t		sc_int_error_mask;
180	uint64_t		sc_channel_idle_mask;
181
182	struct sec_session	sc_sessions[SEC_MAX_SESSIONS];
183
184	struct mtx		sc_controller_lock;
185	struct mtx		sc_descriptors_lock;
186	struct mtx		sc_sessions_lock;
187
188	struct sec_desc		sc_desc[SEC_DESCRIPTORS];
189	u_int			sc_free_desc_get_cnt;
190	u_int			sc_free_desc_put_cnt;
191	u_int			sc_ready_desc_get_cnt;
192	u_int			sc_ready_desc_put_cnt;
193	u_int			sc_queued_desc_get_cnt;
194	u_int			sc_queued_desc_put_cnt;
195
196	struct sec_lt		sc_lt[SEC_LT_ENTRIES + 1];
197	u_int			sc_lt_alloc_cnt;
198	u_int			sc_lt_free_cnt;
199
200	struct sec_dma_mem	sc_desc_dmem;	/* descriptors DMA memory */
201	struct sec_dma_mem	sc_lt_dmem;	/* link tables DMA memory */
202
203	struct resource		*sc_rres;	/* register resource */
204        int			sc_rrid;	/* register rid */
205	struct {
206		bus_space_tag_t	bst;
207		bus_space_handle_t bsh;
208	} sc_bas;
209
210	struct resource		*sc_pri_ires;	/* primary irq resource */
211	void			*sc_pri_ihand;	/* primary irq handler */
212	int			sc_pri_irid;	/* primary irq resource id */
213
214	struct resource		*sc_sec_ires;	/* secondary irq resource */
215	void			*sc_sec_ihand;	/* secondary irq handler */
216	int			sc_sec_irid;	/* secondary irq resource id */
217};
218
219/* Locking macros */
220#define SEC_LOCK(sc, what)						\
221	mtx_lock(&(sc)->sc_ ## what ## _lock)
222#define SEC_UNLOCK(sc, what)						\
223	mtx_unlock(&(sc)->sc_ ## what ## _lock)
224#define SEC_LOCK_ASSERT(sc, what)					\
225	mtx_assert(&(sc)->sc_ ## what ## _lock, MA_OWNED)
226
227/* Read/Write definitions */
228#define SEC_READ(sc, reg)						\
229	bus_space_read_8((sc)->sc_bas.bst, (sc)->sc_bas.bsh, (reg))
230#define SEC_WRITE(sc, reg, val)						\
231	bus_space_write_8((sc)->sc_bas.bst, (sc)->sc_bas.bsh, (reg), (val))
232
233/* Base allocation macros (warning: wrap must be 2^n) */
234#define SEC_CNT_INIT(sc, cnt, wrap)					\
235	(((sc)->cnt) = ((wrap) - 1))
236#define SEC_ADD(sc, cnt, wrap, val)					\
237	((sc)->cnt = (((sc)->cnt) + (val)) & ((wrap) - 1))
238#define SEC_INC(sc, cnt, wrap)						\
239	SEC_ADD(sc, cnt, wrap, 1)
240#define SEC_DEC(sc, cnt, wrap)						\
241	SEC_ADD(sc, cnt, wrap, -1)
242#define SEC_GET_GENERIC(sc, tab, cnt, wrap)				\
243	((sc)->tab[SEC_INC(sc, cnt, wrap)])
244#define SEC_PUT_GENERIC(sc, tab, cnt, wrap, val)			\
245	((sc)->tab[SEC_INC(sc, cnt, wrap)] = val)
246
247/* Interface for descriptors */
248#define SEC_GET_FREE_DESC(sc)						\
249	&SEC_GET_GENERIC(sc, sc_desc, sc_free_desc_get_cnt, SEC_DESCRIPTORS)
250
251#define SEC_PUT_BACK_FREE_DESC(sc)					\
252	SEC_DEC(sc, sc_free_desc_get_cnt, SEC_DESCRIPTORS)
253
254#define SEC_DESC_FREE2READY(sc)						\
255	SEC_INC(sc, sc_ready_desc_put_cnt, SEC_DESCRIPTORS)
256
257#define SEC_GET_READY_DESC(sc)						\
258	&SEC_GET_GENERIC(sc, sc_desc, sc_ready_desc_get_cnt, SEC_DESCRIPTORS)
259
260#define SEC_PUT_BACK_READY_DESC(sc)					\
261	SEC_DEC(sc, sc_ready_desc_get_cnt, SEC_DESCRIPTORS)
262
263#define SEC_DESC_READY2QUEUED(sc)					\
264	SEC_INC(sc, sc_queued_desc_put_cnt, SEC_DESCRIPTORS)
265
266#define SEC_GET_QUEUED_DESC(sc)						\
267	&SEC_GET_GENERIC(sc, sc_desc, sc_queued_desc_get_cnt, SEC_DESCRIPTORS)
268
269#define SEC_PUT_BACK_QUEUED_DESC(sc)					\
270	SEC_DEC(sc, sc_queued_desc_get_cnt, SEC_DESCRIPTORS)
271
272#define SEC_DESC_QUEUED2FREE(sc)					\
273	SEC_INC(sc, sc_free_desc_put_cnt, SEC_DESCRIPTORS)
274
275#define SEC_FREE_DESC_CNT(sc)						\
276	(((sc)->sc_free_desc_put_cnt - (sc)->sc_free_desc_get_cnt - 1)	\
277	& (SEC_DESCRIPTORS - 1))
278
279#define SEC_READY_DESC_CNT(sc)						\
280	(((sc)->sc_ready_desc_put_cnt - (sc)->sc_ready_desc_get_cnt) &	\
281	(SEC_DESCRIPTORS - 1))
282
283#define SEC_QUEUED_DESC_CNT(sc)						\
284	(((sc)->sc_queued_desc_put_cnt - (sc)->sc_queued_desc_get_cnt)	\
285	& (SEC_DESCRIPTORS - 1))
286
287#define SEC_DESC_SYNC(sc, mode) do {					\
288	sec_sync_dma_mem(&((sc)->sc_desc_dmem), (mode));		\
289	sec_sync_dma_mem(&((sc)->sc_lt_dmem), (mode));			\
290} while (0)
291
292#define SEC_DESC_SYNC_POINTERS(desc, mode) do {				\
293	u_int i;							\
294	for (i = 0; i < SEC_POINTERS; i++)				\
295		sec_sync_dma_mem(&((desc)->sd_ptr_dmem[i]), (mode));	\
296} while (0)
297
298#define SEC_DESC_FREE_POINTERS(desc) do {				\
299	u_int i;							\
300	for (i = 0; i < SEC_POINTERS; i++)				\
301		sec_free_dma_mem(&(desc)->sd_ptr_dmem[i]);		\
302} while (0);
303
304#define SEC_DESC_PUT_BACK_LT(sc, desc)					\
305	SEC_PUT_BACK_LT(sc, (desc)->sd_lt_used)
306
307#define SEC_DESC_FREE_LT(sc, desc)					\
308	SEC_FREE_LT(sc, (desc)->sd_lt_used)
309
310/* Interface for link tables */
311#define SEC_ALLOC_LT_ENTRY(sc)						\
312	&SEC_GET_GENERIC(sc, sc_lt, sc_lt_alloc_cnt, SEC_LT_ENTRIES)
313
314#define SEC_PUT_BACK_LT(sc, num)					\
315	SEC_ADD(sc, sc_lt_alloc_cnt, SEC_LT_ENTRIES, -(num))
316
317#define SEC_FREE_LT(sc, num)						\
318	SEC_ADD(sc, sc_lt_free_cnt, SEC_LT_ENTRIES, num)
319
320#define SEC_FREE_LT_CNT(sc)						\
321	(((sc)->sc_lt_free_cnt - (sc)->sc_lt_alloc_cnt - 1)		\
322	& (SEC_LT_ENTRIES - 1))
323
324/* DMA Maping defines */
325#define SEC_MEMORY		0
326#define SEC_UIO			1
327#define SEC_MBUF		2
328
329/* Size of SEC registers area */
330#define SEC_IO_SIZE		0x10000
331
332/* SEC Controller registers */
333#define SEC_IER			0x1008
334#define SEC_INT_CH_DN(n)	(1ULL << (((n) * 2) + 32))
335#define SEC_INT_CH_ERR(n)	(1ULL << (((n) * 2) + 33))
336#define SEC_INT_ITO		(1ULL << 55)
337
338#define SEC_ISR			0x1010
339#define SEC_ICR			0x1018
340#define SEC_ID			0x1020
341
342#define SEC_EUASR		0x1028
343#define SEC_EUASR_RNGU(r)	(((r) >> 0) & 0xF)
344#define SEC_EUASR_PKEU(r)	(((r) >> 8) & 0xF)
345#define SEC_EUASR_KEU(r)	(((r) >> 16) & 0xF)
346#define SEC_EUASR_CRCU(r)	(((r) >> 20) & 0xF)
347#define SEC_EUASR_DEU(r)	(((r) >> 32) & 0xF)
348#define SEC_EUASR_AESU(r)	(((r) >> 40) & 0xF)
349#define SEC_EUASR_MDEU(r)	(((r) >> 48) & 0xF)
350#define SEC_EUASR_AFEU(r)	(((r) >> 56) & 0xF)
351
352#define SEC_MCR			0x1030
353#define SEC_MCR_SWR		(1ULL << 32)
354
355/* SEC Channel registers */
356#define SEC_CHAN_CCR(n)		(((n) * 0x100) + 0x1108)
357#define SEC_CHAN_CCR_CDIE	(1ULL << 1)
358#define SEC_CHAN_CCR_NT		(1ULL << 2)
359#define SEC_CHAN_CCR_AWSE	(1ULL << 3)
360#define SEC_CHAN_CCR_CDWE	(1ULL << 4)
361#define SEC_CHAN_CCR_BS		(1ULL << 8)
362#define SEC_CHAN_CCR_WGN	(1ULL << 13)
363#define SEC_CHAN_CCR_R		(1ULL << 32)
364#define SEC_CHAN_CCR_CON	(1ULL << 33)
365
366#define SEC_CHAN_CSR(n)		(((n) * 0x100) + 0x1110)
367#define SEC_CHAN_CSR2_FFLVL_M	0x1FULL
368#define SEC_CHAN_CSR2_FFLVL_S	56
369#define SEC_CHAN_CSR2_GSTATE_M	0x0FULL
370#define SEC_CHAN_CSR2_GSTATE_S	48
371#define SEC_CHAN_CSR2_PSTATE_M	0x0FULL
372#define SEC_CHAN_CSR2_PSTATE_S	40
373#define SEC_CHAN_CSR2_MSTATE_M	0x3FULL
374#define SEC_CHAN_CSR2_MSTATE_S	32
375#define SEC_CHAN_CSR3_FFLVL_M	0x1FULL
376#define SEC_CHAN_CSR3_FFLVL_S	24
377#define SEC_CHAN_CSR3_MSTATE_M	0x1FFULL
378#define SEC_CHAN_CSR3_MSTATE_S	32
379#define SEC_CHAN_CSR3_PSTATE_M	0x7FULL
380#define SEC_CHAN_CSR3_PSTATE_S	48
381#define SEC_CHAN_CSR3_GSTATE_M	0x7FULL
382#define SEC_CHAN_CSR3_GSTATE_S	56
383
384#define SEC_CHAN_CDPR(n)	(((n) * 0x100) + 0x1140)
385#define SEC_CHAN_FF(n)		(((n) * 0x100) + 0x1148)
386
387/* SEC Execution Units numbers */
388#define SEC_EU_NONE		0x0
389#define SEC_EU_AFEU		0x1
390#define SEC_EU_DEU		0x2
391#define SEC_EU_MDEU_A		0x3
392#define SEC_EU_MDEU_B		0xB
393#define SEC_EU_RNGU		0x4
394#define SEC_EU_PKEU		0x5
395#define SEC_EU_AESU		0x6
396#define SEC_EU_KEU		0x7
397#define SEC_EU_CRCU		0x8
398
399/* SEC descriptor types */
400#define SEC_DT_COMMON_NONSNOOP	0x02
401#define SEC_DT_HMAC_SNOOP	0x04
402
403/* SEC AESU declarations and definitions */
404#define SEC_AESU_MODE_ED	(1ULL << 0)
405#define SEC_AESU_MODE_CBC	(1ULL << 1)
406
407/* SEC DEU declarations and definitions */
408#define SEC_DEU_MODE_ED		(1ULL << 0)
409#define SEC_DEU_MODE_TS		(1ULL << 1)
410#define SEC_DEU_MODE_CBC	(1ULL << 2)
411
412/* SEC MDEU declarations and definitions */
413#define SEC_HMAC_HASH_LEN	12
414#define SEC_MDEU_MODE_SHA1	0x00	/* MDEU A */
415#define SEC_MDEU_MODE_SHA384	0x00	/* MDEU B */
416#define SEC_MDEU_MODE_SHA256	0x01
417#define SEC_MDEU_MODE_MD5	0x02	/* MDEU A */
418#define SEC_MDEU_MODE_SHA512	0x02	/* MDEU B */
419#define SEC_MDEU_MODE_SHA224	0x03
420#define SEC_MDEU_MODE_PD	(1ULL << 2)
421#define SEC_MDEU_MODE_HMAC	(1ULL << 3)
422#define SEC_MDEU_MODE_INIT	(1ULL << 4)
423#define SEC_MDEU_MODE_SMAC	(1ULL << 5)
424#define SEC_MDEU_MODE_CICV	(1ULL << 6)
425#define SEC_MDEU_MODE_CONT	(1ULL << 7)
426
427#endif
428