cesa.h revision 301223
1/*-
2 * Copyright (C) 2009-2011 Semihalf.
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 AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 *
26 * $FreeBSD: head/sys/dev/cesa/cesa.h 301223 2016-06-02 18:37:50Z zbb $
27 */
28
29#ifndef _DEV_CESA_H_
30#define _DEV_CESA_H_
31
32/* Maximum number of allocated sessions */
33#define CESA_SESSIONS			64
34
35/* Maximum number of queued requests */
36#define CESA_REQUESTS			256
37
38/*
39 * CESA is able to process data only in CESA SRAM, which is quite small (2 kB).
40 * We have to fit a packet there, which contains SA descriptor, keys, IV
41 * and data to be processed. Every request must be converted into chain of
42 * packets and each packet can hold about 1.75 kB of data.
43 *
44 * To process each packet we need at least 1 SA descriptor and at least 4 TDMA
45 * descriptors. However there are cases when we use 2 SA and 8 TDMA descriptors
46 * per packet. Number of used TDMA descriptors can increase beyond given values
47 * if data in the request is fragmented in physical memory.
48 *
49 * The driver uses preallocated SA and TDMA descriptors pools to get best
50 * performace. Size of these pools should match expected request size. Example:
51 *
52 * Expected average request size:			1.5 kB (Ethernet MTU)
53 * Packets per average request:				(1.5 kB / 1.75 kB) = 1
54 * SA decriptors per average request (worst case):	1 * 2 = 2
55 * TDMA desctiptors per average request (worst case):	1 * 8 = 8
56 *
57 * More TDMA descriptors should be allocated, if data fragmentation is expected
58 * (for example while processing mbufs larger than MCLBYTES). The driver may use
59 * 2 additional TDMA descriptors per each discontinuity in the physical data
60 * layout.
61 */
62
63/* Values below are optimized for requests containing about 1.5 kB of data */
64#define CESA_SA_DESC_PER_REQ		2
65#define CESA_TDMA_DESC_PER_REQ		8
66
67#define CESA_SA_DESCRIPTORS		(CESA_SA_DESC_PER_REQ * CESA_REQUESTS)
68#define CESA_TDMA_DESCRIPTORS		(CESA_TDMA_DESC_PER_REQ * CESA_REQUESTS)
69
70/* Useful constants */
71#define CESA_HMAC_TRUNC_LEN		12
72#define CESA_MAX_FRAGMENTS		64
73#define CESA_SRAM_SIZE			2048
74
75/*
76 * CESA_MAX_HASH_LEN is maximum length of hash generated by CESA.
77 * As CESA suports only MD5 and SHA1 this equals to 20 bytes.
78 * However we increase the value to 24 bytes to meet alignment
79 * requirements in cesa_sa_data structure.
80 */
81#define CESA_MAX_HASH_LEN		24
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 */
135enum cesa_res_type {
136	RES_TDMA_REGS,
137	RES_CESA_REGS,
138	RES_CESA_IRQ,
139	RES_CESA_NUM
140};
141
142struct 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
150struct 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
166struct 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
174struct 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
181struct 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
188struct 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
195struct cesa_session {
196	uint32_t			cs_sid;
197	uint32_t			cs_config;
198	unsigned int			cs_klen;
199	unsigned int			cs_ivlen;
200	unsigned int			cs_hlen;
201	unsigned int			cs_mblen;
202	uint8_t				cs_key[CESA_MAX_KEY_LEN];
203	uint8_t				cs_aes_dkey[CESA_MAX_KEY_LEN];
204	uint8_t				cs_hiv_in[CESA_MAX_HASH_LEN];
205	uint8_t				cs_hiv_out[CESA_MAX_HASH_LEN];
206
207	STAILQ_ENTRY(cesa_session)	cs_stq;
208};
209
210struct cesa_request {
211	struct cesa_sa_data		*cr_csd;
212	bus_addr_t			cr_csd_paddr;
213	struct cryptop			*cr_crp;
214	struct cryptodesc		*cr_enc;
215	struct cryptodesc		*cr_mac;
216	struct cesa_session		*cr_cs;
217	bus_dmamap_t			cr_dmap;
218	int				cr_dmap_loaded;
219
220	STAILQ_HEAD(, cesa_tdma_desc)	cr_tdesc;
221	STAILQ_HEAD(, cesa_sa_desc)	cr_sdesc;
222
223	STAILQ_ENTRY(cesa_request)	cr_stq;
224};
225
226struct cesa_packet {
227	STAILQ_HEAD(, cesa_tdma_desc)	cp_copyin;
228	STAILQ_HEAD(, cesa_tdma_desc)	cp_copyout;
229	unsigned int			cp_size;
230	unsigned int			cp_offset;
231};
232
233struct cesa_softc {
234	device_t			sc_dev;
235	int32_t				sc_cid;
236	struct resource			*sc_res[RES_CESA_NUM];
237	void				*sc_icookie;
238	bus_dma_tag_t			sc_data_dtag;
239	int				sc_error;
240	int				sc_tperr;
241
242	struct mtx			sc_sc_lock;
243	int				sc_blocked;
244
245	/* TDMA descriptors pool */
246	struct mtx			sc_tdesc_lock;
247	struct cesa_tdma_desc		sc_tdesc[CESA_TDMA_DESCRIPTORS];
248	struct cesa_dma_mem		sc_tdesc_cdm;
249	STAILQ_HEAD(, cesa_tdma_desc)	sc_free_tdesc;
250
251	/* SA descriptors pool */
252	struct mtx			sc_sdesc_lock;
253	struct cesa_sa_desc		sc_sdesc[CESA_SA_DESCRIPTORS];
254	struct cesa_dma_mem		sc_sdesc_cdm;
255	STAILQ_HEAD(, cesa_sa_desc)	sc_free_sdesc;
256
257	/* Requests pool */
258	struct mtx			sc_requests_lock;
259	struct cesa_request		sc_requests[CESA_REQUESTS];
260	struct cesa_dma_mem		sc_requests_cdm;
261	STAILQ_HEAD(, cesa_request)	sc_free_requests;
262	STAILQ_HEAD(, cesa_request)	sc_ready_requests;
263	STAILQ_HEAD(, cesa_request)	sc_queued_requests;
264
265	/* Sessions pool */
266	struct mtx			sc_sessions_lock;
267	struct cesa_session		sc_sessions[CESA_SESSIONS];
268	STAILQ_HEAD(, cesa_session)	sc_free_sessions;
269
270	/* CESA SRAM Address */
271	bus_addr_t			sc_sram_base_pa;
272	bus_space_handle_t		sc_sram_base_va;
273	bus_size_t			sc_sram_size;
274};
275
276struct cesa_chain_info {
277	struct cesa_softc		*cci_sc;
278	struct cesa_request		*cci_cr;
279	struct cryptodesc		*cci_enc;
280	struct cryptodesc		*cci_mac;
281	uint32_t			cci_config;
282	int				cci_error;
283};
284
285/* CESA descriptors flags definitions */
286#define CESA_CTHD_OWNED			(1 << 15)
287
288#define CESA_CSHD_MAC			(0 << 0)
289#define CESA_CSHD_ENC			(1 << 0)
290#define CESA_CSHD_MAC_AND_ENC		(2 << 0)
291#define CESA_CSHD_ENC_AND_MAC		(3 << 0)
292#define CESA_CSHD_OP_MASK		(3 << 0)
293
294#define CESA_CSHD_MD5			(4 << 4)
295#define CESA_CSHD_SHA1			(5 << 4)
296#define CESA_CSHD_MD5_HMAC		(6 << 4)
297#define CESA_CSHD_SHA1_HMAC		(7 << 4)
298
299#define CESA_CSHD_96_BIT_HMAC		(1 << 7)
300
301#define CESA_CSHD_DES			(1 << 8)
302#define CESA_CSHD_3DES			(2 << 8)
303#define CESA_CSHD_AES			(3 << 8)
304
305#define CESA_CSHD_DECRYPT		(1 << 12)
306#define CESA_CSHD_CBC			(1 << 16)
307#define CESA_CSHD_3DES_EDE		(1 << 20)
308
309#define CESA_CSH_AES_KLEN_128		(0 << 24)
310#define CESA_CSH_AES_KLEN_192		(1 << 24)
311#define CESA_CSH_AES_KLEN_256		(2 << 24)
312#define CESA_CSH_AES_KLEN_MASK		(3 << 24)
313
314#define CESA_CSHD_FRAG_FIRST		(1 << 30)
315#define CESA_CSHD_FRAG_LAST		(2U << 30)
316#define CESA_CSHD_FRAG_MIDDLE		(3U << 30)
317
318/* CESA registers definitions */
319#define CESA_ICR			0x0E20
320#define CESA_ICR_ACCTDMA		(1 << 7)
321#define CESA_ICR_TPERR			(1 << 12)
322
323#define CESA_ICM			0x0E24
324#define CESA_ICM_ACCTDMA		CESA_ICR_ACCTDMA
325#define CESA_ICM_TPERR			CESA_ICR_TPERR
326
327/* CESA TDMA registers definitions */
328#define CESA_TDMA_ND			0x0830
329
330#define CESA_TDMA_CR			0x0840
331#define CESA_TDMA_CR_DBL128		(4 << 0)
332#define CESA_TDMA_CR_ORDEN		(1 << 4)
333#define CESA_TDMA_CR_SBL128		(4 << 6)
334#define CESA_TDMA_CR_NBS		(1 << 11)
335#define CESA_TDMA_CR_ENABLE		(1 << 12)
336#define CESA_TDMA_CR_FETCHND		(1 << 13)
337#define CESA_TDMA_CR_ACTIVE		(1 << 14)
338
339#define CESA_TDMA_ECR			0x08C8
340#define CESA_TDMA_ECR_MISS		(1 << 0)
341#define CESA_TDMA_ECR_DOUBLE_HIT	(1 << 1)
342#define CESA_TDMA_ECR_BOTH_HIT		(1 << 2)
343#define CESA_TDMA_ECR_DATA_ERROR	(1 << 3)
344
345#define CESA_TDMA_EMR			0x08CC
346#define CESA_TDMA_EMR_MISS		CESA_TDMA_ECR_MISS
347#define CESA_TDMA_EMR_DOUBLE_HIT	CESA_TDMA_ECR_DOUBLE_HIT
348#define CESA_TDMA_EMR_BOTH_HIT		CESA_TDMA_ECR_BOTH_HIT
349#define CESA_TDMA_EMR_DATA_ERROR	CESA_TDMA_ECR_DATA_ERROR
350
351/*  CESA TDMA address decoding registers */
352#define MV_WIN_CESA_CTRL(n)		(0x8 * (n) + 0xA04)
353#define MV_WIN_CESA_BASE(n)		(0x8 * (n) + 0xA00)
354#define MV_WIN_CESA_MAX			4
355
356/* CESA SA registers definitions */
357#define CESA_SA_CMD			0x0E00
358#define CESA_SA_CMD_ACTVATE		(1 << 0)
359
360#define CESA_SA_DPR			0x0E04
361
362#define CESA_SA_CR			0x0E08
363#define CESA_SA_CR_WAIT_FOR_TDMA	(1 << 7)
364#define CESA_SA_CR_ACTIVATE_TDMA	(1 << 9)
365#define CESA_SA_CR_MULTI_MODE		(1 << 11)
366
367#define CESA_SA_SR			0x0E0C
368#define CESA_SA_SR_ACTIVE		(1 << 0)
369
370#endif
371