cesa.h revision 227730
1139825Simp/*-
282899Sjake * Copyright (C) 2009-2011 Semihalf.
382899Sjake * All rights reserved.
482899Sjake *
580708Sjake * Redistribution and use in source and binary forms, with or without
682899Sjake * modification, are permitted provided that the following conditions
782899Sjake * are met:
882899Sjake * 1. Redistributions of source code must retain the above copyright
982899Sjake *    notice, this list of conditions and the following disclaimer.
1082899Sjake * 2. Redistributions in binary form must reproduce the above copyright
1180708Sjake *    notice, this list of conditions and the following disclaimer in the
1282899Sjake *    documentation and/or other materials provided with the distribution.
1382899Sjake *
1482899Sjake * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1580708Sjake * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1682899Sjake * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1782899Sjake * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1882899Sjake * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1982899Sjake * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2082899Sjake * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2182899Sjake * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2282899Sjake * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2382899Sjake * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2482899Sjake * SUCH DAMAGE.
2582899Sjake *
2682899Sjake * $FreeBSD: head/sys/dev/cesa/cesa.h 227730 2011-11-19 16:30:06Z raj $
2780708Sjake */
2880708Sjake
2980708Sjake#ifndef _DEV_CESA_H_
3080708Sjake#define _DEV_CESA_H_
3180708Sjake
3280708Sjake/* Maximum number of allocated sessions */
3380709Sjake#define CESA_SESSIONS			64
3480709Sjake
3580709Sjake/* Maximum number of queued requests */
3680709Sjake#define CESA_REQUESTS			256
3780709Sjake
3880709Sjake/*
3982004Sjake * CESA is able to process data only in CESA SRAM, which is quite small (2 kB).
4080709Sjake * We have to fit a packet there, which contains SA descriptor, keys, IV
41131952Smarcel * and data to be processed. Every request must be converted into chain of
4280709Sjake * packets and each packet can hold about 1.75 kB of data.
43115970Sjake *
4480709Sjake * To process each packet we need at least 1 SA descriptor and at least 4 TDMA
4580709Sjake * descriptors. However there are cases when we use 2 SA and 8 TDMA descriptors
4680709Sjake * per packet. Number of used TDMA descriptors can increase beyond given values
4786525Sjake * if data in the request is fragmented in physical memory.
48131952Smarcel *
49131952Smarcel * The driver uses preallocated SA and TDMA descriptors pools to get best
5086525Sjake * performace. Size of these pools should match expected request size. Example:
5180709Sjake *
52131952Smarcel * Expected average request size:			1.5 kB (Ethernet MTU)
53131952Smarcel * Packets per average request:				(1.5 kB / 1.75 kB) = 1
5480709Sjake * SA decriptors per average request (worst case):	1 * 2 = 2
5580709Sjake * TDMA desctiptors per average request (worst case):	1 * 8 = 8
5680709Sjake *
5780709Sjake * More TDMA descriptors should be allocated, if data fragmentation is expected
5880709Sjake * (for example while processing mbufs larger than MCLBYTES). The driver may use
5980709Sjake * 2 additional TDMA descriptors per each discontinuity in the physical data
6080709Sjake * layout.
6180709Sjake */
6280709Sjake
6380709Sjake/* Values below are optimized for requests containing about 1.5 kB of data */
6480709Sjake#define CESA_SA_DESC_PER_REQ		2
6580709Sjake#define CESA_TDMA_DESC_PER_REQ		8
6680709Sjake
6780709Sjake#define CESA_SA_DESCRIPTORS		(CESA_SA_DESC_PER_REQ * CESA_REQUESTS)
6880709Sjake#define CESA_TDMA_DESCRIPTORS		(CESA_TDMA_DESC_PER_REQ * CESA_REQUESTS)
6980708Sjake
70/* Useful constants */
71#define CESA_HMAC_HASH_LENGTH		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_READ(sc, reg)		\
97	bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, (reg))
98#define CESA_WRITE(sc, reg, val)	\
99	bus_space_write_4((sc)->sc_bst, (sc)->sc_bsh, (reg), (val))
100
101/* Generic allocator for objects */
102#define CESA_GENERIC_ALLOC_LOCKED(sc, obj, pool) do {		\
103	CESA_LOCK(sc, pool);					\
104								\
105	if (STAILQ_EMPTY(&(sc)->sc_free_ ## pool))		\
106		obj = NULL;					\
107	else {							\
108		obj = STAILQ_FIRST(&(sc)->sc_free_ ## pool);	\
109		STAILQ_REMOVE_HEAD(&(sc)->sc_free_ ## pool,	\
110		    obj ## _stq);				\
111	}							\
112								\
113	CESA_UNLOCK(sc, pool);					\
114} while (0)
115
116#define CESA_GENERIC_FREE_LOCKED(sc, obj, pool) do {		\
117	CESA_LOCK(sc, pool);					\
118	STAILQ_INSERT_TAIL(&(sc)->sc_free_ ## pool, obj,	\
119	    obj ## _stq);					\
120	CESA_UNLOCK(sc, pool);					\
121} while (0)
122
123/* CESA SRAM offset calculation macros */
124#define CESA_SA_DATA(member)					\
125	(sizeof(struct cesa_sa_hdesc) + offsetof(struct cesa_sa_data, member))
126#define CESA_DATA(offset)					\
127	(sizeof(struct cesa_sa_hdesc) + sizeof(struct cesa_sa_data) + offset)
128
129struct cesa_tdma_hdesc {
130	uint16_t	cthd_byte_count;
131	uint16_t	cthd_flags;
132	uint32_t	cthd_src;
133	uint32_t	cthd_dst;
134	uint32_t	cthd_next;
135};
136
137struct cesa_sa_hdesc {
138	uint32_t	cshd_config;
139	uint16_t	cshd_enc_src;
140	uint16_t	cshd_enc_dst;
141	uint32_t	cshd_enc_dlen;
142	uint32_t	cshd_enc_key;
143	uint16_t	cshd_enc_iv;
144	uint16_t	cshd_enc_iv_buf;
145	uint16_t	cshd_mac_src;
146	uint16_t	cshd_mac_total_dlen;
147	uint16_t	cshd_mac_dst;
148	uint16_t	cshd_mac_dlen;
149	uint16_t	cshd_mac_iv_in;
150	uint16_t	cshd_mac_iv_out;
151};
152
153struct cesa_sa_data {
154	uint8_t		csd_key[CESA_MAX_KEY_LEN];
155	uint8_t		csd_iv[CESA_MAX_IV_LEN];
156	uint8_t		csd_hiv_in[CESA_MAX_HASH_LEN];
157	uint8_t		csd_hiv_out[CESA_MAX_HASH_LEN];
158	uint8_t		csd_hash[CESA_MAX_HASH_LEN];
159};
160
161struct cesa_dma_mem {
162	void		*cdm_vaddr;
163	bus_addr_t	cdm_paddr;
164	bus_dma_tag_t	cdm_tag;
165	bus_dmamap_t	cdm_map;
166};
167
168struct cesa_tdma_desc {
169	struct cesa_tdma_hdesc		*ctd_cthd;
170	bus_addr_t			ctd_cthd_paddr;
171
172	STAILQ_ENTRY(cesa_tdma_desc)	ctd_stq;
173};
174
175struct cesa_sa_desc {
176	struct cesa_sa_hdesc		*csd_cshd;
177	bus_addr_t			csd_cshd_paddr;
178
179	STAILQ_ENTRY(cesa_sa_desc)	csd_stq;
180};
181
182struct cesa_session {
183	uint32_t			cs_sid;
184	uint32_t			cs_config;
185	unsigned int			cs_klen;
186	unsigned int			cs_ivlen;
187	unsigned int			cs_hlen;
188	unsigned int			cs_mblen;
189	uint8_t				cs_key[CESA_MAX_KEY_LEN];
190	uint8_t				cs_aes_dkey[CESA_MAX_KEY_LEN];
191	uint8_t				cs_hiv_in[CESA_MAX_HASH_LEN];
192	uint8_t				cs_hiv_out[CESA_MAX_HASH_LEN];
193
194	STAILQ_ENTRY(cesa_session)	cs_stq;
195};
196
197struct cesa_request {
198	struct cesa_sa_data		*cr_csd;
199	bus_addr_t			cr_csd_paddr;
200	struct cryptop			*cr_crp;
201	struct cryptodesc		*cr_enc;
202	struct cryptodesc		*cr_mac;
203	struct cesa_session		*cr_cs;
204	bus_dmamap_t			cr_dmap;
205	int				cr_dmap_loaded;
206
207	STAILQ_HEAD(, cesa_tdma_desc)	cr_tdesc;
208	STAILQ_HEAD(, cesa_sa_desc)	cr_sdesc;
209
210	STAILQ_ENTRY(cesa_request)	cr_stq;
211};
212
213struct cesa_packet {
214	STAILQ_HEAD(, cesa_tdma_desc)	cp_copyin;
215	STAILQ_HEAD(, cesa_tdma_desc)	cp_copyout;
216	unsigned int			cp_size;
217	unsigned int			cp_offset;
218};
219
220struct cesa_softc {
221	device_t			sc_dev;
222	int32_t				sc_cid;
223	struct resource			*sc_res[2];
224	void				*sc_icookie;
225	bus_dma_tag_t			sc_data_dtag;
226	bus_space_tag_t			sc_bst;
227	bus_space_handle_t		sc_bsh;
228	int				sc_error;
229	int				sc_tperr;
230
231	struct mtx			sc_sc_lock;
232	int				sc_blocked;
233
234	/* TDMA descriptors pool */
235	struct mtx			sc_tdesc_lock;
236	struct cesa_tdma_desc		sc_tdesc[CESA_TDMA_DESCRIPTORS];
237	struct cesa_dma_mem		sc_tdesc_cdm;
238	STAILQ_HEAD(, cesa_tdma_desc)	sc_free_tdesc;
239
240	/* SA descriptors pool */
241	struct mtx			sc_sdesc_lock;
242	struct cesa_sa_desc		sc_sdesc[CESA_SA_DESCRIPTORS];
243	struct cesa_dma_mem		sc_sdesc_cdm;
244	STAILQ_HEAD(, cesa_sa_desc)	sc_free_sdesc;
245
246	/* Requests pool */
247	struct mtx			sc_requests_lock;
248	struct cesa_request		sc_requests[CESA_REQUESTS];
249	struct cesa_dma_mem		sc_requests_cdm;
250	STAILQ_HEAD(, cesa_request)	sc_free_requests;
251	STAILQ_HEAD(, cesa_request)	sc_ready_requests;
252	STAILQ_HEAD(, cesa_request)	sc_queued_requests;
253
254	/* Sessions pool */
255	struct mtx			sc_sessions_lock;
256	struct cesa_session		sc_sessions[CESA_SESSIONS];
257	STAILQ_HEAD(, cesa_session)	sc_free_sessions;
258
259	/* CESA SRAM Address */
260	bus_addr_t			sc_sram_base;
261};
262
263struct cesa_chain_info {
264	struct cesa_softc		*cci_sc;
265	struct cesa_request		*cci_cr;
266	struct cryptodesc		*cci_enc;
267	struct cryptodesc		*cci_mac;
268	uint32_t			cci_config;
269	int				cci_error;
270};
271
272/* CESA descriptors flags definitions */
273#define CESA_CTHD_OWNED			(1 << 15)
274
275#define CESA_CSHD_MAC			(0 << 0)
276#define CESA_CSHD_ENC			(1 << 0)
277#define CESA_CSHD_MAC_AND_ENC		(2 << 0)
278#define CESA_CSHD_ENC_AND_MAC		(3 << 0)
279#define CESA_CSHD_OP_MASK		(3 << 0)
280
281#define CESA_CSHD_MD5			(4 << 4)
282#define CESA_CSHD_SHA1			(5 << 4)
283#define CESA_CSHD_MD5_HMAC		((6 << 4) | (1 << 7))
284#define CESA_CSHD_SHA1_HMAC		((7 << 4) | (1 << 7))
285
286#define CESA_CSHD_DES			(1 << 8)
287#define CESA_CSHD_3DES			(2 << 8)
288#define CESA_CSHD_AES			(3 << 8)
289
290#define CESA_CSHD_DECRYPT		(1 << 12)
291#define CESA_CSHD_CBC			(1 << 16)
292#define CESA_CSHD_3DES_EDE		(1 << 20)
293
294#define CESA_CSH_AES_KLEN_128		(0 << 24)
295#define CESA_CSH_AES_KLEN_192		(1 << 24)
296#define CESA_CSH_AES_KLEN_256		(2 << 24)
297#define CESA_CSH_AES_KLEN_MASK		(3 << 24)
298
299#define CESA_CSHD_FRAG_FIRST		(1 << 30)
300#define CESA_CSHD_FRAG_LAST		(2 << 30)
301#define CESA_CSHD_FRAG_MIDDLE		(3 << 30)
302
303/* CESA registers definitions */
304#define CESA_ICR			0xDE20
305#define CESA_ICR_ACCTDMA		(1 << 7)
306#define CESA_ICR_TPERR			(1 << 12)
307
308#define CESA_ICM			0xDE24
309#define CESA_ICM_ACCTDMA		CESA_ICR_ACCTDMA
310#define CESA_ICM_TPERR			CESA_ICR_TPERR
311
312/* CESA TDMA registers definitions */
313#define CESA_TDMA_ND			0x0830
314
315#define CESA_TDMA_CR			0x0840
316#define CESA_TDMA_CR_DBL128		(4 << 0)
317#define CESA_TDMA_CR_ORDEN		(1 << 4)
318#define CESA_TDMA_CR_SBL128		(4 << 6)
319#define CESA_TDMA_CR_NBS		(1 << 11)
320#define CESA_TDMA_CR_ENABLE		(1 << 12)
321#define CESA_TDMA_CR_FETCHND		(1 << 13)
322#define CESA_TDMA_CR_ACTIVE		(1 << 14)
323
324#define CESA_TDMA_ECR			0x08C8
325#define CESA_TDMA_ECR_MISS		(1 << 0)
326#define CESA_TDMA_ECR_DOUBLE_HIT	(1 << 1)
327#define CESA_TDMA_ECR_BOTH_HIT		(1 << 2)
328#define CESA_TDMA_ECR_DATA_ERROR	(1 << 3)
329
330#define CESA_TDMA_EMR			0x08CC
331#define CESA_TDMA_EMR_MISS		CESA_TDMA_ECR_MISS
332#define CESA_TDMA_EMR_DOUBLE_HIT	CESA_TDMA_ECR_DOUBLE_HIT
333#define CESA_TDMA_EMR_BOTH_HIT		CESA_TDMA_ECR_BOTH_HIT
334#define CESA_TDMA_EMR_DATA_ERROR	CESA_TDMA_ECR_DATA_ERROR
335
336/* CESA SA registers definitions */
337#define CESA_SA_CMD			0xDE00
338#define CESA_SA_CMD_ACTVATE		(1 << 0)
339
340#define CESA_SA_DPR			0xDE04
341
342#define CESA_SA_CR			0xDE08
343#define CESA_SA_CR_WAIT_FOR_TDMA	(1 << 7)
344#define CESA_SA_CR_ACTIVATE_TDMA	(1 << 9)
345#define CESA_SA_CR_MULTI_MODE		(1 << 11)
346
347#define CESA_SA_SR			0xDE0C
348#define CESA_SA_SR_ACTIVE		(1 << 0)
349
350#endif
351