diff options
author | raj <raj@FreeBSD.org> | 2011-11-19 16:30:06 +0000 |
---|---|---|
committer | raj <raj@FreeBSD.org> | 2011-11-19 16:30:06 +0000 |
commit | 424b3d8bf270e902ce6324d6ea0887610d442cbf (patch) | |
tree | 4bd8db2ca9ec69154f763cf7ba25fbfc6d8614ac /sys/dev/cesa/cesa.h | |
parent | b40f4ea97574a0cd2d06fa6bcc1afece17f10651 (diff) | |
download | FreeBSD-src-424b3d8bf270e902ce6324d6ea0887610d442cbf.zip FreeBSD-src-424b3d8bf270e902ce6324d6ea0887610d442cbf.tar.gz |
Initial version of cesa(4) driver for Marvell crypto engine and security
accelerator.
The following algorithms and schemes are supported:
- 3DES, AES, DES
- MD5, SHA1
Obtained from: Semihalf
Written by: Piotr Ziecik
Diffstat (limited to 'sys/dev/cesa/cesa.h')
-rw-r--r-- | sys/dev/cesa/cesa.h | 350 |
1 files changed, 350 insertions, 0 deletions
diff --git a/sys/dev/cesa/cesa.h b/sys/dev/cesa/cesa.h new file mode 100644 index 0000000..2c953f0 --- /dev/null +++ b/sys/dev/cesa/cesa.h @@ -0,0 +1,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 |