#ifndef __MVXPSECVAR_H__
#define __MVXPSECVAR_H__
#include <sys/device.h>
#include <dev/marvell/mvxpsecreg.h>
#define MVXPSEC_MULTI_PACKET
#define MVXPSEC_EVENT_COUNTERS
struct mvxpsec_devmem {
bus_dmamap_t map;
void *kva;
int size;
};
#define dm_paddr dm_segs[0].ds_addr
#define devmem_va(x) ((x)->kva)
#define devmem_nseg(x) ((x)->map->dm_nsegs)
#define devmem_pa(x, s) ((x)->map->dm_segs[(s)].ds_addr)
#define devmem_palen(x, s) ((x)->map->dm_segs[(s)].ds_len)
#define devmem_size(x) ((x)->size)
#define devmem_map(x) ((x)->map)
struct mvxpsec_descriptor {
uint32_t tdma_word0;
uint32_t tdma_src;
uint32_t tdma_dst;
uint32_t tdma_nxt;
} __attribute__((__packed__));
struct mvxpsec_descriptor_handle {
bus_dmamap_t map;
paddr_t phys_addr;
int off;
void *_desc;
SIMPLEQ_ENTRY(mvxpsec_descriptor_handle) chain;
};
SIMPLEQ_HEAD(mvxpsec_descriptor_list, mvxpsec_descriptor_handle);
struct mvxpsec_descriptor_ring {
struct mvxpsec_descriptor_handle *dma_head;
struct mvxpsec_descriptor_handle *dma_last;
int dma_size;
};
#define MVXPSEC_SYNC_DESC(sc, x, f) \
do { \
bus_dmamap_sync((sc)->sc_dmat, (x)->map, \
(x)->off, sizeof(struct mvxpsec_descriptor), (f)); \
} while (0);
typedef struct mvxpsec_descriptor_ring mvxpsec_dma_ring;
#define MV_TDMA_DEFAULT_CONTROL \
( MV_TDMA_CONTROL_DST_BURST_32 | \
MV_TDMA_CONTROL_SRC_BURST_32 | \
MV_TDMA_CONTROL_OUTS_EN | \
MV_TDMA_CONTROL_OUTS_MODE_4OUTS | \
MV_TDMA_CONTROL_BSWAP_DIS )
struct mvxpsec_acc_descriptor {
uint32_t acc_config;
uint32_t acc_encdata;
uint32_t acc_enclen;
uint32_t acc_enckey;
uint32_t acc_enciv;
uint32_t acc_macsrc;
uint32_t acc_macdst;
uint32_t acc_maciv;
#define acc_desc_dword0 acc_config
#define acc_desc_dword1 acc_encdata
#define acc_desc_dword2 acc_enclen
#define acc_desc_dword3 acc_enckey
#define acc_desc_dword4 acc_enciv
#define acc_desc_dword5 acc_macsrc
#define acc_desc_dword6 acc_macdst
#define acc_desc_dword7 acc_maciv
} __attribute__((aligned(4)));
struct mvxpsec_crp_key {
uint32_t crp_key32[8];
} __attribute__((aligned(4)));
struct mvxpsec_crp_iv {
uint32_t crp_iv32[4];
} __attribute__((aligned(4)));
struct mvxpsec_mac_iv {
uint32_t mac_iv32[5];
uint32_t mac_ivpad[1];
} __attribute__((aligned(8)));
struct mvxpsec_packet_header {
struct mvxpsec_acc_descriptor desc;
struct mvxpsec_crp_iv crp_iv_work;
struct mvxpsec_crp_iv crp_iv_ext;
} __attribute__((aligned(4)));
struct mvxpsec_session_header {
struct mvxpsec_crp_key crp_key;
struct mvxpsec_crp_key crp_key_d;
struct mvxpsec_mac_iv miv_in;
struct mvxpsec_mac_iv miv_out;
uint8_t pad[16];
} __attribute__((aligned(4)));
#define SRAM_PAYLOAD_SIZE \
(MV_ACC_SRAM_SIZE \
- sizeof(struct mvxpsec_packet_header) \
- sizeof(struct mvxpsec_session_header))
struct mvxpsec_crypt_sram {
struct mvxpsec_packet_header packet_header;
struct mvxpsec_session_header session_header;
uint8_t payload[SRAM_PAYLOAD_SIZE];
} __attribute__((aligned(8)));
#define MVXPSEC_SRAM_PKT_HDR_OFF \
(offsetof(struct mvxpsec_crypt_sram, packet_header))
#define MVXPSEC_SRAM_DESC_OFF (MVXPSEC_SRAM_PKT_HDR_OFF + \
offsetof(struct mvxpsec_packet_header, desc))
#define MVXPSEC_SRAM_IV_WORK_OFF (MVXPSEC_SRAM_PKT_HDR_OFF + \
offsetof(struct mvxpsec_packet_header, crp_iv_work))
#define MVXPSEC_SRAM_IV_EXT_OFF (MVXPSEC_SRAM_PKT_HDR_OFF + \
offsetof(struct mvxpsec_packet_header, crp_iv_ext))
#define MVXPSEC_SRAM_SESS_HDR_OFF \
(offsetof(struct mvxpsec_crypt_sram, session_header))
#define MVXPSEC_SRAM_KEY_OFF (MVXPSEC_SRAM_SESS_HDR_OFF + \
offsetof(struct mvxpsec_session_header, crp_key))
#define MVXPSEC_SRAM_KEY_D_OFF (MVXPSEC_SRAM_SESS_HDR_OFF + \
offsetof(struct mvxpsec_session_header, crp_key_d))
#define MVXPSEC_SRAM_MIV_IN_OFF (MVXPSEC_SRAM_SESS_HDR_OFF + \
offsetof(struct mvxpsec_session_header, miv_in))
#define MVXPSEC_SRAM_MIV_OUT_OFF (MVXPSEC_SRAM_SESS_HDR_OFF + \
offsetof(struct mvxpsec_session_header, miv_out))
#define MVXPSEC_SRAM_PAYLOAD_OFF \
(offsetof(struct mvxpsec_crypt_sram, payload))
#define MVXPSEC_SRAM_DESC_DA MVXPSEC_SRAM_DESC_OFF
#define MVXPSEC_SRAM_IV_WORK_DA MVXPSEC_SRAM_IV_WORK_OFF
#define MVXPSEC_SRAM_IV_EXT_DA MVXPSEC_SRAM_IV_EXT_OFF
#define MVXPSEC_SRAM_KEY_DA MVXPSEC_SRAM_KEY_OFF
#define MVXPSEC_SRAM_KEY_D_DA MVXPSEC_SRAM_KEY_D_OFF
#define MVXPSEC_SRAM_MIV_IN_DA MVXPSEC_SRAM_MIV_IN_OFF
#define MVXPSEC_SRAM_MIV_OUT_DA MVXPSEC_SRAM_MIV_OUT_OFF
#define MVXPSEC_SRAM_PAYLOAD_DA(offset) \
(MVXPSEC_SRAM_PAYLOAD_OFF + (offset))
enum mvxpsec_data_type {
MVXPSEC_DATA_NONE,
MVXPSEC_DATA_RAW,
MVXPSEC_DATA_MBUF,
MVXPSEC_DATA_UIO,
MVXPSEC_DATA_LAST,
};
#define RDY_DATA (1 << 0)
#define RDY_CRP_KEY (1 << 1)
#define RDY_CRP_IV (1 << 2)
#define RDY_MAC_KEY (1 << 3)
#define RDY_MAC_IV (1 << 4)
#define CRP_EXT_IV (1 << 5)
#define SETUP_DONE (1 << 10)
#define DELETED (1 << 11)
#define DIR_ENCRYPT (1 << 12)
#define DIR_DECRYPT (1 << 13)
#define HW_RUNNING (1 << 16)
#define MVXPSEC_MAX_SESSIONS 512
struct mvxpsec_session {
struct mvxpsec_softc *sc;
uint32_t sid;
uint32_t sflags;
uint32_t refs;
bus_dmamap_t session_header_map;
struct mvxpsec_session_header session_header;
int enc_klen;
int mac_klen;
struct mvxpsec_crp_iv session_iv;
int cipher_alg;
int hmac_alg;
};
struct mvxpsec_packet {
struct mvxpsec_session *mv_s;
struct cryptop *crp;
int flags;
mvxpsec_dma_ring dma_ring;
bus_dmamap_t pkt_header_map;
struct mvxpsec_packet_header pkt_header;
bus_dmamap_t data_map;
enum mvxpsec_data_type data_type;
uint32_t data_len;
union {
void *ptr;
void *raw;
struct mbuf *mbuf;
struct uio *uio;
} data;
void *ext_iv;
int ext_ivlen;
uint32_t enc_off;
uint32_t enc_len;
uint32_t enc_ivoff;
uint32_t mac_off;
uint32_t mac_len;
uint32_t mac_dst;
#define data_ptr data.ptr
#define data_raw data.raw
#define data_mbuf data.mbuf
#define data_uio data.uio
SIMPLEQ_ENTRY(mvxpsec_packet) queue;
SLIST_ENTRY(mvxpsec_packet) free_list;
};
typedef SIMPLEQ_HEAD(mvxpsec_packet_queue, mvxpsec_packet) mvxpsec_queue_t;
typedef SLIST_HEAD(mvxpsec_packet_list, mvxpsec_packet) mvxpsec_list_t;
#define MVXPSEC_DMA_DESC_PAGES 16
#define MVXPSEC_DMA_MAX_SEGS 30
#define MVXPSEC_DMA_MAX_SIZE 2048
#define MVXPSEC_ALL_INT (0xffffffff)
#define MVXPSEC_ALL_ERR (0xffffffff)
#define MVXPSEC_DEFAULT_INT (MVXPSEC_INT_ACCTDMA)
#define MVXPSEC_DEFAULT_ERR (MVXPSEC_ALL_ERR)
#define MVXPSEC_MAX_QLEN 512
#define MVXPSEC_QLEN_HIWAT 256
#define MVXPSEC_QLEN_DEF_LOWAT 16
#define MVXPSEC_DEF_PENDING 0
struct mvxpsec_evcnt {
struct evcnt intr_all;
struct evcnt intr_auth;
struct evcnt intr_des;
struct evcnt intr_aes_enc;
struct evcnt intr_aes_dec;
struct evcnt intr_enc;
struct evcnt intr_sa;
struct evcnt intr_acctdma;
struct evcnt intr_comp;
struct evcnt intr_own;
struct evcnt intr_acctdma_cont;
struct evcnt session_new;
struct evcnt session_free;
struct evcnt packet_ok;
struct evcnt packet_err;
struct evcnt dispatch_packets;
struct evcnt dispatch_queue;
struct evcnt queue_full;
struct evcnt max_dispatch;
struct evcnt max_done;
};
#ifdef MVXPSEC_EVENT_COUNTERS
#define MVXPSEC_EVCNT_INCR(sc, name) do { \
(sc)->sc_ev.name.ev_count++; \
} while (0)
#define MVXPSEC_EVCNT_ADD(sc, name, val) do { \
(sc)->sc_ev.name.ev_count += (val); \
} while (0)
#define MVXPSEC_EVCNT_MAX(sc, name, val) do { \
if ((val) > (sc)->sc_ev.name.ev_count) \
(sc)->sc_ev.name.ev_count = (val); \
} while (0)
#else
#define MVXPSEC_EVCNT_INCR(sc, name)
#define MVXPSEC_EVCNT_ADD(sc, name, val)
#define MVXPSEC_EVCNT_MAX(sc, name, val)
#endif
struct mvxpsec_softc {
device_t sc_dev;
uint32_t sc_cid;
bus_space_tag_t sc_iot;
bus_space_handle_t sc_ioh;
bus_dma_tag_t sc_dmat;
struct mvxpsec_devmem *sc_devmem_desc;
struct mvxpsec_devmem *sc_devmem_mmap;
pool_cache_t sc_session_pool;
pool_cache_t sc_packet_pool;
#ifdef MVXPSEC_EVENT_COUNTERS
struct mvxpsec_evcnt sc_ev;
#endif
paddr_t sc_sram_pa;
void * sc_sram_va;
callout_t sc_timeout;
void * sc_done_ih;
void * sc_error_ih;
kmutex_t sc_dma_mtx;
struct mvxpsec_descriptor_handle *sc_desc_ring;
int sc_desc_ring_size;
int sc_desc_ring_prod;
int sc_desc_ring_cons;
kmutex_t sc_session_mtx;
struct mvxpsec_session *sc_sessions[MVXPSEC_MAX_SESSIONS];
int sc_nsessions;
struct mvxpsec_session *sc_last_session;
kmutex_t sc_queue_mtx;
mvxpsec_queue_t sc_wait_queue;
int sc_wait_qlen;
int sc_wait_qlimit;
mvxpsec_queue_t sc_run_queue;
mvxpsec_list_t sc_free_list;
int sc_free_qlen;
uint32_t sc_flags;
int sc_craft_conf;
int sc_craft_p0;
};
#define MVXPSEC_SRAM_BASE(sc) ((sc)->sc_sram_pa)
#define MVXPSEC_SRAM_SIZE(sc) (sizeof(struct mvxpsec_crypt_sram))
#define MVXPSEC_SRAM_PA(sc, offset) \
(MVXPSEC_SRAM_BASE(sc) + (offset))
#define MVXPSEC_SRAM_LIMIT(sc) \
(MVXPSEC_SRAM_BASE(sc) + MVXPSEC_SRAM_SIZE(sc))
#define MVXPSEC_SRAM_PKT_HDR_PA(sc) \
MVXPSEC_SRAM_PA((sc), MVXPSEC_SRAM_PKT_HDR_OFF)
#define MVXPSEC_SRAM_DESC_PA(sc) \
MVXPSEC_SRAM_PA((sc), MVXPSEC_SRAM_DESC_OFF)
#define MVXPSEC_SRAM_IV_WORK_PA(sc) \
MVXPSEC_SRAM_PA((sc), MVXPSEC_SRAM_IV_WORK_OFF)
#define MVXPSEC_SRAM_SESS_HDR_PA(sc) \
MVXPSEC_SRAM_PA((sc), MVXPSEC_SRAM_SESS_HDR_OFF)
#define MVXPSEC_SRAM_KEY_PA(sc) \
MVXPSEC_SRAM_PA((sc), MVXPSEC_SRAM_KEY_OFF)
#define MVXPSEC_SRAM_KEY_D_PA(sc) \
MVXPSEC_SRAM_PA((sc), MVXPSEC_SRAM_KEY_D_OFF)
#define MVXPSEC_SRAM_MIV_IN_PA(sc) \
MVXPSEC_SRAM_PA((sc), MVXPSEC_SRAM_MIV_IN_OFF)
#define MVXPSEC_SRAM_MIV_OUT_PA(sc) \
MVXPSEC_SRAM_PA((sc), MVXPSEC_SRAM_MIV_OUT_OFF)
#define MVXPSEC_SRAM_PAYLOAD_PA(sc, offset) \
MVXPSEC_SRAM_PA((sc), MVXPSEC_SRAM_PAYLOAD_OFF + (offset))
extern int mvxpsec_register(struct mvxpsec_softc *);
extern int mvxpsec_newsession(void *, uint32_t *, struct cryptoini *);
extern void mvxpsec_freesession(void *, uint64_t);
extern int mvxpsec_dispatch(void *, struct cryptop *, int);
extern void mvxpsec_done(void *);
#define MVXPSEC_DEBUG_DMA __BIT(0)
#define MVXPSEC_DEBUG_IOCTL __BIT(1)
#define MVXPSEC_DEBUG_INTR __BIT(2)
#define MVXPSEC_DEBUG_SRAM __BIT(3)
#define MVXPSEC_DEBUG_OPENCRYPTO __BIT(4)
#define MVXPSEC_DEBUG_PAYLOAD __BIT(5)
#define MVXPSEC_DEBUG_HASH_IV __BIT(6)
#define MVXPSEC_DEBUG_HASH_VAL __BIT(7)
#define MVXPSEC_DEBUG_DESC __BIT(8)
#define MVXPSEC_DEBUG_INPUT __BIT(9)
#define MVXPSEC_DEBUG_ENC_IV __BIT(10)
#define MVXPSEC_DEBUG_QUEUE __BIT(11)
#define MVXPSEC_DEBUG_ALL __BITS(11,0)
#ifdef MVXPSEC_DEBUG
#define MVXPSEC_PRINTF(level, fmt, ...) \
do { \
if (mvxpsec_debug & level) { \
printf("%s: ", __func__); \
printf((fmt), ##__VA_ARGS__); \
} \
} while (0)
#else
#define MVXPSEC_PRINTF(level, fmt, ...)
#endif
#endif