]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - sys/dev/cesa/cesa.h
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / sys / dev / cesa / cesa.h
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$
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_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
129 struct 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
137 struct 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
153 struct 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
161 struct 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
168 struct 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
175 struct 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
182 struct 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
197 struct 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
213 struct 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
220 struct 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
263 struct 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 TDMA address decoding registers */
337 #define MV_WIN_CESA_CTRL(n)             (0x8 * (n) + 0xA04)
338 #define MV_WIN_CESA_BASE(n)             (0x8 * (n) + 0xA00)
339 #define MV_WIN_CESA_MAX                 4
340
341 /* CESA SA registers definitions */
342 #define CESA_SA_CMD                     0xDE00
343 #define CESA_SA_CMD_ACTVATE             (1 << 0)
344
345 #define CESA_SA_DPR                     0xDE04
346
347 #define CESA_SA_CR                      0xDE08
348 #define CESA_SA_CR_WAIT_FOR_TDMA        (1 << 7)
349 #define CESA_SA_CR_ACTIVATE_TDMA        (1 << 9)
350 #define CESA_SA_CR_MULTI_MODE           (1 << 11)
351
352 #define CESA_SA_SR                      0xDE0C
353 #define CESA_SA_SR_ACTIVE               (1 << 0)
354
355 #endif