cesa.h revision 301223
1227730Sraj/*- 2227730Sraj * Copyright (C) 2009-2011 Semihalf. 3227730Sraj * All rights reserved. 4227730Sraj * 5227730Sraj * Redistribution and use in source and binary forms, with or without 6227730Sraj * modification, are permitted provided that the following conditions 7227730Sraj * are met: 8227730Sraj * 1. Redistributions of source code must retain the above copyright 9227730Sraj * notice, this list of conditions and the following disclaimer. 10227730Sraj * 2. Redistributions in binary form must reproduce the above copyright 11227730Sraj * notice, this list of conditions and the following disclaimer in the 12227730Sraj * documentation and/or other materials provided with the distribution. 13227730Sraj * 14227730Sraj * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15227730Sraj * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16227730Sraj * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17227730Sraj * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18227730Sraj * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19227730Sraj * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20227730Sraj * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21227730Sraj * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22227730Sraj * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23227730Sraj * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24227730Sraj * SUCH DAMAGE. 25227730Sraj * 26227730Sraj * $FreeBSD: head/sys/dev/cesa/cesa.h 301223 2016-06-02 18:37:50Z zbb $ 27227730Sraj */ 28227730Sraj 29227730Sraj#ifndef _DEV_CESA_H_ 30227730Sraj#define _DEV_CESA_H_ 31227730Sraj 32227730Sraj/* Maximum number of allocated sessions */ 33227730Sraj#define CESA_SESSIONS 64 34227730Sraj 35227730Sraj/* Maximum number of queued requests */ 36227730Sraj#define CESA_REQUESTS 256 37227730Sraj 38227730Sraj/* 39227730Sraj * CESA is able to process data only in CESA SRAM, which is quite small (2 kB). 40227730Sraj * We have to fit a packet there, which contains SA descriptor, keys, IV 41227730Sraj * and data to be processed. Every request must be converted into chain of 42227730Sraj * packets and each packet can hold about 1.75 kB of data. 43227730Sraj * 44227730Sraj * To process each packet we need at least 1 SA descriptor and at least 4 TDMA 45227730Sraj * descriptors. However there are cases when we use 2 SA and 8 TDMA descriptors 46227730Sraj * per packet. Number of used TDMA descriptors can increase beyond given values 47227730Sraj * if data in the request is fragmented in physical memory. 48227730Sraj * 49227730Sraj * The driver uses preallocated SA and TDMA descriptors pools to get best 50227730Sraj * performace. Size of these pools should match expected request size. Example: 51227730Sraj * 52227730Sraj * Expected average request size: 1.5 kB (Ethernet MTU) 53227730Sraj * Packets per average request: (1.5 kB / 1.75 kB) = 1 54227730Sraj * SA decriptors per average request (worst case): 1 * 2 = 2 55227730Sraj * TDMA desctiptors per average request (worst case): 1 * 8 = 8 56227730Sraj * 57227730Sraj * More TDMA descriptors should be allocated, if data fragmentation is expected 58227730Sraj * (for example while processing mbufs larger than MCLBYTES). The driver may use 59227730Sraj * 2 additional TDMA descriptors per each discontinuity in the physical data 60227730Sraj * layout. 61227730Sraj */ 62227730Sraj 63227730Sraj/* Values below are optimized for requests containing about 1.5 kB of data */ 64227730Sraj#define CESA_SA_DESC_PER_REQ 2 65227730Sraj#define CESA_TDMA_DESC_PER_REQ 8 66227730Sraj 67227730Sraj#define CESA_SA_DESCRIPTORS (CESA_SA_DESC_PER_REQ * CESA_REQUESTS) 68227730Sraj#define CESA_TDMA_DESCRIPTORS (CESA_TDMA_DESC_PER_REQ * CESA_REQUESTS) 69227730Sraj 70227730Sraj/* Useful constants */ 71301223Szbb#define CESA_HMAC_TRUNC_LEN 12 72227730Sraj#define CESA_MAX_FRAGMENTS 64 73227730Sraj#define CESA_SRAM_SIZE 2048 74227730Sraj 75227730Sraj/* 76227730Sraj * CESA_MAX_HASH_LEN is maximum length of hash generated by CESA. 77227730Sraj * As CESA suports only MD5 and SHA1 this equals to 20 bytes. 78227730Sraj * However we increase the value to 24 bytes to meet alignment 79227730Sraj * requirements in cesa_sa_data structure. 80227730Sraj */ 81227730Sraj#define CESA_MAX_HASH_LEN 24 82227730Sraj#define CESA_MAX_KEY_LEN 32 83227730Sraj#define CESA_MAX_IV_LEN 16 84227730Sraj#define CESA_MAX_HMAC_BLOCK_LEN 64 85227730Sraj#define CESA_MAX_MKEY_LEN CESA_MAX_HMAC_BLOCK_LEN 86227730Sraj#define CESA_MAX_PACKET_SIZE (CESA_SRAM_SIZE - CESA_DATA(0)) 87227730Sraj#define CESA_MAX_REQUEST_SIZE 65535 88227730Sraj 89227730Sraj/* Locking macros */ 90227730Sraj#define CESA_LOCK(sc, what) mtx_lock(&(sc)->sc_ ## what ## _lock) 91227730Sraj#define CESA_UNLOCK(sc, what) mtx_unlock(&(sc)->sc_ ## what ## _lock) 92227730Sraj#define CESA_LOCK_ASSERT(sc, what) \ 93227730Sraj mtx_assert(&(sc)->sc_ ## what ## _lock, MA_OWNED) 94227730Sraj 95227730Sraj/* Registers read/write macros */ 96301222Szbb#define CESA_REG_READ(sc, reg) \ 97301222Szbb bus_read_4((sc)->sc_res[RES_CESA_REGS], (reg)) 98301222Szbb#define CESA_REG_WRITE(sc, reg, val) \ 99301222Szbb bus_write_4((sc)->sc_res[RES_CESA_REGS], (reg), (val)) 100227730Sraj 101301222Szbb#define CESA_TDMA_READ(sc, reg) \ 102301222Szbb bus_read_4((sc)->sc_res[RES_TDMA_REGS], (reg)) 103301222Szbb#define CESA_TDMA_WRITE(sc, reg, val) \ 104301222Szbb bus_write_4((sc)->sc_res[RES_TDMA_REGS], (reg), (val)) 105301222Szbb 106227730Sraj/* Generic allocator for objects */ 107227730Sraj#define CESA_GENERIC_ALLOC_LOCKED(sc, obj, pool) do { \ 108227730Sraj CESA_LOCK(sc, pool); \ 109227730Sraj \ 110227730Sraj if (STAILQ_EMPTY(&(sc)->sc_free_ ## pool)) \ 111227730Sraj obj = NULL; \ 112227730Sraj else { \ 113227730Sraj obj = STAILQ_FIRST(&(sc)->sc_free_ ## pool); \ 114227730Sraj STAILQ_REMOVE_HEAD(&(sc)->sc_free_ ## pool, \ 115227730Sraj obj ## _stq); \ 116227730Sraj } \ 117227730Sraj \ 118227730Sraj CESA_UNLOCK(sc, pool); \ 119227730Sraj} while (0) 120227730Sraj 121227730Sraj#define CESA_GENERIC_FREE_LOCKED(sc, obj, pool) do { \ 122227730Sraj CESA_LOCK(sc, pool); \ 123227730Sraj STAILQ_INSERT_TAIL(&(sc)->sc_free_ ## pool, obj, \ 124227730Sraj obj ## _stq); \ 125227730Sraj CESA_UNLOCK(sc, pool); \ 126227730Sraj} while (0) 127227730Sraj 128227730Sraj/* CESA SRAM offset calculation macros */ 129227730Sraj#define CESA_SA_DATA(member) \ 130227730Sraj (sizeof(struct cesa_sa_hdesc) + offsetof(struct cesa_sa_data, member)) 131227730Sraj#define CESA_DATA(offset) \ 132227730Sraj (sizeof(struct cesa_sa_hdesc) + sizeof(struct cesa_sa_data) + offset) 133227730Sraj 134301222Szbb/* CESA memory and IRQ resources */ 135301222Szbbenum cesa_res_type { 136301222Szbb RES_TDMA_REGS, 137301222Szbb RES_CESA_REGS, 138301222Szbb RES_CESA_IRQ, 139301222Szbb RES_CESA_NUM 140301222Szbb}; 141301222Szbb 142227730Srajstruct cesa_tdma_hdesc { 143227730Sraj uint16_t cthd_byte_count; 144227730Sraj uint16_t cthd_flags; 145227730Sraj uint32_t cthd_src; 146227730Sraj uint32_t cthd_dst; 147227730Sraj uint32_t cthd_next; 148227730Sraj}; 149227730Sraj 150227730Srajstruct cesa_sa_hdesc { 151227730Sraj uint32_t cshd_config; 152227730Sraj uint16_t cshd_enc_src; 153227730Sraj uint16_t cshd_enc_dst; 154227730Sraj uint32_t cshd_enc_dlen; 155227730Sraj uint32_t cshd_enc_key; 156227730Sraj uint16_t cshd_enc_iv; 157227730Sraj uint16_t cshd_enc_iv_buf; 158227730Sraj uint16_t cshd_mac_src; 159227730Sraj uint16_t cshd_mac_total_dlen; 160227730Sraj uint16_t cshd_mac_dst; 161227730Sraj uint16_t cshd_mac_dlen; 162227730Sraj uint16_t cshd_mac_iv_in; 163227730Sraj uint16_t cshd_mac_iv_out; 164227730Sraj}; 165227730Sraj 166227730Srajstruct cesa_sa_data { 167227730Sraj uint8_t csd_key[CESA_MAX_KEY_LEN]; 168227730Sraj uint8_t csd_iv[CESA_MAX_IV_LEN]; 169227730Sraj uint8_t csd_hiv_in[CESA_MAX_HASH_LEN]; 170227730Sraj uint8_t csd_hiv_out[CESA_MAX_HASH_LEN]; 171227730Sraj uint8_t csd_hash[CESA_MAX_HASH_LEN]; 172227730Sraj}; 173227730Sraj 174227730Srajstruct cesa_dma_mem { 175227730Sraj void *cdm_vaddr; 176227730Sraj bus_addr_t cdm_paddr; 177227730Sraj bus_dma_tag_t cdm_tag; 178227730Sraj bus_dmamap_t cdm_map; 179227730Sraj}; 180227730Sraj 181227730Srajstruct cesa_tdma_desc { 182227730Sraj struct cesa_tdma_hdesc *ctd_cthd; 183227730Sraj bus_addr_t ctd_cthd_paddr; 184227730Sraj 185227730Sraj STAILQ_ENTRY(cesa_tdma_desc) ctd_stq; 186227730Sraj}; 187227730Sraj 188227730Srajstruct cesa_sa_desc { 189227730Sraj struct cesa_sa_hdesc *csd_cshd; 190227730Sraj bus_addr_t csd_cshd_paddr; 191227730Sraj 192227730Sraj STAILQ_ENTRY(cesa_sa_desc) csd_stq; 193227730Sraj}; 194227730Sraj 195227730Srajstruct cesa_session { 196227730Sraj uint32_t cs_sid; 197227730Sraj uint32_t cs_config; 198227730Sraj unsigned int cs_klen; 199227730Sraj unsigned int cs_ivlen; 200227730Sraj unsigned int cs_hlen; 201227730Sraj unsigned int cs_mblen; 202227730Sraj uint8_t cs_key[CESA_MAX_KEY_LEN]; 203227730Sraj uint8_t cs_aes_dkey[CESA_MAX_KEY_LEN]; 204227730Sraj uint8_t cs_hiv_in[CESA_MAX_HASH_LEN]; 205227730Sraj uint8_t cs_hiv_out[CESA_MAX_HASH_LEN]; 206227730Sraj 207227730Sraj STAILQ_ENTRY(cesa_session) cs_stq; 208227730Sraj}; 209227730Sraj 210227730Srajstruct cesa_request { 211227730Sraj struct cesa_sa_data *cr_csd; 212227730Sraj bus_addr_t cr_csd_paddr; 213227730Sraj struct cryptop *cr_crp; 214227730Sraj struct cryptodesc *cr_enc; 215227730Sraj struct cryptodesc *cr_mac; 216227730Sraj struct cesa_session *cr_cs; 217227730Sraj bus_dmamap_t cr_dmap; 218227730Sraj int cr_dmap_loaded; 219227730Sraj 220227730Sraj STAILQ_HEAD(, cesa_tdma_desc) cr_tdesc; 221227730Sraj STAILQ_HEAD(, cesa_sa_desc) cr_sdesc; 222227730Sraj 223227730Sraj STAILQ_ENTRY(cesa_request) cr_stq; 224227730Sraj}; 225227730Sraj 226227730Srajstruct cesa_packet { 227227730Sraj STAILQ_HEAD(, cesa_tdma_desc) cp_copyin; 228227730Sraj STAILQ_HEAD(, cesa_tdma_desc) cp_copyout; 229227730Sraj unsigned int cp_size; 230227730Sraj unsigned int cp_offset; 231227730Sraj}; 232227730Sraj 233227730Srajstruct cesa_softc { 234227730Sraj device_t sc_dev; 235227730Sraj int32_t sc_cid; 236301222Szbb struct resource *sc_res[RES_CESA_NUM]; 237227730Sraj void *sc_icookie; 238227730Sraj bus_dma_tag_t sc_data_dtag; 239227730Sraj int sc_error; 240227730Sraj int sc_tperr; 241227730Sraj 242227730Sraj struct mtx sc_sc_lock; 243227730Sraj int sc_blocked; 244227730Sraj 245227730Sraj /* TDMA descriptors pool */ 246227730Sraj struct mtx sc_tdesc_lock; 247227730Sraj struct cesa_tdma_desc sc_tdesc[CESA_TDMA_DESCRIPTORS]; 248227730Sraj struct cesa_dma_mem sc_tdesc_cdm; 249227730Sraj STAILQ_HEAD(, cesa_tdma_desc) sc_free_tdesc; 250227730Sraj 251227730Sraj /* SA descriptors pool */ 252227730Sraj struct mtx sc_sdesc_lock; 253227730Sraj struct cesa_sa_desc sc_sdesc[CESA_SA_DESCRIPTORS]; 254227730Sraj struct cesa_dma_mem sc_sdesc_cdm; 255227730Sraj STAILQ_HEAD(, cesa_sa_desc) sc_free_sdesc; 256227730Sraj 257227730Sraj /* Requests pool */ 258227730Sraj struct mtx sc_requests_lock; 259227730Sraj struct cesa_request sc_requests[CESA_REQUESTS]; 260227730Sraj struct cesa_dma_mem sc_requests_cdm; 261227730Sraj STAILQ_HEAD(, cesa_request) sc_free_requests; 262227730Sraj STAILQ_HEAD(, cesa_request) sc_ready_requests; 263227730Sraj STAILQ_HEAD(, cesa_request) sc_queued_requests; 264227730Sraj 265227730Sraj /* Sessions pool */ 266227730Sraj struct mtx sc_sessions_lock; 267227730Sraj struct cesa_session sc_sessions[CESA_SESSIONS]; 268227730Sraj STAILQ_HEAD(, cesa_session) sc_free_sessions; 269227730Sraj 270227730Sraj /* CESA SRAM Address */ 271301220Szbb bus_addr_t sc_sram_base_pa; 272301220Szbb bus_space_handle_t sc_sram_base_va; 273301220Szbb bus_size_t sc_sram_size; 274227730Sraj}; 275227730Sraj 276227730Srajstruct cesa_chain_info { 277227730Sraj struct cesa_softc *cci_sc; 278227730Sraj struct cesa_request *cci_cr; 279227730Sraj struct cryptodesc *cci_enc; 280227730Sraj struct cryptodesc *cci_mac; 281227730Sraj uint32_t cci_config; 282227730Sraj int cci_error; 283227730Sraj}; 284227730Sraj 285227730Sraj/* CESA descriptors flags definitions */ 286227730Sraj#define CESA_CTHD_OWNED (1 << 15) 287227730Sraj 288227730Sraj#define CESA_CSHD_MAC (0 << 0) 289227730Sraj#define CESA_CSHD_ENC (1 << 0) 290227730Sraj#define CESA_CSHD_MAC_AND_ENC (2 << 0) 291227730Sraj#define CESA_CSHD_ENC_AND_MAC (3 << 0) 292227730Sraj#define CESA_CSHD_OP_MASK (3 << 0) 293227730Sraj 294227730Sraj#define CESA_CSHD_MD5 (4 << 4) 295227730Sraj#define CESA_CSHD_SHA1 (5 << 4) 296301223Szbb#define CESA_CSHD_MD5_HMAC (6 << 4) 297301223Szbb#define CESA_CSHD_SHA1_HMAC (7 << 4) 298227730Sraj 299301223Szbb#define CESA_CSHD_96_BIT_HMAC (1 << 7) 300301223Szbb 301227730Sraj#define CESA_CSHD_DES (1 << 8) 302227730Sraj#define CESA_CSHD_3DES (2 << 8) 303227730Sraj#define CESA_CSHD_AES (3 << 8) 304227730Sraj 305227730Sraj#define CESA_CSHD_DECRYPT (1 << 12) 306227730Sraj#define CESA_CSHD_CBC (1 << 16) 307227730Sraj#define CESA_CSHD_3DES_EDE (1 << 20) 308227730Sraj 309227730Sraj#define CESA_CSH_AES_KLEN_128 (0 << 24) 310227730Sraj#define CESA_CSH_AES_KLEN_192 (1 << 24) 311227730Sraj#define CESA_CSH_AES_KLEN_256 (2 << 24) 312227730Sraj#define CESA_CSH_AES_KLEN_MASK (3 << 24) 313227730Sraj 314227730Sraj#define CESA_CSHD_FRAG_FIRST (1 << 30) 315258779Seadler#define CESA_CSHD_FRAG_LAST (2U << 30) 316258779Seadler#define CESA_CSHD_FRAG_MIDDLE (3U << 30) 317227730Sraj 318227730Sraj/* CESA registers definitions */ 319301222Szbb#define CESA_ICR 0x0E20 320227730Sraj#define CESA_ICR_ACCTDMA (1 << 7) 321227730Sraj#define CESA_ICR_TPERR (1 << 12) 322227730Sraj 323301222Szbb#define CESA_ICM 0x0E24 324227730Sraj#define CESA_ICM_ACCTDMA CESA_ICR_ACCTDMA 325227730Sraj#define CESA_ICM_TPERR CESA_ICR_TPERR 326227730Sraj 327227730Sraj/* CESA TDMA registers definitions */ 328227730Sraj#define CESA_TDMA_ND 0x0830 329227730Sraj 330227730Sraj#define CESA_TDMA_CR 0x0840 331227730Sraj#define CESA_TDMA_CR_DBL128 (4 << 0) 332227730Sraj#define CESA_TDMA_CR_ORDEN (1 << 4) 333227730Sraj#define CESA_TDMA_CR_SBL128 (4 << 6) 334227730Sraj#define CESA_TDMA_CR_NBS (1 << 11) 335227730Sraj#define CESA_TDMA_CR_ENABLE (1 << 12) 336227730Sraj#define CESA_TDMA_CR_FETCHND (1 << 13) 337227730Sraj#define CESA_TDMA_CR_ACTIVE (1 << 14) 338227730Sraj 339227730Sraj#define CESA_TDMA_ECR 0x08C8 340227730Sraj#define CESA_TDMA_ECR_MISS (1 << 0) 341227730Sraj#define CESA_TDMA_ECR_DOUBLE_HIT (1 << 1) 342227730Sraj#define CESA_TDMA_ECR_BOTH_HIT (1 << 2) 343227730Sraj#define CESA_TDMA_ECR_DATA_ERROR (1 << 3) 344227730Sraj 345227730Sraj#define CESA_TDMA_EMR 0x08CC 346227730Sraj#define CESA_TDMA_EMR_MISS CESA_TDMA_ECR_MISS 347227730Sraj#define CESA_TDMA_EMR_DOUBLE_HIT CESA_TDMA_ECR_DOUBLE_HIT 348227730Sraj#define CESA_TDMA_EMR_BOTH_HIT CESA_TDMA_ECR_BOTH_HIT 349227730Sraj#define CESA_TDMA_EMR_DATA_ERROR CESA_TDMA_ECR_DATA_ERROR 350227730Sraj 351250291Sgber/* CESA TDMA address decoding registers */ 352250291Sgber#define MV_WIN_CESA_CTRL(n) (0x8 * (n) + 0xA04) 353250291Sgber#define MV_WIN_CESA_BASE(n) (0x8 * (n) + 0xA00) 354250291Sgber#define MV_WIN_CESA_MAX 4 355250291Sgber 356227730Sraj/* CESA SA registers definitions */ 357301222Szbb#define CESA_SA_CMD 0x0E00 358227730Sraj#define CESA_SA_CMD_ACTVATE (1 << 0) 359227730Sraj 360301222Szbb#define CESA_SA_DPR 0x0E04 361227730Sraj 362301222Szbb#define CESA_SA_CR 0x0E08 363227730Sraj#define CESA_SA_CR_WAIT_FOR_TDMA (1 << 7) 364227730Sraj#define CESA_SA_CR_ACTIVATE_TDMA (1 << 9) 365227730Sraj#define CESA_SA_CR_MULTI_MODE (1 << 11) 366227730Sraj 367301222Szbb#define CESA_SA_SR 0x0E0C 368227730Sraj#define CESA_SA_SR_ACTIVE (1 << 0) 369227730Sraj 370227730Sraj#endif 371