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 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