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
|
/*-
* Copyright (C) 2009-2011 Semihalf.
* 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 AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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 _DEV_CESA_H_
#define _DEV_CESA_H_
/* Maximum number of allocated sessions */
#define CESA_SESSIONS 64
/* Maximum number of queued requests */
#define CESA_REQUESTS 256
/*
* CESA is able to process data only in CESA SRAM, which is quite small (2 kB).
* We have to fit a packet there, which contains SA descriptor, keys, IV
* and data to be processed. Every request must be converted into chain of
* packets and each packet can hold about 1.75 kB of data.
*
* To process each packet we need at least 1 SA descriptor and at least 4 TDMA
* descriptors. However there are cases when we use 2 SA and 8 TDMA descriptors
* per packet. Number of used TDMA descriptors can increase beyond given values
* if data in the request is fragmented in physical memory.
*
* The driver uses preallocated SA and TDMA descriptors pools to get best
* performace. Size of these pools should match expected request size. Example:
*
* Expected average request size: 1.5 kB (Ethernet MTU)
* Packets per average request: (1.5 kB / 1.75 kB) = 1
* SA decriptors per average request (worst case): 1 * 2 = 2
* TDMA desctiptors per average request (worst case): 1 * 8 = 8
*
* More TDMA descriptors should be allocated, if data fragmentation is expected
* (for example while processing mbufs larger than MCLBYTES). The driver may use
* 2 additional TDMA descriptors per each discontinuity in the physical data
* layout.
*/
/* Values below are optimized for requests containing about 1.5 kB of data */
#define CESA_SA_DESC_PER_REQ 2
#define CESA_TDMA_DESC_PER_REQ 8
#define CESA_SA_DESCRIPTORS (CESA_SA_DESC_PER_REQ * CESA_REQUESTS)
#define CESA_TDMA_DESCRIPTORS (CESA_TDMA_DESC_PER_REQ * CESA_REQUESTS)
/* Useful constants */
#define CESA_HMAC_HASH_LENGTH 12
#define CESA_MAX_FRAGMENTS 64
#define CESA_SRAM_SIZE 2048
/*
* CESA_MAX_HASH_LEN is maximum length of hash generated by CESA.
* As CESA suports only MD5 and SHA1 this equals to 20 bytes.
* However we increase the value to 24 bytes to meet alignment
* requirements in cesa_sa_data structure.
*/
#define CESA_MAX_HASH_LEN 24
#define CESA_MAX_KEY_LEN 32
#define CESA_MAX_IV_LEN 16
#define CESA_MAX_HMAC_BLOCK_LEN 64
#define CESA_MAX_MKEY_LEN CESA_MAX_HMAC_BLOCK_LEN
#define CESA_MAX_PACKET_SIZE (CESA_SRAM_SIZE - CESA_DATA(0))
#define CESA_MAX_REQUEST_SIZE 65535
/* Locking macros */
#define CESA_LOCK(sc, what) mtx_lock(&(sc)->sc_ ## what ## _lock)
#define CESA_UNLOCK(sc, what) mtx_unlock(&(sc)->sc_ ## what ## _lock)
#define CESA_LOCK_ASSERT(sc, what) \
mtx_assert(&(sc)->sc_ ## what ## _lock, MA_OWNED)
/* Registers read/write macros */
#define CESA_READ(sc, reg) \
bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, (reg))
#define CESA_WRITE(sc, reg, val) \
bus_space_write_4((sc)->sc_bst, (sc)->sc_bsh, (reg), (val))
/* Generic allocator for objects */
#define CESA_GENERIC_ALLOC_LOCKED(sc, obj, pool) do { \
CESA_LOCK(sc, pool); \
\
if (STAILQ_EMPTY(&(sc)->sc_free_ ## pool)) \
obj = NULL; \
else { \
obj = STAILQ_FIRST(&(sc)->sc_free_ ## pool); \
STAILQ_REMOVE_HEAD(&(sc)->sc_free_ ## pool, \
obj ## _stq); \
} \
\
CESA_UNLOCK(sc, pool); \
} while (0)
#define CESA_GENERIC_FREE_LOCKED(sc, obj, pool) do { \
CESA_LOCK(sc, pool); \
STAILQ_INSERT_TAIL(&(sc)->sc_free_ ## pool, obj, \
obj ## _stq); \
CESA_UNLOCK(sc, pool); \
} while (0)
/* CESA SRAM offset calculation macros */
#define CESA_SA_DATA(member) \
(sizeof(struct cesa_sa_hdesc) + offsetof(struct cesa_sa_data, member))
#define CESA_DATA(offset) \
(sizeof(struct cesa_sa_hdesc) + sizeof(struct cesa_sa_data) + offset)
struct cesa_tdma_hdesc {
uint16_t cthd_byte_count;
uint16_t cthd_flags;
uint32_t cthd_src;
uint32_t cthd_dst;
uint32_t cthd_next;
};
struct cesa_sa_hdesc {
uint32_t cshd_config;
uint16_t cshd_enc_src;
uint16_t cshd_enc_dst;
uint32_t cshd_enc_dlen;
uint32_t cshd_enc_key;
uint16_t cshd_enc_iv;
uint16_t cshd_enc_iv_buf;
uint16_t cshd_mac_src;
uint16_t cshd_mac_total_dlen;
uint16_t cshd_mac_dst;
uint16_t cshd_mac_dlen;
uint16_t cshd_mac_iv_in;
uint16_t cshd_mac_iv_out;
};
struct cesa_sa_data {
uint8_t csd_key[CESA_MAX_KEY_LEN];
uint8_t csd_iv[CESA_MAX_IV_LEN];
uint8_t csd_hiv_in[CESA_MAX_HASH_LEN];
uint8_t csd_hiv_out[CESA_MAX_HASH_LEN];
uint8_t csd_hash[CESA_MAX_HASH_LEN];
};
struct cesa_dma_mem {
void *cdm_vaddr;
bus_addr_t cdm_paddr;
bus_dma_tag_t cdm_tag;
bus_dmamap_t cdm_map;
};
struct cesa_tdma_desc {
struct cesa_tdma_hdesc *ctd_cthd;
bus_addr_t ctd_cthd_paddr;
STAILQ_ENTRY(cesa_tdma_desc) ctd_stq;
};
struct cesa_sa_desc {
struct cesa_sa_hdesc *csd_cshd;
bus_addr_t csd_cshd_paddr;
STAILQ_ENTRY(cesa_sa_desc) csd_stq;
};
struct cesa_session {
uint32_t cs_sid;
uint32_t cs_config;
unsigned int cs_klen;
unsigned int cs_ivlen;
unsigned int cs_hlen;
unsigned int cs_mblen;
uint8_t cs_key[CESA_MAX_KEY_LEN];
uint8_t cs_aes_dkey[CESA_MAX_KEY_LEN];
uint8_t cs_hiv_in[CESA_MAX_HASH_LEN];
uint8_t cs_hiv_out[CESA_MAX_HASH_LEN];
STAILQ_ENTRY(cesa_session) cs_stq;
};
struct cesa_request {
struct cesa_sa_data *cr_csd;
bus_addr_t cr_csd_paddr;
struct cryptop *cr_crp;
struct cryptodesc *cr_enc;
struct cryptodesc *cr_mac;
struct cesa_session *cr_cs;
bus_dmamap_t cr_dmap;
int cr_dmap_loaded;
STAILQ_HEAD(, cesa_tdma_desc) cr_tdesc;
STAILQ_HEAD(, cesa_sa_desc) cr_sdesc;
STAILQ_ENTRY(cesa_request) cr_stq;
};
struct cesa_packet {
STAILQ_HEAD(, cesa_tdma_desc) cp_copyin;
STAILQ_HEAD(, cesa_tdma_desc) cp_copyout;
unsigned int cp_size;
unsigned int cp_offset;
};
struct cesa_softc {
device_t sc_dev;
int32_t sc_cid;
struct resource *sc_res[2];
void *sc_icookie;
bus_dma_tag_t sc_data_dtag;
bus_space_tag_t sc_bst;
bus_space_handle_t sc_bsh;
int sc_error;
int sc_tperr;
struct mtx sc_sc_lock;
int sc_blocked;
/* TDMA descriptors pool */
struct mtx sc_tdesc_lock;
struct cesa_tdma_desc sc_tdesc[CESA_TDMA_DESCRIPTORS];
struct cesa_dma_mem sc_tdesc_cdm;
STAILQ_HEAD(, cesa_tdma_desc) sc_free_tdesc;
/* SA descriptors pool */
struct mtx sc_sdesc_lock;
struct cesa_sa_desc sc_sdesc[CESA_SA_DESCRIPTORS];
struct cesa_dma_mem sc_sdesc_cdm;
STAILQ_HEAD(, cesa_sa_desc) sc_free_sdesc;
/* Requests pool */
struct mtx sc_requests_lock;
struct cesa_request sc_requests[CESA_REQUESTS];
struct cesa_dma_mem sc_requests_cdm;
STAILQ_HEAD(, cesa_request) sc_free_requests;
STAILQ_HEAD(, cesa_request) sc_ready_requests;
STAILQ_HEAD(, cesa_request) sc_queued_requests;
/* Sessions pool */
struct mtx sc_sessions_lock;
struct cesa_session sc_sessions[CESA_SESSIONS];
STAILQ_HEAD(, cesa_session) sc_free_sessions;
/* CESA SRAM Address */
bus_addr_t sc_sram_base;
};
struct cesa_chain_info {
struct cesa_softc *cci_sc;
struct cesa_request *cci_cr;
struct cryptodesc *cci_enc;
struct cryptodesc *cci_mac;
uint32_t cci_config;
int cci_error;
};
/* CESA descriptors flags definitions */
#define CESA_CTHD_OWNED (1 << 15)
#define CESA_CSHD_MAC (0 << 0)
#define CESA_CSHD_ENC (1 << 0)
#define CESA_CSHD_MAC_AND_ENC (2 << 0)
#define CESA_CSHD_ENC_AND_MAC (3 << 0)
#define CESA_CSHD_OP_MASK (3 << 0)
#define CESA_CSHD_MD5 (4 << 4)
#define CESA_CSHD_SHA1 (5 << 4)
#define CESA_CSHD_MD5_HMAC ((6 << 4) | (1 << 7))
#define CESA_CSHD_SHA1_HMAC ((7 << 4) | (1 << 7))
#define CESA_CSHD_DES (1 << 8)
#define CESA_CSHD_3DES (2 << 8)
#define CESA_CSHD_AES (3 << 8)
#define CESA_CSHD_DECRYPT (1 << 12)
#define CESA_CSHD_CBC (1 << 16)
#define CESA_CSHD_3DES_EDE (1 << 20)
#define CESA_CSH_AES_KLEN_128 (0 << 24)
#define CESA_CSH_AES_KLEN_192 (1 << 24)
#define CESA_CSH_AES_KLEN_256 (2 << 24)
#define CESA_CSH_AES_KLEN_MASK (3 << 24)
#define CESA_CSHD_FRAG_FIRST (1 << 30)
#define CESA_CSHD_FRAG_LAST (2 << 30)
#define CESA_CSHD_FRAG_MIDDLE (3 << 30)
/* CESA registers definitions */
#define CESA_ICR 0xDE20
#define CESA_ICR_ACCTDMA (1 << 7)
#define CESA_ICR_TPERR (1 << 12)
#define CESA_ICM 0xDE24
#define CESA_ICM_ACCTDMA CESA_ICR_ACCTDMA
#define CESA_ICM_TPERR CESA_ICR_TPERR
/* CESA TDMA registers definitions */
#define CESA_TDMA_ND 0x0830
#define CESA_TDMA_CR 0x0840
#define CESA_TDMA_CR_DBL128 (4 << 0)
#define CESA_TDMA_CR_ORDEN (1 << 4)
#define CESA_TDMA_CR_SBL128 (4 << 6)
#define CESA_TDMA_CR_NBS (1 << 11)
#define CESA_TDMA_CR_ENABLE (1 << 12)
#define CESA_TDMA_CR_FETCHND (1 << 13)
#define CESA_TDMA_CR_ACTIVE (1 << 14)
#define CESA_TDMA_ECR 0x08C8
#define CESA_TDMA_ECR_MISS (1 << 0)
#define CESA_TDMA_ECR_DOUBLE_HIT (1 << 1)
#define CESA_TDMA_ECR_BOTH_HIT (1 << 2)
#define CESA_TDMA_ECR_DATA_ERROR (1 << 3)
#define CESA_TDMA_EMR 0x08CC
#define CESA_TDMA_EMR_MISS CESA_TDMA_ECR_MISS
#define CESA_TDMA_EMR_DOUBLE_HIT CESA_TDMA_ECR_DOUBLE_HIT
#define CESA_TDMA_EMR_BOTH_HIT CESA_TDMA_ECR_BOTH_HIT
#define CESA_TDMA_EMR_DATA_ERROR CESA_TDMA_ECR_DATA_ERROR
/* CESA SA registers definitions */
#define CESA_SA_CMD 0xDE00
#define CESA_SA_CMD_ACTVATE (1 << 0)
#define CESA_SA_DPR 0xDE04
#define CESA_SA_CR 0xDE08
#define CESA_SA_CR_WAIT_FOR_TDMA (1 << 7)
#define CESA_SA_CR_ACTIVATE_TDMA (1 << 9)
#define CESA_SA_CR_MULTI_MODE (1 << 11)
#define CESA_SA_SR 0xDE0C
#define CESA_SA_SR_ACTIVE (1 << 0)
#endif
|