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_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 supports MD5, SHA1 and SHA-256 this equals to 32 bytes. 78 */ 79#define CESA_MAX_HASH_LEN 32 80#define CESA_MAX_KEY_LEN 32 81#define CESA_MAX_IV_LEN 16 82#define CESA_MAX_HMAC_BLOCK_LEN 64 83#define CESA_MAX_MKEY_LEN CESA_MAX_HMAC_BLOCK_LEN 84#define CESA_MAX_PACKET_SIZE (CESA_SRAM_SIZE - CESA_DATA(0)) 85#define CESA_MAX_REQUEST_SIZE 65535 86 87/* Locking macros */ 88#define CESA_LOCK(sc, what) mtx_lock(&(sc)->sc_ ## what ## _lock) 89#define CESA_UNLOCK(sc, what) mtx_unlock(&(sc)->sc_ ## what ## _lock) 90#define CESA_LOCK_ASSERT(sc, what) \ 91 mtx_assert(&(sc)->sc_ ## what ## _lock, MA_OWNED) 92 93/* Registers read/write macros */ 94#define CESA_REG_READ(sc, reg) \ 95 bus_read_4((sc)->sc_res[RES_CESA_REGS], (reg)) 96#define CESA_REG_WRITE(sc, reg, val) \ 97 bus_write_4((sc)->sc_res[RES_CESA_REGS], (reg), (val)) 98 99#define CESA_TDMA_READ(sc, reg) \ 100 bus_read_4((sc)->sc_res[RES_TDMA_REGS], (reg)) 101#define CESA_TDMA_WRITE(sc, reg, val) \ 102 bus_write_4((sc)->sc_res[RES_TDMA_REGS], (reg), (val)) 103 104/* Generic allocator for objects */ 105#define CESA_GENERIC_ALLOC_LOCKED(sc, obj, pool) do { \ 106 CESA_LOCK(sc, pool); \ 107 \ 108 if (STAILQ_EMPTY(&(sc)->sc_free_ ## pool)) \ 109 obj = NULL; \ 110 else { \ 111 obj = STAILQ_FIRST(&(sc)->sc_free_ ## pool); \ 112 STAILQ_REMOVE_HEAD(&(sc)->sc_free_ ## pool, \ 113 obj ## _stq); \ 114 } \ 115 \ 116 CESA_UNLOCK(sc, pool); \ 117} while (0) 118 119#define CESA_GENERIC_FREE_LOCKED(sc, obj, pool) do { \ 120 CESA_LOCK(sc, pool); \ 121 STAILQ_INSERT_TAIL(&(sc)->sc_free_ ## pool, obj, \ 122 obj ## _stq); \ 123 CESA_UNLOCK(sc, pool); \ 124} while (0) 125 126/* CESA SRAM offset calculation macros */ 127#define CESA_SA_DATA(member) \ 128 (sizeof(struct cesa_sa_hdesc) + offsetof(struct cesa_sa_data, member)) 129#define CESA_DATA(offset) \ 130 (sizeof(struct cesa_sa_hdesc) + sizeof(struct cesa_sa_data) + offset) 131 132/* CESA memory and IRQ resources */ 133enum cesa_res_type { 134 RES_TDMA_REGS, 135 RES_CESA_REGS, 136 RES_CESA_IRQ, 137 RES_CESA_NUM 138}; 139 140struct cesa_tdma_hdesc { 141 uint16_t cthd_byte_count; 142 uint16_t cthd_flags; 143 uint32_t cthd_src; 144 uint32_t cthd_dst; 145 uint32_t cthd_next; 146}; 147 148struct cesa_sa_hdesc { 149 uint32_t cshd_config; 150 uint16_t cshd_enc_src; 151 uint16_t cshd_enc_dst; 152 uint32_t cshd_enc_dlen; 153 uint32_t cshd_enc_key; 154 uint16_t cshd_enc_iv; 155 uint16_t cshd_enc_iv_buf; 156 uint16_t cshd_mac_src; 157 uint16_t cshd_mac_total_dlen; 158 uint16_t cshd_mac_dst; 159 uint16_t cshd_mac_dlen; 160 uint16_t cshd_mac_iv_in; 161 uint16_t cshd_mac_iv_out; 162}; 163 164struct cesa_sa_data { 165 uint8_t csd_key[CESA_MAX_KEY_LEN]; 166 uint8_t csd_iv[CESA_MAX_IV_LEN]; 167 uint8_t csd_hiv_in[CESA_MAX_HASH_LEN]; 168 uint8_t csd_hiv_out[CESA_MAX_HASH_LEN]; 169 uint8_t csd_hash[CESA_MAX_HASH_LEN]; 170}; 171 172struct cesa_dma_mem { 173 void *cdm_vaddr; 174 bus_addr_t cdm_paddr; 175 bus_dma_tag_t cdm_tag; 176 bus_dmamap_t cdm_map; 177}; 178 179struct cesa_tdma_desc { 180 struct cesa_tdma_hdesc *ctd_cthd; 181 bus_addr_t ctd_cthd_paddr; 182 183 STAILQ_ENTRY(cesa_tdma_desc) ctd_stq; 184}; 185 186struct cesa_sa_desc { 187 struct cesa_sa_hdesc *csd_cshd; 188 bus_addr_t csd_cshd_paddr; 189 190 STAILQ_ENTRY(cesa_sa_desc) csd_stq; 191}; 192 193struct cesa_session { 194 uint32_t cs_sid; 195 uint32_t cs_config; 196 unsigned int cs_klen; 197 unsigned int cs_ivlen; 198 unsigned int cs_hlen; 199 unsigned int cs_mblen; 200 uint8_t cs_key[CESA_MAX_KEY_LEN]; 201 uint8_t cs_aes_dkey[CESA_MAX_KEY_LEN]; 202 uint8_t cs_hiv_in[CESA_MAX_HASH_LEN]; 203 uint8_t cs_hiv_out[CESA_MAX_HASH_LEN]; 204 205 STAILQ_ENTRY(cesa_session) cs_stq; 206}; 207 208struct cesa_request { 209 struct cesa_sa_data *cr_csd; 210 bus_addr_t cr_csd_paddr; 211 struct cryptop *cr_crp; 212 struct cryptodesc *cr_enc; 213 struct cryptodesc *cr_mac; 214 struct cesa_session *cr_cs; 215 bus_dmamap_t cr_dmap; 216 int cr_dmap_loaded; 217 218 STAILQ_HEAD(, cesa_tdma_desc) cr_tdesc; 219 STAILQ_HEAD(, cesa_sa_desc) cr_sdesc; 220 221 STAILQ_ENTRY(cesa_request) cr_stq; 222}; 223 224struct cesa_packet { 225 STAILQ_HEAD(, cesa_tdma_desc) cp_copyin; 226 STAILQ_HEAD(, cesa_tdma_desc) cp_copyout; 227 unsigned int cp_size; 228 unsigned int cp_offset; 229}; 230 231struct cesa_softc { 232 device_t sc_dev; 233 int32_t sc_cid; 234 struct resource *sc_res[RES_CESA_NUM]; 235 void *sc_icookie; 236 bus_dma_tag_t sc_data_dtag; 237 int sc_error; 238 int sc_tperr; 239 240 struct mtx sc_sc_lock; 241 int sc_blocked; 242 243 /* TDMA descriptors pool */ 244 struct mtx sc_tdesc_lock; 245 struct cesa_tdma_desc sc_tdesc[CESA_TDMA_DESCRIPTORS]; 246 struct cesa_dma_mem sc_tdesc_cdm; 247 STAILQ_HEAD(, cesa_tdma_desc) sc_free_tdesc; 248 249 /* SA descriptors pool */ 250 struct mtx sc_sdesc_lock; 251 struct cesa_sa_desc sc_sdesc[CESA_SA_DESCRIPTORS]; 252 struct cesa_dma_mem sc_sdesc_cdm; 253 STAILQ_HEAD(, cesa_sa_desc) sc_free_sdesc; 254 255 /* Requests pool */ 256 struct mtx sc_requests_lock; 257 struct cesa_request sc_requests[CESA_REQUESTS]; 258 struct cesa_dma_mem sc_requests_cdm; 259 STAILQ_HEAD(, cesa_request) sc_free_requests; 260 STAILQ_HEAD(, cesa_request) sc_ready_requests; 261 STAILQ_HEAD(, cesa_request) sc_queued_requests; 262 263 /* Sessions pool */ 264 struct mtx sc_sessions_lock; 265 struct cesa_session sc_sessions[CESA_SESSIONS]; 266 STAILQ_HEAD(, cesa_session) sc_free_sessions; 267 268 /* CESA SRAM Address */ 269 bus_addr_t sc_sram_base_pa; 270 vm_offset_t sc_sram_base_va; 271 bus_size_t sc_sram_size; 272}; 273 274struct cesa_chain_info { 275 struct cesa_softc *cci_sc; 276 struct cesa_request *cci_cr; 277 struct cryptodesc *cci_enc; 278 struct cryptodesc *cci_mac; 279 uint32_t cci_config; 280 int cci_error; 281}; 282 283/* CESA descriptors flags definitions */ 284#define CESA_CTHD_OWNED (1 << 15) 285 286#define CESA_CSHD_MAC (0 << 0) 287#define CESA_CSHD_ENC (1 << 0) 288#define CESA_CSHD_MAC_AND_ENC (2 << 0) 289#define CESA_CSHD_ENC_AND_MAC (3 << 0) 290#define CESA_CSHD_OP_MASK (3 << 0) 291 292#define CESA_CSHD_MD5 (4 << 4) 293#define CESA_CSHD_SHA1 (5 << 4) 294#define CESA_CSHD_SHA2_256 (1 << 4) 295#define CESA_CSHD_MD5_HMAC (6 << 4) 296#define CESA_CSHD_SHA1_HMAC (7 << 4) 297#define CESA_CSHD_SHA2_256_HMAC (3 << 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#if defined (SOC_MV_ARMADA38X) 340#define CESA_TDMA_NUM_OUTSTAND (2 << 16) 341#endif 342 343#define CESA_TDMA_ECR 0x08C8 344#define CESA_TDMA_ECR_MISS (1 << 0) 345#define CESA_TDMA_ECR_DOUBLE_HIT (1 << 1) 346#define CESA_TDMA_ECR_BOTH_HIT (1 << 2) 347#define CESA_TDMA_ECR_DATA_ERROR (1 << 3) 348 349#define CESA_TDMA_EMR 0x08CC 350#define CESA_TDMA_EMR_MISS CESA_TDMA_ECR_MISS 351#define CESA_TDMA_EMR_DOUBLE_HIT CESA_TDMA_ECR_DOUBLE_HIT 352#define CESA_TDMA_EMR_BOTH_HIT CESA_TDMA_ECR_BOTH_HIT 353#define CESA_TDMA_EMR_DATA_ERROR CESA_TDMA_ECR_DATA_ERROR 354 355/* CESA TDMA address decoding registers */ 356#define MV_WIN_CESA_CTRL(n) (0x8 * (n) + 0xA04) 357#define MV_WIN_CESA_BASE(n) (0x8 * (n) + 0xA00) 358#define MV_WIN_CESA_MAX 4 359 360/* CESA SA registers definitions */ 361#define CESA_SA_CMD 0x0E00 362#define CESA_SA_CMD_ACTVATE (1 << 0) 363 364#if defined (SOC_MV_ARMADA38X) 365#define CESA_SA_CMD_SHA2 (1 << 31) 366#endif 367 368#define CESA_SA_DPR 0x0E04 369 370#define CESA_SA_CR 0x0E08 371#define CESA_SA_CR_WAIT_FOR_TDMA (1 << 7) 372#define CESA_SA_CR_ACTIVATE_TDMA (1 << 9) 373#define CESA_SA_CR_MULTI_MODE (1 << 11) 374 375#define CESA_SA_SR 0x0E0C 376#define CESA_SA_SR_ACTIVE (1 << 0) 377 378#endif 379