summaryrefslogtreecommitdiff
path: root/target/linux/generic-2.4/files/crypto/ocf/kirkwood/cesa_ocf_drv.c
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/generic-2.4/files/crypto/ocf/kirkwood/cesa_ocf_drv.c')
-rw-r--r--target/linux/generic-2.4/files/crypto/ocf/kirkwood/cesa_ocf_drv.c1296
1 files changed, 0 insertions, 1296 deletions
diff --git a/target/linux/generic-2.4/files/crypto/ocf/kirkwood/cesa_ocf_drv.c b/target/linux/generic-2.4/files/crypto/ocf/kirkwood/cesa_ocf_drv.c
deleted file mode 100644
index ccf92276c0..0000000000
--- a/target/linux/generic-2.4/files/crypto/ocf/kirkwood/cesa_ocf_drv.c
+++ /dev/null
@@ -1,1296 +0,0 @@
-/*******************************************************************************
-Copyright (C) Marvell International Ltd. and its affiliates
-
-This software file (the "File") is owned and distributed by Marvell
-International Ltd. and/or its affiliates ("Marvell") under the following
-alternative licensing terms. Once you have made an election to distribute the
-File under one of the following license alternatives, please (i) delete this
-introductory statement regarding license alternatives, (ii) delete the two
-license alternatives that you have not elected to use and (iii) preserve the
-Marvell copyright notice above.
-
-
-********************************************************************************
-Marvell GPL License Option
-
-If you received this File from Marvell, you may opt to use, redistribute and/or
-modify this File in accordance with the terms and conditions of the General
-Public License Version 2, June 1991 (the "GPL License"), a copy of which is
-available along with the File in the license.txt file or by writing to the Free
-Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
-on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
-
-THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
-WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
-DISCLAIMED. The GPL License provides additional details about this warranty
-disclaimer.
-*******************************************************************************/
-
-#ifndef AUTOCONF_INCLUDED
-#include <linux/config.h>
-#endif
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/list.h>
-#include <linux/slab.h>
-#include <linux/sched.h>
-#include <linux/wait.h>
-#include <linux/crypto.h>
-#include <linux/mm.h>
-#include <linux/skbuff.h>
-#include <linux/random.h>
-#include <linux/platform_device.h>
-#include <asm/scatterlist.h>
-#include <linux/spinlock.h>
-#include "ctrlEnv/sys/mvSysCesa.h"
-#include "cesa/mvCesa.h" /* moved here before cryptodev.h due to include dependencies */
-#include <cryptodev.h>
-#include <uio.h>
-#include <plat/mv_cesa.h>
-#include <linux/mbus.h>
-#include "mvDebug.h"
-
-#include "cesa/mvMD5.h"
-#include "cesa/mvSHA1.h"
-
-#include "cesa/mvCesaRegs.h"
-#include "cesa/AES/mvAes.h"
-#include "cesa/mvLru.h"
-
-#undef RT_DEBUG
-#ifdef RT_DEBUG
-static int debug = 1;
-module_param(debug, int, 1);
-MODULE_PARM_DESC(debug, "Enable debug");
-#undef dprintk
-#define dprintk(a...) if (debug) { printk(a); } else
-#else
-static int debug = 0;
-#undef dprintk
-#define dprintk(a...)
-#endif
-
-
-/* TDMA Regs */
-#define WINDOW_BASE(i) 0xA00 + (i << 3)
-#define WINDOW_CTRL(i) 0xA04 + (i << 3)
-
-/* interrupt handling */
-#undef CESA_OCF_POLLING
-#undef CESA_OCF_TASKLET
-
-#if defined(CESA_OCF_POLLING) && defined(CESA_OCF_TASKLET)
-#error "don't use both tasklet and polling mode"
-#endif
-
-extern int cesaReqResources;
-/* support for spliting action into 2 actions */
-#define CESA_OCF_SPLIT
-
-/* general defines */
-#define CESA_OCF_MAX_SES 128
-#define CESA_Q_SIZE 64
-
-
-/* data structures */
-struct cesa_ocf_data {
- int cipher_alg;
- int auth_alg;
- int encrypt_tn_auth;
-#define auth_tn_decrypt encrypt_tn_auth
- int ivlen;
- int digestlen;
- short sid_encrypt;
- short sid_decrypt;
- /* fragment workaround sessions */
- short frag_wa_encrypt;
- short frag_wa_decrypt;
- short frag_wa_auth;
-};
-
-/* CESA device data */
-struct cesa_dev {
- void __iomem *sram;
- void __iomem *reg;
- struct mv_cesa_platform_data *plat_data;
- int irq;
-};
-
-#define DIGEST_BUF_SIZE 32
-struct cesa_ocf_process {
- MV_CESA_COMMAND cesa_cmd;
- MV_CESA_MBUF cesa_mbuf;
- MV_BUF_INFO cesa_bufs[MV_CESA_MAX_MBUF_FRAGS];
- char digest[DIGEST_BUF_SIZE];
- int digest_len;
- struct cryptop *crp;
- int need_cb;
-};
-
-/* global variables */
-static int32_t cesa_ocf_id = -1;
-static struct cesa_ocf_data *cesa_ocf_sessions[CESA_OCF_MAX_SES];
-static spinlock_t cesa_lock;
-static struct cesa_dev cesa_device;
-
-/* static APIs */
-static int cesa_ocf_process (device_t, struct cryptop *, int);
-static int cesa_ocf_newsession (device_t, u_int32_t *, struct cryptoini *);
-static int cesa_ocf_freesession (device_t, u_int64_t);
-static void cesa_callback (unsigned long);
-static irqreturn_t cesa_interrupt_handler (int, void *);
-#ifdef CESA_OCF_POLLING
-static void cesa_interrupt_polling(void);
-#endif
-#ifdef CESA_OCF_TASKLET
-static struct tasklet_struct cesa_ocf_tasklet;
-#endif
-
-static struct timeval tt_start;
-static struct timeval tt_end;
-
-/*
- * dummy device structure
- */
-
-static struct {
- softc_device_decl sc_dev;
-} mv_cesa_dev;
-
-static device_method_t mv_cesa_methods = {
- /* crypto device methods */
- DEVMETHOD(cryptodev_newsession, cesa_ocf_newsession),
- DEVMETHOD(cryptodev_freesession,cesa_ocf_freesession),
- DEVMETHOD(cryptodev_process, cesa_ocf_process),
- DEVMETHOD(cryptodev_kprocess, NULL),
-};
-
-
-
-/* Add debug Trace */
-#undef CESA_OCF_TRACE_DEBUG
-#ifdef CESA_OCF_TRACE_DEBUG
-
-#define MV_CESA_USE_TIMER_ID 0
-
-typedef struct
-{
- int type; /* 0 - isrEmpty, 1 - cesaReadyGet, 2 - cesaAction */
- MV_U32 timeStamp;
- MV_U32 cause;
- MV_U32 realCause;
- MV_U32 dmaCause;
- int resources;
- MV_CESA_REQ* pReqReady;
- MV_CESA_REQ* pReqEmpty;
- MV_CESA_REQ* pReqProcess;
-} MV_CESA_TEST_TRACE;
-
-#define MV_CESA_TEST_TRACE_SIZE 50
-
-static int cesaTestTraceIdx = 0;
-static MV_CESA_TEST_TRACE cesaTestTrace[MV_CESA_TEST_TRACE_SIZE];
-
-static void cesaTestTraceAdd(int type)
-{
- cesaTestTrace[cesaTestTraceIdx].type = type;
- cesaTestTrace[cesaTestTraceIdx].realCause = MV_REG_READ(MV_CESA_ISR_CAUSE_REG);
- //cesaTestTrace[cesaTestTraceIdx].idmaCause = MV_REG_READ(IDMA_CAUSE_REG);
- cesaTestTrace[cesaTestTraceIdx].resources = cesaReqResources;
- cesaTestTrace[cesaTestTraceIdx].pReqReady = pCesaReqReady;
- cesaTestTrace[cesaTestTraceIdx].pReqEmpty = pCesaReqEmpty;
- cesaTestTrace[cesaTestTraceIdx].pReqProcess = pCesaReqProcess;
- cesaTestTrace[cesaTestTraceIdx].timeStamp = mvCntmrRead(MV_CESA_USE_TIMER_ID);
- cesaTestTraceIdx++;
- if(cesaTestTraceIdx == MV_CESA_TEST_TRACE_SIZE)
- cesaTestTraceIdx = 0;
-}
-
-#else /* CESA_OCF_TRACE_DEBUG */
-
-#define cesaTestTraceAdd(x)
-
-#endif /* CESA_OCF_TRACE_DEBUG */
-
-unsigned int
-get_usec(unsigned int start)
-{
- if(start) {
- do_gettimeofday (&tt_start);
- return 0;
- }
- else {
- do_gettimeofday (&tt_end);
- tt_end.tv_sec -= tt_start.tv_sec;
- tt_end.tv_usec -= tt_start.tv_usec;
- if (tt_end.tv_usec < 0) {
- tt_end.tv_usec += 1000 * 1000;
- tt_end.tv_sec -= 1;
- }
- }
- printk("time taken is %d\n", (unsigned int)(tt_end.tv_usec + tt_end.tv_sec * 1000000));
- return (tt_end.tv_usec + tt_end.tv_sec * 1000000);
-}
-
-#ifdef RT_DEBUG
-/*
- * check that the crp action match the current session
- */
-static int
-ocf_check_action(struct cryptop *crp, struct cesa_ocf_data *cesa_ocf_cur_ses) {
- int count = 0;
- int encrypt = 0, decrypt = 0, auth = 0;
- struct cryptodesc *crd;
-
- /* Go through crypto descriptors, processing as we go */
- for (crd = crp->crp_desc; crd; crd = crd->crd_next, count++) {
- if(count > 2) {
- printk("%s,%d: session mode is not supported.\n", __FILE__, __LINE__);
- return 1;
- }
-
- /* Encryption /Decryption */
- if(crd->crd_alg == cesa_ocf_cur_ses->cipher_alg) {
- /* check that the action is compatible with session */
- if(encrypt || decrypt) {
- printk("%s,%d: session mode is not supported.\n", __FILE__, __LINE__);
- return 1;
- }
-
- if(crd->crd_flags & CRD_F_ENCRYPT) { /* encrypt */
- if( (count == 2) && (cesa_ocf_cur_ses->encrypt_tn_auth) ) {
- printk("%s,%d: sequence isn't supported by this session.\n", __FILE__, __LINE__);
- return 1;
- }
- encrypt++;
- }
- else { /* decrypt */
- if( (count == 2) && !(cesa_ocf_cur_ses->auth_tn_decrypt) ) {
- printk("%s,%d: sequence isn't supported by this session.\n", __FILE__, __LINE__);
- return 1;
- }
- decrypt++;
- }
-
- }
- /* Authentication */
- else if(crd->crd_alg == cesa_ocf_cur_ses->auth_alg) {
- /* check that the action is compatible with session */
- if(auth) {
- printk("%s,%d: session mode is not supported.\n", __FILE__, __LINE__);
- return 1;
- }
- if( (count == 2) && (decrypt) && (cesa_ocf_cur_ses->auth_tn_decrypt)) {
- printk("%s,%d: sequence isn't supported by this session.\n", __FILE__, __LINE__);
- return 1;
- }
- if( (count == 2) && (encrypt) && !(cesa_ocf_cur_ses->encrypt_tn_auth)) {
- printk("%s,%d: sequence isn't supported by this session.\n", __FILE__, __LINE__);
- return 1;
- }
- auth++;
- }
- else {
- printk("%s,%d: Alg isn't supported by this session.\n", __FILE__, __LINE__);
- return 1;
- }
- }
- return 0;
-
-}
-#endif
-
-/*
- * Process a request.
- */
-static int
-cesa_ocf_process(device_t dev, struct cryptop *crp, int hint)
-{
- struct cesa_ocf_process *cesa_ocf_cmd = NULL;
- struct cesa_ocf_process *cesa_ocf_cmd_wa = NULL;
- MV_CESA_COMMAND *cesa_cmd;
- struct cryptodesc *crd;
- struct cesa_ocf_data *cesa_ocf_cur_ses;
- int sid = 0, temp_len = 0, i;
- int encrypt = 0, decrypt = 0, auth = 0;
- int status;
- struct sk_buff *skb = NULL;
- struct uio *uiop = NULL;
- unsigned char *ivp;
- MV_BUF_INFO *p_buf_info;
- MV_CESA_MBUF *p_mbuf_info;
- unsigned long flags;
-
- dprintk("%s()\n", __FUNCTION__);
-
- if( cesaReqResources <= 1 ) {
- dprintk("%s,%d: ERESTART\n", __FILE__, __LINE__);
- return ERESTART;
- }
-
-#ifdef RT_DEBUG
- /* Sanity check */
- if (crp == NULL) {
- printk("%s,%d: EINVAL\n", __FILE__, __LINE__);
- return EINVAL;
- }
-
- if (crp->crp_desc == NULL || crp->crp_buf == NULL ) {
- printk("%s,%d: EINVAL\n", __FILE__, __LINE__);
- crp->crp_etype = EINVAL;
- return EINVAL;
- }
-
- sid = crp->crp_sid & 0xffffffff;
- if ((sid >= CESA_OCF_MAX_SES) || (cesa_ocf_sessions[sid] == NULL)) {
- crp->crp_etype = ENOENT;
- printk("%s,%d: ENOENT session %d \n", __FILE__, __LINE__, sid);
- return EINVAL;
- }
-#endif
-
- sid = crp->crp_sid & 0xffffffff;
- crp->crp_etype = 0;
- cesa_ocf_cur_ses = cesa_ocf_sessions[sid];
-
-#ifdef RT_DEBUG
- if(ocf_check_action(crp, cesa_ocf_cur_ses)){
- goto p_error;
- }
-#endif
-
- /* malloc a new cesa process */
- cesa_ocf_cmd = kmalloc(sizeof(struct cesa_ocf_process), GFP_ATOMIC);
-
- if (cesa_ocf_cmd == NULL) {
- printk("%s,%d: ENOBUFS \n", __FILE__, __LINE__);
- goto p_error;
- }
- memset(cesa_ocf_cmd, 0, sizeof(struct cesa_ocf_process));
-
- /* init cesa_process */
- cesa_ocf_cmd->crp = crp;
- /* always call callback */
- cesa_ocf_cmd->need_cb = 1;
-
- /* init cesa_cmd for usage of the HALs */
- cesa_cmd = &cesa_ocf_cmd->cesa_cmd;
- cesa_cmd->pReqPrv = (void *)cesa_ocf_cmd;
- cesa_cmd->sessionId = cesa_ocf_cur_ses->sid_encrypt; /* defualt use encrypt */
-
- /* prepare src buffer */
- /* we send the entire buffer to the HAL, even if only part of it should be encrypt/auth. */
- /* if not using seesions for both encrypt and auth, then it will be wiser to to copy only */
- /* from skip to crd_len. */
- p_buf_info = cesa_ocf_cmd->cesa_bufs;
- p_mbuf_info = &cesa_ocf_cmd->cesa_mbuf;
-
- p_buf_info += 2; /* save 2 first buffers for IV and digest -
- we won't append them to the end since, they
- might be places in an unaligned addresses. */
-
- p_mbuf_info->pFrags = p_buf_info;
- temp_len = 0;
-
- /* handle SKB */
- if (crp->crp_flags & CRYPTO_F_SKBUF) {
-
- dprintk("%s,%d: handle SKB.\n", __FILE__, __LINE__);
- skb = (struct sk_buff *) crp->crp_buf;
-
- if (skb_shinfo(skb)->nr_frags >= (MV_CESA_MAX_MBUF_FRAGS - 1)) {
- printk("%s,%d: %d nr_frags > MV_CESA_MAX_MBUF_FRAGS", __FILE__, __LINE__, skb_shinfo(skb)->nr_frags);
- goto p_error;
- }
-
- p_mbuf_info->mbufSize = skb->len;
- temp_len = skb->len;
- /* first skb fragment */
- p_buf_info->bufSize = skb_headlen(skb);
- p_buf_info->bufVirtPtr = skb->data;
- p_buf_info++;
-
- /* now handle all other skb fragments */
- for ( i = 0; i < skb_shinfo(skb)->nr_frags; i++ ) {
- skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
- p_buf_info->bufSize = frag->size;
- p_buf_info->bufVirtPtr = page_address(frag->page) + frag->page_offset;
- p_buf_info++;
- }
- p_mbuf_info->numFrags = skb_shinfo(skb)->nr_frags + 1;
- }
- /* handle UIO */
- else if(crp->crp_flags & CRYPTO_F_IOV) {
-
- dprintk("%s,%d: handle UIO.\n", __FILE__, __LINE__);
- uiop = (struct uio *) crp->crp_buf;
-
- if (uiop->uio_iovcnt > (MV_CESA_MAX_MBUF_FRAGS - 1)) {
- printk("%s,%d: %d uio_iovcnt > MV_CESA_MAX_MBUF_FRAGS \n", __FILE__, __LINE__, uiop->uio_iovcnt);
- goto p_error;
- }
-
- p_mbuf_info->mbufSize = crp->crp_ilen;
- p_mbuf_info->numFrags = uiop->uio_iovcnt;
- for(i = 0; i < uiop->uio_iovcnt; i++) {
- p_buf_info->bufVirtPtr = uiop->uio_iov[i].iov_base;
- p_buf_info->bufSize = uiop->uio_iov[i].iov_len;
- temp_len += p_buf_info->bufSize;
- dprintk("%s,%d: buf %x-> addr %x, size %x \n"
- , __FILE__, __LINE__, i, (unsigned int)p_buf_info->bufVirtPtr, p_buf_info->bufSize);
- p_buf_info++;
- }
-
- }
- /* handle CONTIG */
- else {
- dprintk("%s,%d: handle CONTIG.\n", __FILE__, __LINE__);
- p_mbuf_info->numFrags = 1;
- p_mbuf_info->mbufSize = crp->crp_ilen;
- p_buf_info->bufVirtPtr = crp->crp_buf;
- p_buf_info->bufSize = crp->crp_ilen;
- temp_len = crp->crp_ilen;
- p_buf_info++;
- }
-
- /* Support up to 64K why? cause! */
- if(crp->crp_ilen > 64*1024) {
- printk("%s,%d: buf too big %x \n", __FILE__, __LINE__, crp->crp_ilen);
- goto p_error;
- }
-
- if( temp_len != crp->crp_ilen ) {
- printk("%s,%d: warning size don't match.(%x %x) \n", __FILE__, __LINE__, temp_len, crp->crp_ilen);
- }
-
- cesa_cmd->pSrc = p_mbuf_info;
- cesa_cmd->pDst = p_mbuf_info;
-
- /* restore p_buf_info to point to first available buf */
- p_buf_info = cesa_ocf_cmd->cesa_bufs;
- p_buf_info += 1;
-
-
- /* Go through crypto descriptors, processing as we go */
- for (crd = crp->crp_desc; crd; crd = crd->crd_next) {
-
- /* Encryption /Decryption */
- if(crd->crd_alg == cesa_ocf_cur_ses->cipher_alg) {
-
- dprintk("%s,%d: cipher", __FILE__, __LINE__);
-
- cesa_cmd->cryptoOffset = crd->crd_skip;
- cesa_cmd->cryptoLength = crd->crd_len;
-
- if(crd->crd_flags & CRD_F_ENCRYPT) { /* encrypt */
- dprintk(" encrypt \n");
- encrypt++;
-
- /* handle IV */
- if (crd->crd_flags & CRD_F_IV_EXPLICIT) { /* IV from USER */
- dprintk("%s,%d: IV from USER (offset %x) \n", __FILE__, __LINE__, crd->crd_inject);
- cesa_cmd->ivFromUser = 1;
- ivp = crd->crd_iv;
-
- /*
- * do we have to copy the IV back to the buffer ?
- */
- if ((crd->crd_flags & CRD_F_IV_PRESENT) == 0) {
- dprintk("%s,%d: copy the IV back to the buffer\n", __FILE__, __LINE__);
- cesa_cmd->ivOffset = crd->crd_inject;
- crypto_copy_bits_back(crp->crp_buf, crd->crd_inject, ivp, cesa_ocf_cur_ses->ivlen);
- }
- else {
- dprintk("%s,%d: don't copy the IV back to the buffer \n", __FILE__, __LINE__);
- p_mbuf_info->numFrags++;
- p_mbuf_info->mbufSize += cesa_ocf_cur_ses->ivlen;
- p_mbuf_info->pFrags = p_buf_info;
-
- p_buf_info->bufVirtPtr = ivp;
- p_buf_info->bufSize = cesa_ocf_cur_ses->ivlen;
- p_buf_info--;
-
- /* offsets */
- cesa_cmd->ivOffset = 0;
- cesa_cmd->cryptoOffset += cesa_ocf_cur_ses->ivlen;
- if(auth) {
- cesa_cmd->macOffset += cesa_ocf_cur_ses->ivlen;
- cesa_cmd->digestOffset += cesa_ocf_cur_ses->ivlen;
- }
- }
- }
- else { /* random IV */
- dprintk("%s,%d: random IV \n", __FILE__, __LINE__);
- cesa_cmd->ivFromUser = 0;
-
- /*
- * do we have to copy the IV back to the buffer ?
- */
- /* in this mode the HAL will always copy the IV */
- /* given by the session to the ivOffset */
- if ((crd->crd_flags & CRD_F_IV_PRESENT) == 0) {
- cesa_cmd->ivOffset = crd->crd_inject;
- }
- else {
- /* if IV isn't copy, then how will the user know which IV did we use??? */
- printk("%s,%d: EINVAL\n", __FILE__, __LINE__);
- goto p_error;
- }
- }
- }
- else { /* decrypt */
- dprintk(" decrypt \n");
- decrypt++;
- cesa_cmd->sessionId = cesa_ocf_cur_ses->sid_decrypt;
-
- /* handle IV */
- if (crd->crd_flags & CRD_F_IV_EXPLICIT) {
- dprintk("%s,%d: IV from USER \n", __FILE__, __LINE__);
- /* append the IV buf to the mbuf */
- cesa_cmd->ivFromUser = 1;
- p_mbuf_info->numFrags++;
- p_mbuf_info->mbufSize += cesa_ocf_cur_ses->ivlen;
- p_mbuf_info->pFrags = p_buf_info;
-
- p_buf_info->bufVirtPtr = crd->crd_iv;
- p_buf_info->bufSize = cesa_ocf_cur_ses->ivlen;
- p_buf_info--;
-
- /* offsets */
- cesa_cmd->ivOffset = 0;
- cesa_cmd->cryptoOffset += cesa_ocf_cur_ses->ivlen;
- if(auth) {
- cesa_cmd->macOffset += cesa_ocf_cur_ses->ivlen;
- cesa_cmd->digestOffset += cesa_ocf_cur_ses->ivlen;
- }
- }
- else {
- dprintk("%s,%d: IV inside the buffer \n", __FILE__, __LINE__);
- cesa_cmd->ivFromUser = 0;
- cesa_cmd->ivOffset = crd->crd_inject;
- }
- }
-
- }
- /* Authentication */
- else if(crd->crd_alg == cesa_ocf_cur_ses->auth_alg) {
- dprintk("%s,%d: Authentication \n", __FILE__, __LINE__);
- auth++;
- cesa_cmd->macOffset = crd->crd_skip;
- cesa_cmd->macLength = crd->crd_len;
-
- /* digest + mac */
- cesa_cmd->digestOffset = crd->crd_inject;
- }
- else {
- printk("%s,%d: Alg isn't supported by this session.\n", __FILE__, __LINE__);
- goto p_error;
- }
- }
-
- dprintk("\n");
- dprintk("%s,%d: Sending Action: \n", __FILE__, __LINE__);
- dprintk("%s,%d: IV from user: %d. IV offset %x \n", __FILE__, __LINE__, cesa_cmd->ivFromUser, cesa_cmd->ivOffset);
- dprintk("%s,%d: crypt offset %x len %x \n", __FILE__, __LINE__, cesa_cmd->cryptoOffset, cesa_cmd->cryptoLength);
- dprintk("%s,%d: Auth offset %x len %x \n", __FILE__, __LINE__, cesa_cmd->macOffset, cesa_cmd->macLength);
- dprintk("%s,%d: set digest in offset %x . \n", __FILE__, __LINE__, cesa_cmd->digestOffset);
- if(debug) {
- mvCesaDebugMbuf("SRC BUFFER", cesa_cmd->pSrc, 0, cesa_cmd->pSrc->mbufSize);
- }
-
-
- /* send action to HAL */
- spin_lock_irqsave(&cesa_lock, flags);
- status = mvCesaAction(cesa_cmd);
- spin_unlock_irqrestore(&cesa_lock, flags);
-
- /* action not allowed */
- if(status == MV_NOT_ALLOWED) {
-#ifdef CESA_OCF_SPLIT
- /* if both encrypt and auth try to split */
- if(auth && (encrypt || decrypt)) {
- MV_CESA_COMMAND *cesa_cmd_wa;
-
- /* malloc a new cesa process and init it */
- cesa_ocf_cmd_wa = kmalloc(sizeof(struct cesa_ocf_process), GFP_ATOMIC);
-
- if (cesa_ocf_cmd_wa == NULL) {
- printk("%s,%d: ENOBUFS \n", __FILE__, __LINE__);
- goto p_error;
- }
- memcpy(cesa_ocf_cmd_wa, cesa_ocf_cmd, sizeof(struct cesa_ocf_process));
- cesa_cmd_wa = &cesa_ocf_cmd_wa->cesa_cmd;
- cesa_cmd_wa->pReqPrv = (void *)cesa_ocf_cmd_wa;
- cesa_ocf_cmd_wa->need_cb = 0;
-
- /* break requests to two operation, first operation completion won't call callback */
- if((decrypt) && (cesa_ocf_cur_ses->auth_tn_decrypt)) {
- cesa_cmd_wa->sessionId = cesa_ocf_cur_ses->frag_wa_auth;
- cesa_cmd->sessionId = cesa_ocf_cur_ses->frag_wa_decrypt;
- }
- else if((decrypt) && !(cesa_ocf_cur_ses->auth_tn_decrypt)) {
- cesa_cmd_wa->sessionId = cesa_ocf_cur_ses->frag_wa_decrypt;
- cesa_cmd->sessionId = cesa_ocf_cur_ses->frag_wa_auth;
- }
- else if((encrypt) && (cesa_ocf_cur_ses->encrypt_tn_auth)) {
- cesa_cmd_wa->sessionId = cesa_ocf_cur_ses->frag_wa_encrypt;
- cesa_cmd->sessionId = cesa_ocf_cur_ses->frag_wa_auth;
- }
- else if((encrypt) && !(cesa_ocf_cur_ses->encrypt_tn_auth)){
- cesa_cmd_wa->sessionId = cesa_ocf_cur_ses->frag_wa_auth;
- cesa_cmd->sessionId = cesa_ocf_cur_ses->frag_wa_encrypt;
- }
- else {
- printk("%s,%d: Unsupporterd fragment wa mode \n", __FILE__, __LINE__);
- goto p_error;
- }
-
- /* send the 2 actions to the HAL */
- spin_lock_irqsave(&cesa_lock, flags);
- status = mvCesaAction(cesa_cmd_wa);
- spin_unlock_irqrestore(&cesa_lock, flags);
-
- if((status != MV_NO_MORE) && (status != MV_OK)) {
- printk("%s,%d: cesa action failed, status = 0x%x\n", __FILE__, __LINE__, status);
- goto p_error;
- }
- spin_lock_irqsave(&cesa_lock, flags);
- status = mvCesaAction(cesa_cmd);
- spin_unlock_irqrestore(&cesa_lock, flags);
-
- }
- /* action not allowed and can't split */
- else
-#endif
- {
- goto p_error;
- }
- }
-
- /* Hal Q is full, send again. This should never happen */
- if(status == MV_NO_RESOURCE) {
- printk("%s,%d: cesa no more resources \n", __FILE__, __LINE__);
- if(cesa_ocf_cmd)
- kfree(cesa_ocf_cmd);
- if(cesa_ocf_cmd_wa)
- kfree(cesa_ocf_cmd_wa);
- return ERESTART;
- }
- else if((status != MV_NO_MORE) && (status != MV_OK)) {
- printk("%s,%d: cesa action failed, status = 0x%x\n", __FILE__, __LINE__, status);
- goto p_error;
- }
-
-
-#ifdef CESA_OCF_POLLING
- cesa_interrupt_polling();
-#endif
- cesaTestTraceAdd(5);
-
- return 0;
-p_error:
- crp->crp_etype = EINVAL;
- if(cesa_ocf_cmd)
- kfree(cesa_ocf_cmd);
- if(cesa_ocf_cmd_wa)
- kfree(cesa_ocf_cmd_wa);
- return EINVAL;
-}
-
-/*
- * cesa callback.
- */
-static void
-cesa_callback(unsigned long dummy)
-{
- struct cesa_ocf_process *cesa_ocf_cmd = NULL;
- struct cryptop *crp = NULL;
- MV_CESA_RESULT result[MV_CESA_MAX_CHAN];
- int res_idx = 0,i;
- MV_STATUS status;
-
- dprintk("%s()\n", __FUNCTION__);
-
-#ifdef CESA_OCF_TASKLET
- disable_irq(cesa_device.irq);
-#endif
- while(MV_TRUE) {
-
- /* Get Ready requests */
- spin_lock(&cesa_lock);
- status = mvCesaReadyGet(&result[res_idx]);
- spin_unlock(&cesa_lock);
-
- cesaTestTraceAdd(2);
-
- if(status != MV_OK) {
-#ifdef CESA_OCF_POLLING
- if(status == MV_BUSY) { /* Fragment */
- cesa_interrupt_polling();
- return;
- }
-#endif
- break;
- }
- res_idx++;
- break;
- }
-
- for(i = 0; i < res_idx; i++) {
-
- if(!result[i].pReqPrv) {
- printk("%s,%d: warning private is NULL\n", __FILE__, __LINE__);
- break;
- }
-
- cesa_ocf_cmd = result[i].pReqPrv;
- crp = cesa_ocf_cmd->crp;
-
- // ignore HMAC error.
- //if(result->retCode)
- // crp->crp_etype = EIO;
-
-#if defined(CESA_OCF_POLLING)
- if(!cesa_ocf_cmd->need_cb){
- cesa_interrupt_polling();
- }
-#endif
- if(cesa_ocf_cmd->need_cb) {
- if(debug) {
- mvCesaDebugMbuf("DST BUFFER", cesa_ocf_cmd->cesa_cmd.pDst, 0, cesa_ocf_cmd->cesa_cmd.pDst->mbufSize);
- }
- crypto_done(crp);
- }
- kfree(cesa_ocf_cmd);
- }
-#ifdef CESA_OCF_TASKLET
- enable_irq(cesa_device.irq);
-#endif
-
- cesaTestTraceAdd(3);
-
- return;
-}
-
-#ifdef CESA_OCF_POLLING
-static void
-cesa_interrupt_polling(void)
-{
- u32 cause;
-
- dprintk("%s()\n", __FUNCTION__);
-
- /* Read cause register */
- do {
- cause = MV_REG_READ(MV_CESA_ISR_CAUSE_REG);
- cause &= MV_CESA_CAUSE_ACC_DMA_ALL_MASK;
-
- } while (cause == 0);
-
- /* clear interrupts */
- MV_REG_WRITE(MV_CESA_ISR_CAUSE_REG, 0);
-
- cesa_callback(0);
-
- return;
-}
-
-#endif
-
-/*
- * cesa Interrupt polling routine.
- */
-static irqreturn_t
-cesa_interrupt_handler(int irq, void *arg)
-{
- u32 cause;
-
- dprintk("%s()\n", __FUNCTION__);
-
- cesaTestTraceAdd(0);
-
- /* Read cause register */
- cause = MV_REG_READ(MV_CESA_ISR_CAUSE_REG);
-
- if( (cause & MV_CESA_CAUSE_ACC_DMA_ALL_MASK) == 0)
- {
- /* Empty interrupt */
- dprintk("%s,%d: cesaTestReadyIsr: cause=0x%x\n", __FILE__, __LINE__, cause);
- return IRQ_HANDLED;
- }
-
- /* clear interrupts */
- MV_REG_WRITE(MV_CESA_ISR_CAUSE_REG, 0);
-
- cesaTestTraceAdd(1);
-#ifdef CESA_OCF_TASKLET
- tasklet_hi_schedule(&cesa_ocf_tasklet);
-#else
- cesa_callback(0);
-#endif
- return IRQ_HANDLED;
-}
-
-/*
- * Open a session.
- */
-static int
-/*cesa_ocf_newsession(void *arg, u_int32_t *sid, struct cryptoini *cri)*/
-cesa_ocf_newsession(device_t dev, u_int32_t *sid, struct cryptoini *cri)
-{
- u32 status = 0, i;
- u32 count = 0, auth = 0, encrypt =0;
- struct cesa_ocf_data *cesa_ocf_cur_ses;
- MV_CESA_OPEN_SESSION cesa_session;
- MV_CESA_OPEN_SESSION *cesa_ses = &cesa_session;
-
-
- dprintk("%s()\n", __FUNCTION__);
- if (sid == NULL || cri == NULL) {
- printk("%s,%d: EINVAL\n", __FILE__, __LINE__);
- return EINVAL;
- }
-
- /* leave first empty like in other implementations */
- for (i = 1; i < CESA_OCF_MAX_SES; i++) {
- if (cesa_ocf_sessions[i] == NULL)
- break;
- }
-
- if(i >= CESA_OCF_MAX_SES) {
- printk("%s,%d: no more sessions \n", __FILE__, __LINE__);
- return EINVAL;
- }
-
- cesa_ocf_sessions[i] = (struct cesa_ocf_data *) kmalloc(sizeof(struct cesa_ocf_data), GFP_ATOMIC);
- if (cesa_ocf_sessions[i] == NULL) {
- cesa_ocf_freesession(NULL, i);
- printk("%s,%d: ENOBUFS \n", __FILE__, __LINE__);
- return ENOBUFS;
- }
- dprintk("%s,%d: new session %d \n", __FILE__, __LINE__, i);
-
- *sid = i;
- cesa_ocf_cur_ses = cesa_ocf_sessions[i];
- memset(cesa_ocf_cur_ses, 0, sizeof(struct cesa_ocf_data));
- cesa_ocf_cur_ses->sid_encrypt = -1;
- cesa_ocf_cur_ses->sid_decrypt = -1;
- cesa_ocf_cur_ses->frag_wa_encrypt = -1;
- cesa_ocf_cur_ses->frag_wa_decrypt = -1;
- cesa_ocf_cur_ses->frag_wa_auth = -1;
-
- /* init the session */
- memset(cesa_ses, 0, sizeof(MV_CESA_OPEN_SESSION));
- count = 1;
- while (cri) {
- if(count > 2) {
- printk("%s,%d: don't support more then 2 operations\n", __FILE__, __LINE__);
- goto error;
- }
- switch (cri->cri_alg) {
- case CRYPTO_AES_CBC:
- dprintk("%s,%d: (%d) AES CBC \n", __FILE__, __LINE__, count);
- cesa_ocf_cur_ses->cipher_alg = cri->cri_alg;
- cesa_ocf_cur_ses->ivlen = MV_CESA_AES_BLOCK_SIZE;
- cesa_ses->cryptoAlgorithm = MV_CESA_CRYPTO_AES;
- cesa_ses->cryptoMode = MV_CESA_CRYPTO_CBC;
- if(cri->cri_klen/8 > MV_CESA_MAX_CRYPTO_KEY_LENGTH) {
- printk("%s,%d: CRYPTO key too long.\n", __FILE__, __LINE__);
- goto error;
- }
- memcpy(cesa_ses->cryptoKey, cri->cri_key, cri->cri_klen/8);
- dprintk("%s,%d: key length %d \n", __FILE__, __LINE__, cri->cri_klen/8);
- cesa_ses->cryptoKeyLength = cri->cri_klen/8;
- encrypt += count;
- break;
- case CRYPTO_3DES_CBC:
- dprintk("%s,%d: (%d) 3DES CBC \n", __FILE__, __LINE__, count);
- cesa_ocf_cur_ses->cipher_alg = cri->cri_alg;
- cesa_ocf_cur_ses->ivlen = MV_CESA_3DES_BLOCK_SIZE;
- cesa_ses->cryptoAlgorithm = MV_CESA_CRYPTO_3DES;
- cesa_ses->cryptoMode = MV_CESA_CRYPTO_CBC;
- if(cri->cri_klen/8 > MV_CESA_MAX_CRYPTO_KEY_LENGTH) {
- printk("%s,%d: CRYPTO key too long.\n", __FILE__, __LINE__);
- goto error;
- }
- memcpy(cesa_ses->cryptoKey, cri->cri_key, cri->cri_klen/8);
- cesa_ses->cryptoKeyLength = cri->cri_klen/8;
- encrypt += count;
- break;
- case CRYPTO_DES_CBC:
- dprintk("%s,%d: (%d) DES CBC \n", __FILE__, __LINE__, count);
- cesa_ocf_cur_ses->cipher_alg = cri->cri_alg;
- cesa_ocf_cur_ses->ivlen = MV_CESA_DES_BLOCK_SIZE;
- cesa_ses->cryptoAlgorithm = MV_CESA_CRYPTO_DES;
- cesa_ses->cryptoMode = MV_CESA_CRYPTO_CBC;
- if(cri->cri_klen/8 > MV_CESA_MAX_CRYPTO_KEY_LENGTH) {
- printk("%s,%d: CRYPTO key too long.\n", __FILE__, __LINE__);
- goto error;
- }
- memcpy(cesa_ses->cryptoKey, cri->cri_key, cri->cri_klen/8);
- cesa_ses->cryptoKeyLength = cri->cri_klen/8;
- encrypt += count;
- break;
- case CRYPTO_MD5:
- case CRYPTO_MD5_HMAC:
- dprintk("%s,%d: (%d) %sMD5 CBC \n", __FILE__, __LINE__, count, (cri->cri_alg != CRYPTO_MD5)? "H-":" ");
- cesa_ocf_cur_ses->auth_alg = cri->cri_alg;
- cesa_ocf_cur_ses->digestlen = (cri->cri_alg == CRYPTO_MD5)? MV_CESA_MD5_DIGEST_SIZE : 12;
- cesa_ses->macMode = (cri->cri_alg == CRYPTO_MD5)? MV_CESA_MAC_MD5 : MV_CESA_MAC_HMAC_MD5;
- if(cri->cri_klen/8 > MV_CESA_MAX_CRYPTO_KEY_LENGTH) {
- printk("%s,%d: MAC key too long. \n", __FILE__, __LINE__);
- goto error;
- }
- cesa_ses->macKeyLength = cri->cri_klen/8;
- memcpy(cesa_ses->macKey, cri->cri_key, cri->cri_klen/8);
- cesa_ses->digestSize = cesa_ocf_cur_ses->digestlen;
- auth += count;
- break;
- case CRYPTO_SHA1:
- case CRYPTO_SHA1_HMAC:
- dprintk("%s,%d: (%d) %sSHA1 CBC \n", __FILE__, __LINE__, count, (cri->cri_alg != CRYPTO_SHA1)? "H-":" ");
- cesa_ocf_cur_ses->auth_alg = cri->cri_alg;
- cesa_ocf_cur_ses->digestlen = (cri->cri_alg == CRYPTO_SHA1)? MV_CESA_SHA1_DIGEST_SIZE : 12;
- cesa_ses->macMode = (cri->cri_alg == CRYPTO_SHA1)? MV_CESA_MAC_SHA1 : MV_CESA_MAC_HMAC_SHA1;
- if(cri->cri_klen/8 > MV_CESA_MAX_CRYPTO_KEY_LENGTH) {
- printk("%s,%d: MAC key too long. \n", __FILE__, __LINE__);
- goto error;
- }
- cesa_ses->macKeyLength = cri->cri_klen/8;
- memcpy(cesa_ses->macKey, cri->cri_key, cri->cri_klen/8);
- cesa_ses->digestSize = cesa_ocf_cur_ses->digestlen;
- auth += count;
- break;
- default:
- printk("%s,%d: unknown algo 0x%x\n", __FILE__, __LINE__, cri->cri_alg);
- goto error;
- }
- cri = cri->cri_next;
- count++;
- }
-
- if((encrypt > 2) || (auth > 2)) {
- printk("%s,%d: session mode is not supported.\n", __FILE__, __LINE__);
- goto error;
- }
- /* create new sessions in HAL */
- if(encrypt) {
- cesa_ses->operation = MV_CESA_CRYPTO_ONLY;
- /* encrypt session */
- if(auth == 1) {
- cesa_ses->operation = MV_CESA_MAC_THEN_CRYPTO;
- }
- else if(auth == 2) {
- cesa_ses->operation = MV_CESA_CRYPTO_THEN_MAC;
- cesa_ocf_cur_ses->encrypt_tn_auth = 1;
- }
- else {
- cesa_ses->operation = MV_CESA_CRYPTO_ONLY;
- }
- cesa_ses->direction = MV_CESA_DIR_ENCODE;
- status = mvCesaSessionOpen(cesa_ses, &cesa_ocf_cur_ses->sid_encrypt);
- if(status != MV_OK) {
- printk("%s,%d: Can't open new session - status = 0x%x\n", __FILE__, __LINE__, status);
- goto error;
- }
- /* decrypt session */
- if( cesa_ses->operation == MV_CESA_MAC_THEN_CRYPTO ) {
- cesa_ses->operation = MV_CESA_CRYPTO_THEN_MAC;
- }
- else if( cesa_ses->operation == MV_CESA_CRYPTO_THEN_MAC ) {
- cesa_ses->operation = MV_CESA_MAC_THEN_CRYPTO;
- }
- cesa_ses->direction = MV_CESA_DIR_DECODE;
- status = mvCesaSessionOpen(cesa_ses, &cesa_ocf_cur_ses->sid_decrypt);
- if(status != MV_OK) {
- printk("%s,%d: Can't open new session - status = 0x%x\n", __FILE__, __LINE__, status);
- goto error;
- }
-
- /* preapre one action sessions for case we will need to split an action */
-#ifdef CESA_OCF_SPLIT
- if(( cesa_ses->operation == MV_CESA_MAC_THEN_CRYPTO ) ||
- ( cesa_ses->operation == MV_CESA_CRYPTO_THEN_MAC )) {
- /* open one session for encode and one for decode */
- cesa_ses->operation = MV_CESA_CRYPTO_ONLY;
- cesa_ses->direction = MV_CESA_DIR_ENCODE;
- status = mvCesaSessionOpen(cesa_ses, &cesa_ocf_cur_ses->frag_wa_encrypt);
- if(status != MV_OK) {
- printk("%s,%d: Can't open new session - status = 0x%x\n", __FILE__, __LINE__, status);
- goto error;
- }
-
- cesa_ses->direction = MV_CESA_DIR_DECODE;
- status = mvCesaSessionOpen(cesa_ses, &cesa_ocf_cur_ses->frag_wa_decrypt);
- if(status != MV_OK) {
- printk("%s,%d: Can't open new session - status = 0x%x\n", __FILE__, __LINE__, status);
- goto error;
- }
- /* open one session for auth */
- cesa_ses->operation = MV_CESA_MAC_ONLY;
- cesa_ses->direction = MV_CESA_DIR_ENCODE;
- status = mvCesaSessionOpen(cesa_ses, &cesa_ocf_cur_ses->frag_wa_auth);
- if(status != MV_OK) {
- printk("%s,%d: Can't open new session - status = 0x%x\n", __FILE__, __LINE__, status);
- goto error;
- }
- }
-#endif
- }
- else { /* only auth */
- cesa_ses->operation = MV_CESA_MAC_ONLY;
- cesa_ses->direction = MV_CESA_DIR_ENCODE;
- status = mvCesaSessionOpen(cesa_ses, &cesa_ocf_cur_ses->sid_encrypt);
- if(status != MV_OK) {
- printk("%s,%d: Can't open new session - status = 0x%x\n", __FILE__, __LINE__, status);
- goto error;
- }
- }
-
- return 0;
-error:
- cesa_ocf_freesession(NULL, *sid);
- return EINVAL;
-
-}
-
-
-/*
- * Free a session.
- */
-static int
-cesa_ocf_freesession(device_t dev, u_int64_t tid)
-{
- struct cesa_ocf_data *cesa_ocf_cur_ses;
- u_int32_t sid = CRYPTO_SESID2LID(tid);
- //unsigned long flags;
-
- dprintk("%s() %d \n", __FUNCTION__, sid);
- if ( (sid >= CESA_OCF_MAX_SES) || (cesa_ocf_sessions[sid] == NULL) ) {
- printk("%s,%d: EINVAL can't free session %d \n", __FILE__, __LINE__, sid);
- return(EINVAL);
- }
-
- /* Silently accept and return */
- if (sid == 0)
- return(0);
-
- /* release session from HAL */
- cesa_ocf_cur_ses = cesa_ocf_sessions[sid];
- if (cesa_ocf_cur_ses->sid_encrypt != -1) {
- mvCesaSessionClose(cesa_ocf_cur_ses->sid_encrypt);
- }
- if (cesa_ocf_cur_ses->sid_decrypt != -1) {
- mvCesaSessionClose(cesa_ocf_cur_ses->sid_decrypt);
- }
- if (cesa_ocf_cur_ses->frag_wa_encrypt != -1) {
- mvCesaSessionClose(cesa_ocf_cur_ses->frag_wa_encrypt);
- }
- if (cesa_ocf_cur_ses->frag_wa_decrypt != -1) {
- mvCesaSessionClose(cesa_ocf_cur_ses->frag_wa_decrypt);
- }
- if (cesa_ocf_cur_ses->frag_wa_auth != -1) {
- mvCesaSessionClose(cesa_ocf_cur_ses->frag_wa_auth);
- }
-
- kfree(cesa_ocf_cur_ses);
- cesa_ocf_sessions[sid] = NULL;
-
- return 0;
-}
-
-
-/* TDMA Window setup */
-
-static void __init
-setup_tdma_mbus_windows(struct cesa_dev *dev)
-{
- int i;
-
- for (i = 0; i < 4; i++) {
- writel(0, dev->reg + WINDOW_BASE(i));
- writel(0, dev->reg + WINDOW_CTRL(i));
- }
-
- for (i = 0; i < dev->plat_data->dram->num_cs; i++) {
- struct mbus_dram_window *cs = dev->plat_data->dram->cs + i;
- writel(
- ((cs->size - 1) & 0xffff0000) |
- (cs->mbus_attr << 8) |
- (dev->plat_data->dram->mbus_dram_target_id << 4) | 1,
- dev->reg + WINDOW_CTRL(i)
- );
- writel(cs->base, dev->reg + WINDOW_BASE(i));
- }
-}
-
-/*
- * our driver startup and shutdown routines
- */
-static int
-mv_cesa_ocf_init(struct platform_device *pdev)
-{
-#if defined(CONFIG_MV78200) || defined(CONFIG_MV632X)
- if (MV_FALSE == mvSocUnitIsMappedToThisCpu(CESA))
- {
- dprintk("CESA is not mapped to this CPU\n");
- return -ENODEV;
- }
-#endif
-
- dprintk("%s\n", __FUNCTION__);
- memset(&mv_cesa_dev, 0, sizeof(mv_cesa_dev));
- softc_device_init(&mv_cesa_dev, "MV CESA", 0, mv_cesa_methods);
- cesa_ocf_id = crypto_get_driverid(softc_get_device(&mv_cesa_dev),CRYPTOCAP_F_HARDWARE);
-
- if (cesa_ocf_id < 0)
- panic("MV CESA crypto device cannot initialize!");
-
- dprintk("%s,%d: cesa ocf device id is %d \n", __FILE__, __LINE__, cesa_ocf_id);
-
- /* CESA unit is auto power on off */
-#if 0
- if (MV_FALSE == mvCtrlPwrClckGet(CESA_UNIT_ID,0))
- {
- printk("\nWarning CESA %d is Powered Off\n",0);
- return EINVAL;
- }
-#endif
-
- memset(&cesa_device, 0, sizeof(struct cesa_dev));
- /* Get the IRQ, and crypto memory regions */
- {
- struct resource *res;
- res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "sram");
-
- if (!res)
- return -ENXIO;
-
- cesa_device.sram = ioremap(res->start, res->end - res->start + 1);
- res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "regs");
-
- if (!res) {
- iounmap(cesa_device.sram);
- return -ENXIO;
- }
- cesa_device.reg = ioremap(res->start, res->end - res->start + 1);
- cesa_device.irq = platform_get_irq(pdev, 0);
- cesa_device.plat_data = pdev->dev.platform_data;
- setup_tdma_mbus_windows(&cesa_device);
-
- }
-
-
- if( MV_OK != mvCesaInit(CESA_OCF_MAX_SES*5, CESA_Q_SIZE, cesa_device.reg,
- NULL) ) {
- printk("%s,%d: mvCesaInit Failed. \n", __FILE__, __LINE__);
- return EINVAL;
- }
-
- /* clear and unmask Int */
- MV_REG_WRITE( MV_CESA_ISR_CAUSE_REG, 0);
-#ifndef CESA_OCF_POLLING
- MV_REG_WRITE( MV_CESA_ISR_MASK_REG, MV_CESA_CAUSE_ACC_DMA_MASK);
-#endif
-#ifdef CESA_OCF_TASKLET
- tasklet_init(&cesa_ocf_tasklet, cesa_callback, (unsigned int) 0);
-#endif
- /* register interrupt */
- if( request_irq( cesa_device.irq, cesa_interrupt_handler,
- (IRQF_DISABLED) , "cesa", &cesa_ocf_id) < 0) {
- printk("%s,%d: cannot assign irq %x\n", __FILE__, __LINE__, cesa_device.reg);
- return EINVAL;
- }
-
-
- memset(cesa_ocf_sessions, 0, sizeof(struct cesa_ocf_data *) * CESA_OCF_MAX_SES);
-
-#define REGISTER(alg) \
- crypto_register(cesa_ocf_id, alg, 0,0)
- REGISTER(CRYPTO_AES_CBC);
- REGISTER(CRYPTO_DES_CBC);
- REGISTER(CRYPTO_3DES_CBC);
- REGISTER(CRYPTO_MD5);
- REGISTER(CRYPTO_MD5_HMAC);
- REGISTER(CRYPTO_SHA1);
- REGISTER(CRYPTO_SHA1_HMAC);
-#undef REGISTER
-
- return 0;
-}
-
-static void
-mv_cesa_ocf_exit(struct platform_device *pdev)
-{
- dprintk("%s()\n", __FUNCTION__);
-
- crypto_unregister_all(cesa_ocf_id);
- cesa_ocf_id = -1;
- iounmap(cesa_device.reg);
- iounmap(cesa_device.sram);
- free_irq(cesa_device.irq, NULL);
-
- /* mask and clear Int */
- MV_REG_WRITE( MV_CESA_ISR_MASK_REG, 0);
- MV_REG_WRITE( MV_CESA_ISR_CAUSE_REG, 0);
-
-
- if( MV_OK != mvCesaFinish() ) {
- printk("%s,%d: mvCesaFinish Failed. \n", __FILE__, __LINE__);
- return;
- }
-}
-
-
-void cesa_ocf_debug(void)
-{
-
-#ifdef CESA_OCF_TRACE_DEBUG
- {
- int i, j;
- j = cesaTestTraceIdx;
- mvOsPrintf("No Type rCause iCause Proc Isr Res Time pReady pProc pEmpty\n");
- for(i=0; i<MV_CESA_TEST_TRACE_SIZE; i++)
- {
- mvOsPrintf("%02d. %d 0x%04x 0x%04x 0x%02x 0x%02x %02d 0x%06x %p %p %p\n",
- j, cesaTestTrace[j].type, cesaTestTrace[j].realCause,
- cesaTestTrace[j].idmaCause,
- cesaTestTrace[j].resources, cesaTestTrace[j].timeStamp,
- cesaTestTrace[j].pReqReady, cesaTestTrace[j].pReqProcess, cesaTestTrace[j].pReqEmpty);
- j++;
- if(j == MV_CESA_TEST_TRACE_SIZE)
- j = 0;
- }
- }
-#endif
-
-}
-
-static struct platform_driver marvell_cesa = {
- .probe = mv_cesa_ocf_init,
- .remove = mv_cesa_ocf_exit,
- .driver = {
- .owner = THIS_MODULE,
- .name = "mv_crypto",
- },
-};
-
-MODULE_ALIAS("platform:mv_crypto");
-
-static int __init mv_cesa_init(void)
-{
- return platform_driver_register(&marvell_cesa);
-}
-
-module_init(mv_cesa_init);
-
-static void __exit mv_cesa_exit(void)
-{
- platform_driver_unregister(&marvell_cesa);
-}
-
-module_exit(mv_cesa_exit);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Ronen Shitrit");
-MODULE_DESCRIPTION("OCF module for Orion CESA crypto");