aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/lantiq/patches/270-crypto.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/lantiq/patches/270-crypto.patch')
-rw-r--r--target/linux/lantiq/patches/270-crypto.patch6197
1 files changed, 0 insertions, 6197 deletions
diff --git a/target/linux/lantiq/patches/270-crypto.patch b/target/linux/lantiq/patches/270-crypto.patch
deleted file mode 100644
index e99cfd381c..0000000000
--- a/target/linux/lantiq/patches/270-crypto.patch
+++ /dev/null
@@ -1,6197 +0,0 @@
---- a/drivers/crypto/Kconfig
-+++ b/drivers/crypto/Kconfig
-@@ -252,4 +252,75 @@
- OMAP processors have AES module accelerator. Select this if you
- want to use the OMAP module for AES algorithms.
-
-+config CRYPTO_DEV_LANTIQ
-+ tristate "Support for Lantiq crypto engine"
-+ select CRYPTO_ALGAPI
-+ default y
-+ help
-+ Will support Lantiq crypto hardware
-+ If you are unsure, say M.
-+
-+menuconfig CRYPTO_DEV_LANTIQ_DES
-+ bool "Lantiq crypto hardware for DES algorithm"
-+ depends on CRYPTO_DEV_LANTIQ
-+ select CRYPTO_BLKCIPHER
-+ default y
-+ help
-+ Use crypto hardware for DES/3DES algorithm.
-+ If unsure say N.
-+
-+menuconfig CRYPTO_DEV_LANTIQ_AES
-+ bool "Lantiq crypto hardware for AES algorithm"
-+ depends on CRYPTO_DEV_LANTIQ
-+ select CRYPTO_BLKCIPHER
-+ default y
-+ help
-+ Use crypto hardware for AES algorithm.
-+ If unsure say N.
-+
-+menuconfig CRYPTO_DEV_LANTIQ_ARC4
-+ bool "Lantiq crypto hardware for ARC4 algorithm"
-+ depends on (CRYPTO_DEV_LANTIQ && IFXMIPS_AR9)
-+ select CRYPTO_BLKCIPHER
-+ default y
-+ help
-+ Use crypto hardware for ARC4 algorithm.
-+ If unsure say N.
-+
-+menuconfig CRYPTO_DEV_LANTIQ_MD5
-+ bool "Lantiq crypto hardware for MD5 algorithm"
-+ depends on CRYPTO_DEV_LANTIQ
-+ select CRYPTO_BLKCIPHER
-+ default y
-+ help
-+ Use crypto hardware for MD5 algorithm.
-+ If unsure say N.
-+
-+menuconfig CRYPTO_DEV_LANTIQ_SHA1
-+ bool "Lantiq crypto hardware for SHA1 algorithm"
-+ depends on CRYPTO_DEV_LANTIQ
-+ select CRYPTO_BLKCIPHER
-+ default y
-+ help
-+ Use crypto hardware for SHA1 algorithm.
-+ If unsure say N.
-+
-+menuconfig CRYPTO_DEV_LANTIQ_SHA1_HMAC
-+ bool "Lantiq crypto hardware for SHA1_HMAC algorithm"
-+ depends on (CRYPTO_DEV_LANTIQ && IFXMIPS_AR9)
-+ select CRYPTO_BLKCIPHER
-+ default y
-+ help
-+ Use crypto hardware for SHA1_HMAC algorithm.
-+ If unsure say N.
-+
-+menuconfig CRYPTO_DEV_LANTIQ_MD5_HMAC
-+ bool "Lantiq crypto hardware for MD5_HMAC algorithms"
-+ depends on (CRYPTO_DEV_LANTIQ && IFXMIPS_AR9)
-+ select CRYPTO_BLKCIPHER
-+ default y
-+ help
-+ Use crypto hardware for MD5_HMAC algorithm.
-+ If unsure say N.
-+
- endif # CRYPTO_HW
---- /dev/null
-+++ b/drivers/crypto/lantiq/Makefile
-@@ -0,0 +1,11 @@
-+obj-$(CONFIG_CRYPTO_DEV_LANTIQ) += deu.o
-+obj-$(CONFIG_CRYPTO_DEV_LANTIQ) += deu_falcon.o
-+obj-$(CONFIG_CRYPTO_DEV_LANTIQ) += deu_danube.o
-+obj-$(CONFIG_CRYPTO_DEV_LANTIQ) += deu_ar9.o
-+obj-$(CONFIG_CRYPTO_DEV_LANTIQ_DES) += des.o
-+obj-$(CONFIG_CRYPTO_DEV_LANTIQ_AES) += aes.o
-+obj-$(CONFIG_CRYPTO_DEV_LANTIQ_ARC4) += arc4.o
-+obj-$(CONFIG_CRYPTO_DEV_LANTIQ_SHA1) += sha1.o
-+obj-$(CONFIG_CRYPTO_DEV_LANTIQ_SHA1_HMAC) += sha1_hmac.o
-+obj-$(CONFIG_CRYPTO_DEV_LANTIQ_MD5) += md5.o
-+obj-$(CONFIG_CRYPTO_DEV_LANTIQ_MD5_HMAC) += md5_hmac.o
---- /dev/null
-+++ b/drivers/crypto/lantiq/aes.c
-@@ -0,0 +1,1029 @@
-+/*
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
-+ *
-+ * Copyright (C) 2010 Ralph Hempel <ralph.hempel@lantiq.com>
-+ * Copyright (C) 2009 Mohammad Firdaus
-+ */
-+
-+/**
-+ \defgroup LQ_DEU LQ_DEU_DRIVERS
-+ \ingroup API
-+ \brief Lantiq DEU driver module
-+*/
-+
-+/**
-+ \file aes.c
-+ \ingroup LQ_DEU
-+ \brief AES Encryption Driver main file
-+*/
-+
-+/**
-+ \defgroup LQ_AES_FUNCTIONS LQ_AES_FUNCTIONS
-+ \ingroup LQ_DEU
-+ \brief Lantiq AES driver Functions
-+*/
-+
-+#include <linux/version.h>
-+#include <linux/module.h>
-+#include <linux/init.h>
-+#include <linux/types.h>
-+#include <linux/errno.h>
-+#include <linux/crypto.h>
-+#include <linux/interrupt.h>
-+#include <linux/delay.h>
-+#include <asm/byteorder.h>
-+#include <crypto/algapi.h>
-+#include "deu.h"
-+
-+#ifdef CONFIG_CRYPTO_DEV_DMA
-+# include "deu_dma.h"
-+#endif
-+
-+static spinlock_t cipher_lock;
-+
-+/* Definition of constants */
-+
-+#define AES_MIN_KEY_SIZE 16
-+#define AES_MAX_KEY_SIZE 32
-+#define AES_BLOCK_SIZE 16
-+#define CTR_RFC3686_NONCE_SIZE 4
-+#define CTR_RFC3686_IV_SIZE 8
-+#define CTR_RFC3686_MAX_KEY_SIZE (AES_MAX_KEY_SIZE \
-+ + CTR_RFC3686_NONCE_SIZE)
-+
-+struct aes_ctx {
-+ int key_length;
-+ u32 buf[AES_MAX_KEY_SIZE];
-+ u8 nonce[CTR_RFC3686_NONCE_SIZE];
-+};
-+
-+/** \fn int aes_set_key(struct crypto_tfm *tfm, const uint8_t *in_key, unsigned int key_len)
-+ * \ingroup LQ_AES_FUNCTIONS
-+ * \brief sets the AES keys
-+ * \param tfm linux crypto algo transform
-+ * \param in_key input key
-+ * \param key_len key lengths of 16, 24 and 32 bytes supported
-+ * \return -EINVAL - bad key length, 0 - SUCCESS
-+*/
-+static int aes_set_key(struct crypto_tfm *tfm,
-+ const u8 *in_key,
-+ unsigned int key_len)
-+{
-+ struct aes_ctx *ctx = crypto_tfm_ctx(tfm);
-+ u32 *flags = &tfm->crt_flags;
-+
-+ DPRINTF(0, "ctx @%p, key_len %d\n", ctx, key_len);
-+
-+ if (key_len != 16 && key_len != 24 && key_len != 32) {
-+ *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
-+ return -EINVAL;
-+ }
-+
-+ ctx->key_length = key_len;
-+ memcpy((u8 *)(ctx->buf), in_key, key_len);
-+
-+ return 0;
-+}
-+
-+#ifndef CONFIG_CRYPTO_DEV_DMA
-+/** \fn void deu_aes(void *ctx_arg, u8 *out_arg, const u8 *in_arg, u8 *iv_arg, size_t nbytes, int encdec, int mode)
-+ * \ingroup LQ_AES_FUNCTIONS
-+ * \brief main interface to AES hardware
-+ * \param ctx_arg crypto algo context
-+ * \param out_arg output bytestream
-+ * \param in_arg input bytestream
-+ * \param iv_arg initialization vector
-+ * \param nbytes length of bytestream
-+ * \param encdec 1 for encrypt; 0 for decrypt
-+ * \param mode operation mode such as ebc, cbc, ctr
-+ *
-+*/
-+static void deu_aes(void *ctx_arg,
-+ u8 *out_arg,
-+ const u8 *in_arg,
-+ u8 *iv_arg,
-+ size_t nbytes,
-+ int encdec,
-+ int mode)
-+#else
-+
-+/** \fn void deu_aes_core(void *ctx_arg, u8 *out_arg, const u8 *in_arg, u8 *iv_arg, size_t nbytes, int encdec, int mode)
-+ * \ingroup LQ_AES_FUNCTIONS
-+ * \brief main interface to AES hardware
-+ * \param ctx_arg crypto algo context
-+ * \param out_arg output bytestream
-+ * \param in_arg input bytestream
-+ * \param iv_arg initialization vector
-+ * \param nbytes length of bytestream
-+ * \param encdec 1 for encrypt; 0 for decrypt
-+ * \param mode operation mode such as ebc, cbc, ctr
-+ *
-+*/
-+static void deu_aes_core(void *ctx_arg,
-+ u8 *out_arg,
-+ const u8 *in_arg,
-+ u8 *iv_arg,
-+ size_t nbytes,
-+ int encdec,
-+ int mode)
-+#endif
-+
-+{
-+ /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
-+ volatile struct deu_aes *aes = (volatile struct deu_aes *)AES_START;
-+ struct aes_ctx *ctx = (struct aes_ctx *)ctx_arg;
-+ u32 *in_key = ctx->buf;
-+ ulong flag;
-+ /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
-+ int key_len = ctx->key_length;
-+
-+#ifndef CONFIG_CRYPTO_DEV_DMA
-+ int i = 0;
-+ int byte_cnt = nbytes;
-+#else
-+ volatile struct deu_dma *dma = (struct deu_dma *)LQ_DEU_DMA_CON;
-+ struct dma_device_info *dma_device = lq_deu[0].dma_device;
-+ /* struct deu_drv_priv *deu_priv =
-+ * (struct deu_drv_priv *)dma_device->priv; */
-+ int wlen = 0;
-+ u32 *outcopy = NULL;
-+ u32 *dword_mem_aligned_in = NULL;
-+
-+# ifdef CONFIG_CRYPTO_DEV_POLL_DMA
-+ u32 timeout = 0;
-+ u32 *out_dma = NULL;
-+# endif
-+#endif
-+
-+ DPRINTF(0, "ctx @%p, mode %d, encdec %d\n", ctx, mode, encdec);
-+
-+ CRTCL_SECT_START;
-+
-+ /* 128, 192 or 256 bit key length */
-+ aes->ctrl.K = key_len / 8 - 2;
-+ if (key_len == 128 / 8) {
-+ aes->K3R = DEU_ENDIAN_SWAP(*((u32 *)in_key + 0));
-+ aes->K2R = DEU_ENDIAN_SWAP(*((u32 *)in_key + 1));
-+ aes->K1R = DEU_ENDIAN_SWAP(*((u32 *)in_key + 2));
-+ aes->K0R = DEU_ENDIAN_SWAP(*((u32 *)in_key + 3));
-+ }
-+ else if (key_len == 192 / 8) {
-+ aes->K5R = DEU_ENDIAN_SWAP(*((u32 *)in_key + 0));
-+ aes->K4R = DEU_ENDIAN_SWAP(*((u32 *)in_key + 1));
-+ aes->K3R = DEU_ENDIAN_SWAP(*((u32 *)in_key + 2));
-+ aes->K2R = DEU_ENDIAN_SWAP(*((u32 *)in_key + 3));
-+ aes->K1R = DEU_ENDIAN_SWAP(*((u32 *)in_key + 4));
-+ aes->K0R = DEU_ENDIAN_SWAP(*((u32 *)in_key + 5));
-+ }
-+ else if (key_len == 256 / 8) {
-+ aes->K7R = DEU_ENDIAN_SWAP(*((u32 *)in_key + 0));
-+ aes->K6R = DEU_ENDIAN_SWAP(*((u32 *)in_key + 1));
-+ aes->K5R = DEU_ENDIAN_SWAP(*((u32 *)in_key + 2));
-+ aes->K4R = DEU_ENDIAN_SWAP(*((u32 *)in_key + 3));
-+ aes->K3R = DEU_ENDIAN_SWAP(*((u32 *)in_key + 4));
-+ aes->K2R = DEU_ENDIAN_SWAP(*((u32 *)in_key + 5));
-+ aes->K1R = DEU_ENDIAN_SWAP(*((u32 *)in_key + 6));
-+ aes->K0R = DEU_ENDIAN_SWAP(*((u32 *)in_key + 7));
-+ }
-+ else {
-+ CRTCL_SECT_END;
-+ return; /* -EINVAL; */
-+ }
-+
-+ /* let HW pre-process DEcryption key in any case (even if
-+ ENcryption is used). Key Valid (KV) bit is then only
-+ checked in decryption routine! */
-+ aes->ctrl.PNK = 1;
-+
-+#ifdef CONFIG_CRYPTO_DEV_DMA
-+ while (aes->ctrl.BUS) {
-+ /* this will not take long */
-+ }
-+ AES_DMA_MISC_CONFIG();
-+#endif
-+
-+ aes->ctrl.E_D = !encdec; /* encryption */
-+ aes->ctrl.O = mode; /* 0 ECB 1 CBC 2 OFB 3 CFB 4 CTR */
-+ aes->ctrl.SM = 1; /* start after writing input register */
-+ aes->ctrl.DAU = 0; /* Disable Automatic Update of init
-+ vector */
-+ aes->ctrl.ARS = 1; /* Autostart Select - write to IHR */
-+
-+ /* aes->ctrl.F = 128; */ /* default; only for CFB and OFB modes;
-+ change only for
-+ customer-specific apps */
-+ if (mode > 0) {
-+ aes->IV3R = DEU_ENDIAN_SWAP(*(u32 *)iv_arg);
-+ aes->IV2R = DEU_ENDIAN_SWAP(*((u32 *)iv_arg + 1));
-+ aes->IV1R = DEU_ENDIAN_SWAP(*((u32 *)iv_arg + 2));
-+ aes->IV0R = DEU_ENDIAN_SWAP(*((u32 *)iv_arg + 3));
-+ };
-+
-+#ifndef CONFIG_CRYPTO_DEV_DMA
-+ i = 0;
-+ while (byte_cnt >= 16) {
-+ aes->ID3R = INPUT_ENDIAN_SWAP(*((u32 *)in_arg + (i * 4) + 0));
-+ aes->ID2R = INPUT_ENDIAN_SWAP(*((u32 *)in_arg + (i * 4) + 1));
-+ aes->ID1R = INPUT_ENDIAN_SWAP(*((u32 *)in_arg + (i * 4) + 2));
-+ /* start crypto */
-+ aes->ID0R = INPUT_ENDIAN_SWAP(*((u32 *)in_arg + (i * 4) + 3));
-+
-+ while (aes->ctrl.BUS) {
-+ /* this will not take long */
-+ }
-+
-+ *((volatile u32 *)out_arg + (i * 4) + 0) = aes->OD3R;
-+ *((volatile u32 *)out_arg + (i * 4) + 1) = aes->OD2R;
-+ *((volatile u32 *)out_arg + (i * 4) + 2) = aes->OD1R;
-+ *((volatile u32 *)out_arg + (i * 4) + 3) = aes->OD0R;
-+
-+ i++;
-+ byte_cnt -= 16;
-+ }
-+#else /* dma */
-+ /* Prepare Rx buf length used in dma psuedo interrupt */
-+ /* deu_priv->deu_rx_buf = out_arg; */
-+ /* deu_priv->deu_rx_len = nbytes; */
-+
-+ /* memory alignment issue */
-+ dword_mem_aligned_in = (u32 *)DEU_DWORD_REORDERING(in_arg,
-+ aes_buff_in,
-+ BUFFER_IN, nbytes);
-+
-+ dma->ctrl.ALGO = 1; /* AES */
-+ dma->ctrl.BS = 0;
-+ aes->ctrl.DAU = 0;
-+ dma->ctrl.EN = 1;
-+
-+ while (aes->ctrl.BUS) {
-+ /* wait for AES to be ready */
-+ };
-+
-+ wlen = dma_device_write(dma_device, (u8 *)dword_mem_aligned_in,
-+ nbytes, NULL);
-+ if (wlen != nbytes) {
-+ dma->ctrl.EN = 0;
-+ CRTCL_SECT_END;
-+ printk(KERN_ERR "[%s %s %d]: dma_device_write fail!\n",
-+ __FILE__, __func__, __LINE__);
-+ return; /* -EINVAL; */
-+ }
-+
-+ WAIT_AES_DMA_READY();
-+
-+# ifdef CONFIG_CRYPTO_DEV_POLL_DMA
-+ outcopy = (u32 *)DEU_DWORD_REORDERING(out_arg, aes_buff_out,
-+ BUFFER_OUT, nbytes);
-+
-+ /* polling DMA rx channel */
-+ while ((dma_device_read(dma_device, (u8 **)&out_dma, NULL)) == 0) {
-+ timeout++;
-+
-+ if (timeout >= 333000) {
-+ dma->ctrl.EN = 0;
-+ CRTCL_SECT_END;
-+ printk (KERN_ERR "[%s %s %d]: timeout!!\n",
-+ __FILE__, __func__, __LINE__);
-+ return; /* -EINVAL; */
-+ }
-+ }
-+
-+ WAIT_AES_DMA_READY();
-+
-+ AES_MEMORY_COPY(outcopy, out_dma, out_arg, nbytes);
-+
-+# else /* not working at the moment.. */
-+ CRTCL_SECT_END;
-+
-+ /* sleep and wait for Rx finished */
-+ DEU_WAIT_EVENT(deu_priv->deu_thread_wait, DEU_EVENT,
-+ deu_priv->deu_event_flags);
-+
-+ CRTCL_SECT_START;
-+# endif
-+
-+#endif /* dma */
-+
-+ /* tc.chen : copy iv_arg back */
-+ if (mode > 0) {
-+ *((u32 *)iv_arg) = DEU_ENDIAN_SWAP(*((u32 *)iv_arg));
-+ *((u32 *)iv_arg + 1) = DEU_ENDIAN_SWAP(*((u32 *)iv_arg + 1));
-+ *((u32 *)iv_arg + 2) = DEU_ENDIAN_SWAP(*((u32 *)iv_arg + 2));
-+ *((u32 *)iv_arg + 3) = DEU_ENDIAN_SWAP(*((u32 *)iv_arg + 3));
-+ }
-+
-+ CRTCL_SECT_END;
-+}
-+
-+/** \fn int ctr_rfc3686_aes_set_key(struct crypto_tfm *tfm, const uint8_t *in_key, unsigned int key_len)
-+ * \ingroup LQ_AES_FUNCTIONS
-+ * \brief sets RFC3686 key
-+ * \param tfm linux crypto algo transform
-+ * \param in_key input key
-+ * \param key_len key lengths of 20, 28 and 36 bytes supported; last 4 bytes is nonce
-+ * \return 0 - SUCCESS
-+ * -EINVAL - bad key length
-+*/
-+static int ctr_rfc3686_aes_set_key(struct crypto_tfm *tfm,
-+ const uint8_t *in_key,
-+ unsigned int key_len)
-+{
-+ struct aes_ctx *ctx = crypto_tfm_ctx(tfm);
-+ u32 *flags = &tfm->crt_flags;
-+
-+ memcpy(ctx->nonce, in_key + (key_len - CTR_RFC3686_NONCE_SIZE),
-+ CTR_RFC3686_NONCE_SIZE);
-+
-+ key_len -= CTR_RFC3686_NONCE_SIZE; /* remove 4 bytes of nonce */
-+
-+ if (key_len != 16 && key_len != 24 && key_len != 32) {
-+ *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
-+ return -EINVAL;
-+ }
-+
-+ ctx->key_length = key_len;
-+
-+ memcpy((u8 *)(ctx->buf), in_key, key_len);
-+
-+ return 0;
-+}
-+
-+/** \fn void deu_aes(void *ctx_arg, u8 *out_arg, const u8 *in_arg, u8 *iv_arg, u32 nbytes, int encdec, int mode)
-+ * \ingroup LQ_AES_FUNCTIONS
-+ * \brief main interface with DEU hardware in DMA mode
-+ * \param ctx_arg crypto algo context
-+ * \param out_arg output bytestream
-+ * \param in_arg input bytestream
-+ * \param iv_arg initialization vector
-+ * \param nbytes length of bytestream
-+ * \param encdec 1 for encrypt; 0 for decrypt
-+ * \param mode operation mode such as ebc, cbc, ctr
-+*/
-+
-+#ifdef CONFIG_CRYPTO_DEV_DMA
-+static void deu_aes(void *ctx_arg,
-+ u8 *out_arg,
-+ const u8 *in_arg,
-+ u8 *iv_arg,
-+ u32 nbytes,
-+ int encdec,
-+ int mode)
-+{
-+ u32 remain = nbytes;
-+ u32 inc;
-+
-+ while (remain > 0) {
-+ if (remain >= DEU_MAX_PACKET_SIZE)
-+ inc = DEU_MAX_PACKET_SIZE;
-+ else
-+ inc = remain;
-+
-+ remain -= inc;
-+
-+ deu_aes_core(ctx_arg, out_arg, in_arg, iv_arg, inc, encdec,
-+ mode);
-+
-+ out_arg += inc;
-+ in_arg += inc;
-+ }
-+}
-+#endif
-+
-+/* definitions from linux/include/crypto.h:
-+#define CRYPTO_TFM_MODE_ECB 0x00000001
-+#define CRYPTO_TFM_MODE_CBC 0x00000002
-+#define CRYPTO_TFM_MODE_CFB 0x00000004
-+#define CRYPTO_TFM_MODE_CTR 0x00000008
-+#define CRYPTO_TFM_MODE_OFB 0x00000010
-+but hardware definition: 0 ECB 1 CBC 2 OFB 3 CFB 4 CTR */
-+
-+/** \fn void deu_aes_ecb(void *ctx, uint8_t *dst, const uint8_t *src, uint8_t *iv, size_t nbytes, int encdec, int inplace)
-+ * \ingroup LQ_AES_FUNCTIONS
-+ * \brief sets AES hardware to ECB mode
-+ * \param ctx crypto algo context
-+ * \param dst output bytestream
-+ * \param src input bytestream
-+ * \param iv initialization vector
-+ * \param nbytes length of bytestream
-+ * \param encdec 1 for encrypt; 0 for decrypt
-+ * \param inplace not used
-+*/
-+static void deu_aes_ecb(void *ctx,
-+ uint8_t *dst,
-+ const uint8_t *src,
-+ uint8_t *iv,
-+ size_t nbytes,
-+ int encdec,
-+ int inplace)
-+{
-+ deu_aes(ctx, dst, src, NULL, nbytes, encdec, 0);
-+}
-+
-+/** \fn void deu_aes_cbc(void *ctx, uint8_t *dst, const uint8_t *src, uint8_t *iv, size_t nbytes, int encdec, int inplace)
-+ * \ingroup LQ_AES_FUNCTIONS
-+ * \brief sets AES hardware to CBC mode
-+ * \param ctx crypto algo context
-+ * \param dst output bytestream
-+ * \param src input bytestream
-+ * \param iv initialization vector
-+ * \param nbytes length of bytestream
-+ * \param encdec 1 for encrypt; 0 for decrypt
-+ * \param inplace not used
-+*/
-+static void deu_aes_cbc(void *ctx,
-+ uint8_t *dst,
-+ const uint8_t *src,
-+ uint8_t *iv,
-+ size_t nbytes,
-+ int encdec,
-+ int inplace)
-+{
-+ deu_aes(ctx, dst, src, iv, nbytes, encdec, 1);
-+}
-+
-+#if 0
-+/** \fn void deu_aes_ofb(void *ctx, uint8_t *dst, const uint8_t *src, uint8_t *iv, size_t nbytes, int encdec, int inplace)
-+ * \ingroup LQ_AES_FUNCTIONS
-+ * \brief sets AES hardware to OFB mode
-+ * \param ctx crypto algo context
-+ * \param dst output bytestream
-+ * \param src input bytestream
-+ * \param iv initialization vector
-+ * \param nbytes length of bytestream
-+ * \param encdec 1 for encrypt; 0 for decrypt
-+ * \param inplace not used
-+*/
-+static void deu_aes_ofb(void *ctx,
-+ uint8_t *dst,
-+ const uint8_t *src,
-+ uint8_t *iv,
-+ size_t nbytes,
-+ int encdec,
-+ int inplace)
-+{
-+ deu_aes(ctx, dst, src, iv, nbytes, encdec, 2);
-+}
-+
-+/** \fn void deu_aes_cfb(void *ctx, uint8_t *dst, const uint8_t *src, uint8_t *iv, size_t nbytes, int encdec, int inplace)
-+ * \ingroup LQ_AES_FUNCTIONS
-+ * \brief sets AES hardware to CFB mode
-+ * \param ctx crypto algo context
-+ * \param dst output bytestream
-+ * \param src input bytestream
-+ * \param iv initialization vector
-+ * \param nbytes length of bytestream
-+ * \param encdec 1 for encrypt; 0 for decrypt
-+ * \param inplace not used
-+*/
-+static void deu_aes_cfb(void *ctx,
-+ uint8_t *dst,
-+ const uint8_t *src,
-+ uint8_t *iv,
-+ size_t nbytes,
-+ int encdec,
-+ int inplace)
-+{
-+ deu_aes(ctx, dst, src, iv, nbytes, encdec, 3);
-+}
-+#endif
-+
-+/** \fn void deu_aes_ctr(void *ctx, uint8_t *dst, const uint8_t *src, uint8_t *iv, size_t nbytes, int encdec, int inplace)
-+ * \ingroup LQ_AES_FUNCTIONS
-+ * \brief sets AES hardware to CTR mode
-+ * \param ctx crypto algo context
-+ * \param dst output bytestream
-+ * \param src input bytestream
-+ * \param iv initialization vector
-+ * \param nbytes length of bytestream
-+ * \param encdec 1 for encrypt; 0 for decrypt
-+ * \param inplace not used
-+*/
-+static void deu_aes_ctr(void *ctx,
-+ uint8_t *dst,
-+ const uint8_t *src,
-+ uint8_t *iv,
-+ size_t nbytes,
-+ int encdec,
-+ int inplace)
-+{
-+ deu_aes(ctx, dst, src, iv, nbytes, encdec, 4);
-+}
-+
-+/** \fn void aes_encrypt(struct crypto_tfm *tfm, uint8_t *out, const uint8_t *in)
-+ * \ingroup LQ_AES_FUNCTIONS
-+ * \brief encrypt AES_BLOCK_SIZE of data
-+ * \param tfm linux crypto algo transform
-+ * \param out output bytestream
-+ * \param in input bytestream
-+*/
-+static void aes_encrypt(struct crypto_tfm *tfm, uint8_t *out, const uint8_t *in)
-+{
-+ struct aes_ctx *ctx = crypto_tfm_ctx(tfm);
-+ deu_aes(ctx, out, in, NULL, AES_BLOCK_SIZE, CRYPTO_DIR_ENCRYPT, 0);
-+}
-+
-+/** \fn void aes_decrypt(struct crypto_tfm *tfm, uint8_t *out, const uint8_t *in)
-+ * \ingroup LQ_AES_FUNCTIONS
-+ * \brief decrypt AES_BLOCK_SIZE of data
-+ * \param tfm linux crypto algo transform
-+ * \param out output bytestream
-+ * \param in input bytestream
-+*/
-+static void aes_decrypt(struct crypto_tfm *tfm, uint8_t *out, const uint8_t *in)
-+{
-+ struct aes_ctx *ctx = crypto_tfm_ctx(tfm);
-+ deu_aes(ctx, out, in, NULL, AES_BLOCK_SIZE, CRYPTO_DIR_DECRYPT, 0);
-+}
-+
-+/*
-+ * \brief AES function mappings
-+*/
-+static struct crypto_alg aes_alg = {
-+ .cra_name = "aes",
-+ .cra_driver_name = "lq_deu-aes",
-+ .cra_flags = CRYPTO_ALG_TYPE_CIPHER,
-+ .cra_blocksize = AES_BLOCK_SIZE,
-+ .cra_ctxsize = sizeof(struct aes_ctx),
-+ .cra_module = THIS_MODULE,
-+ .cra_list = LIST_HEAD_INIT(aes_alg.cra_list),
-+ .cra_u = {
-+ .cipher = {
-+ .cia_min_keysize = AES_MIN_KEY_SIZE,
-+ .cia_max_keysize = AES_MAX_KEY_SIZE,
-+ .cia_setkey = aes_set_key,
-+ .cia_encrypt = aes_encrypt,
-+ .cia_decrypt = aes_decrypt,
-+ }
-+ }
-+};
-+
-+/** \fn int ecb_aes_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst, struct scatterlist *src, unsigned int nbytes)
-+ * \ingroup LQ_AES_FUNCTIONS
-+ * \brief ECB AES encrypt using linux crypto blkcipher
-+ * \param desc blkcipher descriptor
-+ * \param dst output scatterlist
-+ * \param src input scatterlist
-+ * \param nbytes data size in bytes
-+ * \return err
-+*/
-+static int ecb_aes_encrypt(struct blkcipher_desc *desc,
-+ struct scatterlist *dst,
-+ struct scatterlist *src,
-+ unsigned int nbytes)
-+{
-+ struct aes_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
-+ struct blkcipher_walk walk;
-+ int err;
-+
-+ blkcipher_walk_init(&walk, dst, src, nbytes);
-+ err = blkcipher_walk_virt(desc, &walk);
-+
-+ while ((nbytes = walk.nbytes)) {
-+ nbytes -= (nbytes % AES_BLOCK_SIZE);
-+ deu_aes_ecb(ctx, walk.dst.virt.addr, walk.src.virt.addr,
-+ NULL, nbytes, CRYPTO_DIR_ENCRYPT, 0);
-+ nbytes &= AES_BLOCK_SIZE - 1;
-+ err = blkcipher_walk_done(desc, &walk, nbytes);
-+ }
-+
-+ return err;
-+}
-+
-+/** \fn int ecb_aes_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst, struct scatterlist *src, unsigned int nbytes)
-+ * \ingroup LQ_AES_FUNCTIONS
-+ * \brief ECB AES decrypt using linux crypto blkcipher
-+ * \param desc blkcipher descriptor
-+ * \param dst output scatterlist
-+ * \param src input scatterlist
-+ * \param nbytes data size in bytes
-+ * \return err
-+*/
-+static int ecb_aes_decrypt(struct blkcipher_desc *desc,
-+ struct scatterlist *dst,
-+ struct scatterlist *src,
-+ unsigned int nbytes)
-+{
-+ struct aes_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
-+ struct blkcipher_walk walk;
-+ int err;
-+
-+ blkcipher_walk_init(&walk, dst, src, nbytes);
-+ err = blkcipher_walk_virt(desc, &walk);
-+
-+ while ((nbytes = walk.nbytes)) {
-+ nbytes -= (nbytes % AES_BLOCK_SIZE);
-+ deu_aes_ecb(ctx, walk.dst.virt.addr, walk.src.virt.addr,
-+ NULL, nbytes, CRYPTO_DIR_DECRYPT, 0);
-+ nbytes &= AES_BLOCK_SIZE - 1;
-+ err = blkcipher_walk_done(desc, &walk, nbytes);
-+ }
-+
-+ return err;
-+}
-+
-+/*
-+ * \brief AES function mappings
-+*/
-+static struct crypto_alg ecb_aes_alg = {
-+ .cra_name = "ecb(aes)",
-+ .cra_driver_name = "lq_deu-ecb(aes)",
-+ .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
-+ .cra_blocksize = AES_BLOCK_SIZE,
-+ .cra_ctxsize = sizeof(struct aes_ctx),
-+ .cra_type = &crypto_blkcipher_type,
-+ .cra_module = THIS_MODULE,
-+ .cra_list = LIST_HEAD_INIT(ecb_aes_alg.cra_list),
-+ .cra_u = {
-+ .blkcipher = {
-+ .min_keysize = AES_MIN_KEY_SIZE,
-+ .max_keysize = AES_MAX_KEY_SIZE,
-+ .setkey = aes_set_key,
-+ .encrypt = ecb_aes_encrypt,
-+ .decrypt = ecb_aes_decrypt,
-+ }
-+ }
-+};
-+
-+/** \fn int cbc_aes_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst, struct scatterlist *src, unsigned int nbytes)
-+ * \ingroup LQ_AES_FUNCTIONS
-+ * \brief CBC AES encrypt using linux crypto blkcipher
-+ * \param desc blkcipher descriptor
-+ * \param dst output scatterlist
-+ * \param src input scatterlist
-+ * \param nbytes data size in bytes
-+ * \return err
-+*/
-+static int cbc_aes_encrypt(struct blkcipher_desc *desc,
-+ struct scatterlist *dst,
-+ struct scatterlist *src,
-+ unsigned int nbytes)
-+{
-+ struct aes_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
-+ struct blkcipher_walk walk;
-+ int err;
-+
-+ blkcipher_walk_init(&walk, dst, src, nbytes);
-+ err = blkcipher_walk_virt(desc, &walk);
-+
-+ while ((nbytes = walk.nbytes)) {
-+ u8 *iv = walk.iv;
-+ nbytes -= (nbytes % AES_BLOCK_SIZE);
-+ deu_aes_cbc(ctx, walk.dst.virt.addr, walk.src.virt.addr,
-+ iv, nbytes, CRYPTO_DIR_ENCRYPT, 0);
-+ nbytes &= AES_BLOCK_SIZE - 1;
-+ err = blkcipher_walk_done(desc, &walk, nbytes);
-+ }
-+
-+ return err;
-+}
-+
-+/** \fn int cbc_aes_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst, struct scatterlist *src, unsigned int nbytes)
-+ * \ingroup LQ_AES_FUNCTIONS
-+ * \brief CBC AES decrypt using linux crypto blkcipher
-+ * \param desc blkcipher descriptor
-+ * \param dst output scatterlist
-+ * \param src input scatterlist
-+ * \param nbytes data size in bytes
-+ * \return err
-+*/
-+static int cbc_aes_decrypt(struct blkcipher_desc *desc,
-+ struct scatterlist *dst,
-+ struct scatterlist *src,
-+ unsigned int nbytes)
-+{
-+ struct aes_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
-+ struct blkcipher_walk walk;
-+ int err;
-+
-+ blkcipher_walk_init(&walk, dst, src, nbytes);
-+ err = blkcipher_walk_virt(desc, &walk);
-+
-+ while ((nbytes = walk.nbytes)) {
-+ u8 *iv = walk.iv;
-+ nbytes -= (nbytes % AES_BLOCK_SIZE);
-+ deu_aes_cbc(ctx, walk.dst.virt.addr, walk.src.virt.addr,
-+ iv, nbytes, CRYPTO_DIR_DECRYPT, 0);
-+ nbytes &= AES_BLOCK_SIZE - 1;
-+ err = blkcipher_walk_done(desc, &walk, nbytes);
-+ }
-+
-+ return err;
-+}
-+
-+/*
-+ * \brief AES function mappings
-+*/
-+static struct crypto_alg cbc_aes_alg = {
-+ .cra_name = "cbc(aes)",
-+ .cra_driver_name = "lq_deu-cbc(aes)",
-+ .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
-+ .cra_blocksize = AES_BLOCK_SIZE,
-+ .cra_ctxsize = sizeof(struct aes_ctx),
-+ .cra_type = &crypto_blkcipher_type,
-+ .cra_module = THIS_MODULE,
-+ .cra_list = LIST_HEAD_INIT(cbc_aes_alg.cra_list),
-+ .cra_u = {
-+ .blkcipher = {
-+ .min_keysize = AES_MIN_KEY_SIZE,
-+ .max_keysize = AES_MAX_KEY_SIZE,
-+ .ivsize = AES_BLOCK_SIZE,
-+ .setkey = aes_set_key,
-+ .encrypt = cbc_aes_encrypt,
-+ .decrypt = cbc_aes_decrypt,
-+ }
-+ }
-+};
-+
-+/** \fn int ctr_basic_aes_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst, struct scatterlist *src, unsigned int nbytes)
-+ * \ingroup LQ_AES_FUNCTIONS
-+ * \brief Counter mode AES encrypt using linux crypto blkcipher
-+ * \param desc blkcipher descriptor
-+ * \param dst output scatterlist
-+ * \param src input scatterlist
-+ * \param nbytes data size in bytes
-+ * \return err
-+*/
-+static int ctr_basic_aes_encrypt(struct blkcipher_desc *desc,
-+ struct scatterlist *dst,
-+ struct scatterlist *src,
-+ unsigned int nbytes)
-+{
-+ struct aes_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
-+ struct blkcipher_walk walk;
-+ int err;
-+
-+ blkcipher_walk_init(&walk, dst, src, nbytes);
-+ err = blkcipher_walk_virt(desc, &walk);
-+
-+ while ((nbytes = walk.nbytes)) {
-+ u8 *iv = walk.iv;
-+ nbytes -= (nbytes % AES_BLOCK_SIZE);
-+ deu_aes_ctr(ctx, walk.dst.virt.addr, walk.src.virt.addr,
-+ iv, nbytes, CRYPTO_DIR_ENCRYPT, 0);
-+ nbytes &= AES_BLOCK_SIZE - 1;
-+ err = blkcipher_walk_done(desc, &walk, nbytes);
-+ }
-+
-+ return err;
-+}
-+
-+/** \fn int ctr_basic_aes_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst, struct scatterlist *src, unsigned int nbytes)
-+ * \ingroup LQ_AES_FUNCTIONS
-+ * \brief Counter mode AES decrypt using linux crypto blkcipher
-+ * \param desc blkcipher descriptor
-+ * \param dst output scatterlist
-+ * \param src input scatterlist
-+ * \param nbytes data size in bytes
-+ * \return err
-+*/
-+static int ctr_basic_aes_decrypt(struct blkcipher_desc *desc,
-+ struct scatterlist *dst,
-+ struct scatterlist *src,
-+ unsigned int nbytes)
-+{
-+ struct aes_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
-+ struct blkcipher_walk walk;
-+ int err;
-+
-+ blkcipher_walk_init(&walk, dst, src, nbytes);
-+ err = blkcipher_walk_virt(desc, &walk);
-+
-+ while ((nbytes = walk.nbytes)) {
-+ u8 *iv = walk.iv;
-+ nbytes -= (nbytes % AES_BLOCK_SIZE);
-+ deu_aes_ctr(ctx, walk.dst.virt.addr, walk.src.virt.addr,
-+ iv, nbytes, CRYPTO_DIR_DECRYPT, 0);
-+ nbytes &= AES_BLOCK_SIZE - 1;
-+ err = blkcipher_walk_done(desc, &walk, nbytes);
-+ }
-+
-+ return err;
-+}
-+
-+/*
-+ * \brief AES function mappings
-+*/
-+static struct crypto_alg ctr_basic_aes_alg = {
-+ .cra_name = "ctr(aes)",
-+ .cra_driver_name = "lq_deu-ctr(aes)",
-+ .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
-+ .cra_blocksize = AES_BLOCK_SIZE,
-+ .cra_ctxsize = sizeof(struct aes_ctx),
-+ .cra_type = &crypto_blkcipher_type,
-+ .cra_module = THIS_MODULE,
-+ .cra_list = LIST_HEAD_INIT(ctr_basic_aes_alg.cra_list),
-+ .cra_u = {
-+ .blkcipher = {
-+ .min_keysize = AES_MIN_KEY_SIZE,
-+ .max_keysize = AES_MAX_KEY_SIZE,
-+ .ivsize = AES_BLOCK_SIZE,
-+ .setkey = aes_set_key,
-+ .encrypt = ctr_basic_aes_encrypt,
-+ .decrypt = ctr_basic_aes_decrypt,
-+ }
-+ }
-+};
-+
-+/** \fn int ctr_rfc3686_aes_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst, struct scatterlist *src, unsigned int nbytes)
-+ * \ingroup LQ_AES_FUNCTIONS
-+ * \brief Counter mode AES (rfc3686) encrypt using linux crypto blkcipher
-+ * \param desc blkcipher descriptor
-+ * \param dst output scatterlist
-+ * \param src input scatterlist
-+ * \param nbytes data size in bytes
-+ * \return err
-+*/
-+static int ctr_rfc3686_aes_encrypt(struct blkcipher_desc *desc,
-+ struct scatterlist *dst,
-+ struct scatterlist *src,
-+ unsigned int nbytes)
-+{
-+ struct aes_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
-+ struct blkcipher_walk walk;
-+ int err;
-+ u8 rfc3686_iv[16];
-+
-+ blkcipher_walk_init(&walk, dst, src, nbytes);
-+ err = blkcipher_walk_virt(desc, &walk);
-+
-+ /* set up counter block */
-+ memcpy(rfc3686_iv, ctx->nonce, CTR_RFC3686_NONCE_SIZE);
-+ memcpy(rfc3686_iv + CTR_RFC3686_NONCE_SIZE, walk.iv,
-+ CTR_RFC3686_IV_SIZE);
-+
-+ /* initialize counter portion of counter block */
-+ *(__be32 *)(rfc3686_iv + CTR_RFC3686_NONCE_SIZE + CTR_RFC3686_IV_SIZE) =
-+ cpu_to_be32(1);
-+
-+ while ((nbytes = walk.nbytes)) {
-+ nbytes -= (nbytes % AES_BLOCK_SIZE);
-+ deu_aes_ctr(ctx, walk.dst.virt.addr, walk.src.virt.addr,
-+ rfc3686_iv, nbytes, CRYPTO_DIR_ENCRYPT, 0);
-+ nbytes &= AES_BLOCK_SIZE - 1;
-+ err = blkcipher_walk_done(desc, &walk, nbytes);
-+ }
-+
-+ return err;
-+}
-+
-+/** \fn int ctr_rfc3686_aes_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst, struct scatterlist *src, unsigned int nbytes)
-+ * \ingroup LQ_AES_FUNCTIONS
-+ * \brief Counter mode AES (rfc3686) decrypt using linux crypto blkcipher
-+ * \param desc blkcipher descriptor
-+ * \param dst output scatterlist
-+ * \param src input scatterlist
-+ * \param nbytes data size in bytes
-+ * \return err
-+*/
-+static int ctr_rfc3686_aes_decrypt(struct blkcipher_desc *desc,
-+ struct scatterlist *dst,
-+ struct scatterlist *src,
-+ unsigned int nbytes)
-+{
-+ struct aes_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
-+ struct blkcipher_walk walk;
-+ int err;
-+ u8 rfc3686_iv[16];
-+
-+ blkcipher_walk_init(&walk, dst, src, nbytes);
-+ err = blkcipher_walk_virt(desc, &walk);
-+
-+ /* set up counter block */
-+ memcpy(rfc3686_iv, ctx->nonce, CTR_RFC3686_NONCE_SIZE);
-+ memcpy(rfc3686_iv + CTR_RFC3686_NONCE_SIZE, walk.iv,
-+ CTR_RFC3686_IV_SIZE);
-+
-+ /* initialize counter portion of counter block */
-+ *(__be32 *)(rfc3686_iv + CTR_RFC3686_NONCE_SIZE + CTR_RFC3686_IV_SIZE) =
-+ cpu_to_be32(1);
-+
-+ while ((nbytes = walk.nbytes)) {
-+ nbytes -= (nbytes % AES_BLOCK_SIZE);
-+ deu_aes_ctr(ctx, walk.dst.virt.addr, walk.src.virt.addr,
-+ rfc3686_iv, nbytes, CRYPTO_DIR_DECRYPT, 0);
-+ nbytes &= AES_BLOCK_SIZE - 1;
-+ err = blkcipher_walk_done(desc, &walk, nbytes);
-+ }
-+
-+ return err;
-+}
-+
-+/*
-+ * \brief AES function mappings
-+*/
-+static struct crypto_alg ctr_rfc3686_aes_alg = {
-+ .cra_name = "rfc3686(ctr(aes))",
-+ .cra_driver_name = "lq_deu-ctr-rfc3686(aes)",
-+ .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
-+ .cra_blocksize = AES_BLOCK_SIZE,
-+ .cra_ctxsize = sizeof(struct aes_ctx),
-+ .cra_type = &crypto_blkcipher_type,
-+ .cra_module = THIS_MODULE,
-+ .cra_list = LIST_HEAD_INIT(ctr_rfc3686_aes_alg.cra_list),
-+ .cra_u = {
-+ .blkcipher = {
-+ .min_keysize = AES_MIN_KEY_SIZE,
-+ .max_keysize = CTR_RFC3686_MAX_KEY_SIZE,
-+ .ivsize = CTR_RFC3686_IV_SIZE,
-+ .setkey = ctr_rfc3686_aes_set_key,
-+ .encrypt = ctr_rfc3686_aes_encrypt,
-+ .decrypt = ctr_rfc3686_aes_decrypt,
-+ }
-+ }
-+};
-+
-+/** \fn int lq_deu_init_aes (void)
-+ * \ingroup LQ_AES_FUNCTIONS
-+ * \brief function to initialize AES driver
-+ * \return ret
-+*/
-+int lq_deu_init_aes(void)
-+{
-+ int ret;
-+
-+ if ((ret = crypto_register_alg(&aes_alg)))
-+ goto aes_err;
-+
-+ if ((ret = crypto_register_alg(&ecb_aes_alg)))
-+ goto ecb_aes_err;
-+
-+ if ((ret = crypto_register_alg(&cbc_aes_alg)))
-+ goto cbc_aes_err;
-+
-+ if ((ret = crypto_register_alg(&ctr_basic_aes_alg)))
-+ goto ctr_basic_aes_err;
-+
-+ if ((ret = crypto_register_alg(&ctr_rfc3686_aes_alg)))
-+ goto ctr_rfc3686_aes_err;
-+
-+ deu_aes_chip_init();
-+
-+ CRTCL_SECT_INIT;
-+
-+#ifdef CONFIG_CRYPTO_DEV_DMA
-+ if (ALLOCATE_MEMORY(BUFFER_IN, AES_ALGO) < 0) {
-+ printk(KERN_ERR "[%s %s %d]: malloc memory fail!\n",
-+ __FILE__, __func__, __LINE__);
-+ goto ctr_rfc3686_aes_err;
-+ }
-+ if (ALLOCATE_MEMORY(BUFFER_OUT, AES_ALGO) < 0) {
-+ printk(KERN_ERR "[%s %s %d]: malloc memory fail!\n",
-+ __FILE__, __func__, __LINE__);
-+ goto ctr_rfc3686_aes_err;
-+ }
-+#endif
-+
-+ printk(KERN_NOTICE "Lantiq DEU AES initialized%s.\n",
-+ disable_deudma ? "" : " (DMA)");
-+ return ret;
-+
-+ctr_rfc3686_aes_err:
-+ crypto_unregister_alg(&ctr_rfc3686_aes_alg);
-+ printk(KERN_ERR "Lantiq ctr_rfc3686_aes initialization failed!\n");
-+ return ret;
-+ctr_basic_aes_err:
-+ crypto_unregister_alg(&ctr_basic_aes_alg);
-+ printk(KERN_ERR "Lantiq ctr_basic_aes initialization failed!\n");
-+ return ret;
-+cbc_aes_err:
-+ crypto_unregister_alg(&cbc_aes_alg);
-+ printk(KERN_ERR "Lantiq cbc_aes initialization failed!\n");
-+ return ret;
-+ecb_aes_err:
-+ crypto_unregister_alg(&ecb_aes_alg);
-+ printk(KERN_ERR "Lantiq aes initialization failed!\n");
-+ return ret;
-+aes_err:
-+ printk(KERN_ERR "Lantiq DEU AES initialization failed!\n");
-+ return ret;
-+}
-+
-+/** \fn void lq_deu_fini_aes(void)
-+ * \ingroup LQ_AES_FUNCTIONS
-+ * \brief unregister aes driver
-+*/
-+void lq_deu_fini_aes(void)
-+{
-+ crypto_unregister_alg(&aes_alg);
-+ crypto_unregister_alg(&ecb_aes_alg);
-+ crypto_unregister_alg(&cbc_aes_alg);
-+ crypto_unregister_alg(&ctr_basic_aes_alg);
-+ crypto_unregister_alg(&ctr_rfc3686_aes_alg);
-+
-+#ifdef CONFIG_CRYPTO_DEV_DMA
-+ FREE_MEMORY(aes_buff_in);
-+ FREE_MEMORY(aes_buff_out);
-+#endif
-+}
---- /dev/null
-+++ b/drivers/crypto/lantiq/arc4.c
-@@ -0,0 +1,397 @@
-+/*
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
-+ *
-+ * Copyright (C) 2010 Ralph Hempel <ralph.hempel@lantiq.com>
-+ * Copyright (C) 2009 Mohammad Firdaus
-+ */
-+
-+/**
-+ \defgroup LQ_DEU LQ_DEU_DRIVERS
-+ \ingroup API
-+ \brief Lantiq DEU driver module
-+*/
-+
-+/**
-+ \file arc4.c
-+ \ingroup LQ_DEU
-+ \brief ARC4 encryption DEU driver file
-+*/
-+
-+/**
-+ \defgroup LQ_ARC4_FUNCTIONS LQ_ARC4_FUNCTIONS
-+ \ingroup LQ_DEU
-+ \brief Lantiq DEU driver functions
-+*/
-+
-+#include <linux/version.h>
-+#include <linux/module.h>
-+#include <linux/init.h>
-+#include <linux/types.h>
-+#include <linux/errno.h>
-+#include <linux/crypto.h>
-+#include <crypto/algapi.h>
-+#include <linux/interrupt.h>
-+#include <asm/byteorder.h>
-+#include <linux/delay.h>
-+
-+#ifdef CONFIG_SOL_LANTIQ_XWAY
-+
-+#include "deu.h"
-+
-+#ifdef CONFIG_CRYPTO_DEV_LANTIQ_DMA
-+
-+static spinlock_t cipher_lock;
-+
-+/* Preprocessor declerations */
-+#define ARC4_MIN_KEY_SIZE 1
-+/* #define ARC4_MAX_KEY_SIZE 256 */
-+#define ARC4_MAX_KEY_SIZE 16
-+#define ARC4_BLOCK_SIZE 1
-+
-+/*
-+ * \brief arc4 private structure
-+*/
-+struct arc4_ctx {
-+ int key_length;
-+ u8 buf[120];
-+};
-+
-+/** \fn static void deu_arc4(void *ctx_arg, u8 *out_arg, const u8 *in_arg, u8 *iv_arg, u32 nbytes, int encdec, int mode)
-+ \ingroup LQ_ARC4_FUNCTIONS
-+ \brief main interface to AES hardware
-+ \param ctx_arg crypto algo context
-+ \param out_arg output bytestream
-+ \param in_arg input bytestream
-+ \param iv_arg initialization vector
-+ \param nbytes length of bytestream
-+ \param encdec 1 for encrypt; 0 for decrypt
-+ \param mode operation mode such as ebc, cbc, ctr
-+*/
-+static void deu_arc4(void *ctx_arg,
-+ u8 *out_arg,
-+ const u8 *in_arg,
-+ u8 *iv_arg,
-+ u32 nbytes,
-+ int encdec,
-+ int mode)
-+{
-+ volatile struct deu_arc4 *arc4 = (struct deu_arc4 *) ARC4_START;
-+ int i = 0;
-+ ulong flag;
-+
-+#if 1 /* need to handle nbytes not multiple of 16 */
-+ volatile u32 tmp_array32[4];
-+ volatile u8 *tmp_ptr8;
-+ int remaining_bytes, j;
-+#endif
-+
-+ CRTCL_SECT_START;
-+
-+ arc4->IDLEN = nbytes;
-+
-+#if 1
-+ while (i < nbytes) {
-+ arc4->ID3R = *((u32 *) in_arg + (i>>2) + 0);
-+ arc4->ID2R = *((u32 *) in_arg + (i>>2) + 1);
-+ arc4->ID1R = *((u32 *) in_arg + (i>>2) + 2);
-+ arc4->ID0R = *((u32 *) in_arg + (i>>2) + 3);
-+
-+ arc4->ctrl.GO = 1;
-+
-+ while (arc4->ctrl.BUS) {
-+ /* this will not take long */ }
-+
-+#if 1
-+ /* need to handle nbytes not multiple of 16 */
-+ tmp_array32[0] = arc4->OD3R;
-+ tmp_array32[1] = arc4->OD2R;
-+ tmp_array32[2] = arc4->OD1R;
-+ tmp_array32[3] = arc4->OD0R;
-+
-+ remaining_bytes = nbytes - i;
-+ if (remaining_bytes > 16)
-+ remaining_bytes = 16;
-+
-+ tmp_ptr8 = (u8 *)&tmp_array32[0];
-+ for (j = 0; j < remaining_bytes; j++)
-+ *out_arg++ = *tmp_ptr8++;
-+#else
-+ *((u32 *) out_arg + (i>>2) + 0) = arc4->OD3R;
-+ *((u32 *) out_arg + (i>>2) + 1) = arc4->OD2R;
-+ *((u32 *) out_arg + (i>>2) + 2) = arc4->OD1R;
-+ *((u32 *) out_arg + (i>>2) + 3) = arc4->OD0R;
-+#endif
-+
-+ i += 16;
-+ }
-+#else /* dma */
-+
-+#endif /* dma */
-+
-+ CRTCL_SECT_END;
-+}
-+
-+/** \fn arc4_chip_init(void)
-+ \ingroup LQ_ARC4_FUNCTIONS
-+ \brief initialize arc4 hardware
-+*/
-+static void arc4_chip_init(void)
-+{
-+ /* do nothing */
-+}
-+
-+/** \fn static int arc4_set_key(struct crypto_tfm *tfm, const u8 *in_key, unsigned int key_len)
-+ \ingroup LQ_ARC4_FUNCTIONS
-+ \brief sets ARC4 key
-+ \param tfm linux crypto algo transform
-+ \param in_key input key
-+ \param key_len key lengths less than or equal to 16 bytes supported
-+*/
-+static int arc4_set_key(struct crypto_tfm *tfm,
-+ const u8 *inkey,
-+ unsigned int key_len)
-+{
-+ /* struct arc4_ctx *ctx = crypto_tfm_ctx(tfm); */
-+ volatile struct deu_arc4 *arc4 = (struct deu_arc4 *) ARC4_START;
-+
-+ u32 *in_key = (u32 *)inkey;
-+
-+ /* must program all bits at one go?!!! */
-+#if 1
-+ /* #ifndef CONFIG_CRYPTO_DEV_VR9_DMA */
-+ *LQ_ARC4_CON = ( (1<<31) | ((key_len - 1)<<27) | (1<<26) | (3<<16) );
-+ /* NDC=1,ENDI=1,GO=0,KSAE=1,SM=0 */
-+
-+ arc4->K3R = *((u32 *) in_key + 0);
-+ arc4->K2R = *((u32 *) in_key + 1);
-+ arc4->K1R = *((u32 *) in_key + 2);
-+ arc4->K0R = *((u32 *) in_key + 3);
-+#else /* dma */
-+ *AMAZONS_ARC4_CON = ( (1<<31) | ((key_len - 1)<<27) | (1<<26) | (3<<16) | (1<<4) );
-+ /* NDC=1,ENDI=1,GO=0,KSAE=1,SM=1 */
-+
-+ arc4->K3R = *((u32 *) in_key + 0);
-+ arc4->K2R = *((u32 *) in_key + 1);
-+ arc4->K1R = *((u32 *) in_key + 2);
-+ arc4->K0R = *((u32 *) in_key + 3);
-+
-+#if 0
-+ arc4->K3R = deu_endian_swap(*((u32 *) in_key + 0));
-+ arc4->K2R = deu_endian_swap(*((u32 *) in_key + 1));
-+ arc4->K1R = deu_endian_swap(*((u32 *) in_key + 2));
-+ arc4->K0R = deu_endian_swap(*((u32 *) in_key + 3));
-+#endif
-+
-+#endif
-+
-+#if 0 /* arc4 is a ugly state machine, KSAE can only be set once per session */
-+ ctx->key_length = key_len;
-+
-+ memcpy((u8 *)(ctx->buf), in_key, key_len);
-+#endif
-+
-+ return 0;
-+}
-+
-+/** \fn static void deu_arc4_ecb(void *ctx, uint8_t *dst, const uint8_t *src, uint8_t *iv, size_t nbytes, int encdec, int inplace)
-+ \ingroup LQ_ARC4_FUNCTIONS
-+ \brief sets ARC4 hardware to ECB mode
-+ \param ctx crypto algo context
-+ \param dst output bytestream
-+ \param src input bytestream
-+ \param iv initialization vector
-+ \param nbytes length of bytestream
-+ \param encdec 1 for encrypt; 0 for decrypt
-+ \param inplace not used
-+*/
-+static void deu_arc4_ecb(void *ctx,
-+ uint8_t *dst,
-+ const uint8_t *src,
-+ uint8_t *iv,
-+ size_t nbytes,
-+ int encdec,
-+ int inplace)
-+{
-+ deu_arc4(ctx, dst, src, NULL, nbytes, encdec, 0);
-+}
-+
-+/** \fn static void arc4_crypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
-+ \ingroup LQ_ARC4_FUNCTIONS
-+ \brief encrypt/decrypt ARC4_BLOCK_SIZE of data
-+ \param tfm linux crypto algo transform
-+ \param out output bytestream
-+ \param in input bytestream
-+*/
-+static void arc4_crypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
-+{
-+ struct arc4_ctx *ctx = crypto_tfm_ctx(tfm);
-+
-+ deu_arc4(ctx, out, in, NULL, ARC4_BLOCK_SIZE,
-+ CRYPTO_DIR_DECRYPT, CRYPTO_TFM_MODE_ECB);
-+}
-+
-+/*
-+ * \brief ARC4 function mappings
-+*/
-+static struct crypto_alg arc4_alg = {
-+ .cra_name = "arc4",
-+ .cra_driver_name = "lq_deu-arc4",
-+ .cra_flags = CRYPTO_ALG_TYPE_CIPHER,
-+ .cra_blocksize = ARC4_BLOCK_SIZE,
-+ .cra_ctxsize = sizeof(struct arc4_ctx),
-+ .cra_module = THIS_MODULE,
-+ .cra_list = LIST_HEAD_INIT(arc4_alg.cra_list),
-+ .cra_u = {
-+ .cipher = {
-+ .cia_min_keysize = ARC4_MIN_KEY_SIZE,
-+ .cia_max_keysize = ARC4_MAX_KEY_SIZE,
-+ .cia_setkey = arc4_set_key,
-+ .cia_encrypt = arc4_crypt,
-+ .cia_decrypt = arc4_crypt,
-+ }
-+ }
-+};
-+
-+/** \fn static int ecb_arc4_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst, struct scatterlist *src, unsigned int nbytes)
-+ \ingroup LQ_ARC4_FUNCTIONS
-+ \brief ECB ARC4 encrypt using linux crypto blkcipher
-+ \param desc blkcipher descriptor
-+ \param dst output scatterlist
-+ \param src input scatterlist
-+ \param nbytes data size in bytes
-+*/
-+static int ecb_arc4_encrypt(struct blkcipher_desc *desc,
-+ struct scatterlist *dst,
-+ struct scatterlist *src,
-+ unsigned int nbytes)
-+{
-+ struct arc4_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
-+ struct blkcipher_walk walk;
-+ int err;
-+
-+ DPRINTF(1, "\n");
-+ blkcipher_walk_init(&walk, dst, src, nbytes);
-+ err = blkcipher_walk_virt(desc, &walk);
-+
-+ while ((nbytes = walk.nbytes)) {
-+ deu_arc4_ecb(ctx, walk.dst.virt.addr, walk.src.virt.addr,
-+ NULL, nbytes, CRYPTO_DIR_ENCRYPT, 0);
-+ nbytes &= ARC4_BLOCK_SIZE - 1;
-+ err = blkcipher_walk_done(desc, &walk, nbytes);
-+ }
-+
-+ return err;
-+}
-+
-+/** \fn static int ecb_arc4_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst, struct scatterlist *src, unsigned int nbytes)
-+ \ingroup LQ_ARC4_FUNCTIONS
-+ \brief ECB ARC4 decrypt using linux crypto blkcipher
-+ \param desc blkcipher descriptor
-+ \param dst output scatterlist
-+ \param src input scatterlist
-+ \param nbytes data size in bytes
-+*/
-+static int ecb_arc4_decrypt(struct blkcipher_desc *desc,
-+ struct scatterlist *dst,
-+ struct scatterlist *src,
-+ unsigned int nbytes)
-+{
-+ struct arc4_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
-+ struct blkcipher_walk walk;
-+ int err;
-+
-+ DPRINTF(1, "\n");
-+ blkcipher_walk_init(&walk, dst, src, nbytes);
-+ err = blkcipher_walk_virt(desc, &walk);
-+
-+ while ((nbytes = walk.nbytes)) {
-+ deu_arc4_ecb(ctx, walk.dst.virt.addr, walk.src.virt.addr,
-+ NULL, nbytes, CRYPTO_DIR_DECRYPT, 0);
-+ nbytes &= ARC4_BLOCK_SIZE - 1;
-+ err = blkcipher_walk_done(desc, &walk, nbytes);
-+ }
-+
-+ return err;
-+}
-+
-+/*
-+ * \brief ARC4 function mappings
-+*/
-+static struct crypto_alg ecb_arc4_alg = {
-+ .cra_name = "ecb(arc4)",
-+ .cra_driver_name = "lq_deu-ecb(arc4)",
-+ .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
-+ .cra_blocksize = ARC4_BLOCK_SIZE,
-+ .cra_ctxsize = sizeof(struct arc4_ctx),
-+ .cra_type = &crypto_blkcipher_type,
-+ .cra_module = THIS_MODULE,
-+ .cra_list = LIST_HEAD_INIT(ecb_arc4_alg.cra_list),
-+ .cra_u = {
-+ .blkcipher = {
-+ .min_keysize = ARC4_MIN_KEY_SIZE,
-+ .max_keysize = ARC4_MAX_KEY_SIZE,
-+ .setkey = arc4_set_key,
-+ .encrypt = ecb_arc4_encrypt,
-+ .decrypt = ecb_arc4_decrypt,
-+ }
-+ }
-+};
-+
-+/** \fn int lq_deu_init_arc4(void)
-+ \ingroup LQ_ARC4_FUNCTIONS
-+ \brief initialize arc4 driver
-+*/
-+int lq_deu_init_arc4(void)
-+{
-+ int ret;
-+
-+ if ((ret = crypto_register_alg(&arc4_alg)))
-+ goto arc4_err;
-+
-+ if ((ret = crypto_register_alg(&ecb_arc4_alg)))
-+ goto ecb_arc4_err;
-+
-+ arc4_chip_init();
-+
-+ CRTCL_SECT_INIT;
-+
-+ printk(KERN_NOTICE "Lantiq DEU ARC4 initialized %s.\n",
-+ disable_deudma ? "" : " (DMA)");
-+ return ret;
-+
-+arc4_err:
-+ crypto_unregister_alg(&arc4_alg);
-+ printk(KERN_ERR "Lantiq arc4 initialization failed!\n");
-+ return ret;
-+ecb_arc4_err:
-+ crypto_unregister_alg(&ecb_arc4_alg);
-+ printk(KERN_ERR "Lantiq ecb_arc4 initialization failed!\n");
-+
-+ return ret;
-+}
-+
-+/** \fn void lq_deu_fini_arc4(void)
-+ \ingroup LQ_ARC4_FUNCTIONS
-+ \brief unregister arc4 driver
-+*/
-+void lq_deu_fini_arc4(void)
-+{
-+ crypto_unregister_alg(&arc4_alg);
-+ crypto_unregister_alg(&ecb_arc4_alg);
-+}
-+
-+#endif
-+
-+#endif
---- /dev/null
-+++ b/drivers/crypto/lantiq/des.c
-@@ -0,0 +1,929 @@
-+/*
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
-+ *
-+ * Copyright (C) 2010 Ralph Hempel <ralph.hempel@lantiq.com>
-+ * Copyright (C) 2009 Mohammad Firdaus
-+ */
-+
-+/**
-+ \defgroup LQ_DEU LQ_DEU_DRIVERS
-+ \ingroup API
-+ \brief Lantiq DEU driver
-+*/
-+
-+/**
-+ \file des.c
-+ \ingroup LQ_DEU
-+ \brief DES encryption DEU driver file
-+*/
-+
-+/**
-+ \defgroup LQ_DES_FUNCTIONS LQ_DES_FUNCTIONS
-+ \ingroup LQ_DEU
-+ \brief Lantiq DES Encryption functions
-+*/
-+
-+#include <linux/version.h>
-+#include <linux/module.h>
-+#include <linux/init.h>
-+#include <linux/types.h>
-+#include <linux/errno.h>
-+#include <linux/crypto.h>
-+#include <linux/interrupt.h>
-+#include <linux/delay.h>
-+#include <asm/byteorder.h>
-+#include <crypto/algapi.h>
-+
-+#ifdef CONFIG_SOL_LANTIQ_XWAY
-+
-+#include "deu.h"
-+
-+#ifdef CONFIG_CRYPTO_DEV_DMA
-+# include "deu_dma.h"
-+#endif
-+
-+static spinlock_t cipher_lock;
-+
-+/* Preprocessor declarations */
-+#define DES_KEY_SIZE 8
-+#define DES_EXPKEY_WORDS 32
-+#define DES_BLOCK_SIZE 8
-+#define DES3_EDE_KEY_SIZE (3 * DES_KEY_SIZE)
-+#define DES3_EDE_EXPKEY_WORDS (3 * DES_EXPKEY_WORDS)
-+#define DES3_EDE_BLOCK_SIZE DES_BLOCK_SIZE
-+
-+struct des_ctx {
-+ int controlr_M;
-+ int key_length;
-+ u8 iv[DES_BLOCK_SIZE];
-+ u32 expkey[DES3_EDE_EXPKEY_WORDS];
-+};
-+
-+/** \fn int des_setkey(struct crypto_tfm *tfm, const u8 *key, unsigned int key_len)
-+ * \ingroup LQ_DES_FUNCTIONS
-+ * \brief sets DES key
-+ * \param tfm linux crypto algo transform
-+ * \param key input key
-+ * \param key_len key length
-+*/
-+static int des_setkey(struct crypto_tfm *tfm,
-+ const u8 *key,
-+ unsigned int key_len)
-+{
-+ struct des_ctx *ctx = crypto_tfm_ctx(tfm);
-+
-+ DPRINTF(0, "ctx @%p, key_len %d %d\n", ctx, key_len);
-+
-+ ctx->controlr_M = 0; /* des */
-+ ctx->key_length = key_len;
-+
-+ memcpy((u8 *)(ctx->expkey), key, key_len);
-+
-+ return 0;
-+}
-+
-+#ifndef CONFIG_CRYPTO_DEV_LANTIQ_DMA
-+/** \fn void deu_des(void *ctx_arg, u8 *out_arg, const u8 *in_arg, u8 *iv_arg, u32 nbytes, int encdec, int mode)
-+ * \ingroup LQ_DES_FUNCTIONS
-+ * \brief main interface to DES hardware
-+ * \param ctx_arg crypto algo context
-+ * \param out_arg output bytestream
-+ * \param in_arg input bytestream
-+ * \param iv_arg initialization vector
-+ * \param nbytes length of bytestream
-+ * \param encdec 1 for encrypt; 0 for decrypt
-+ * \param mode operation mode such as ebc, cbc
-+*/
-+
-+static void deu_des(void *ctx_arg,
-+ u8 *out_arg,
-+ const u8 *in_arg,
-+ u8 *iv_arg,
-+ u32 nbytes,
-+ int encdec,
-+ int mode)
-+#else
-+/** \fn void deu_des_core(void *ctx_arg, u8 *out_arg, const u8 *in_arg, u8 *iv_arg, u32 nbytes, int encdec, int mode)
-+ * \ingroup LQ_DES_FUNCTIONS
-+ * \brief main interface to DES hardware
-+ * \param ctx_arg crypto algo context
-+ * \param out_arg output bytestream
-+ * \param in_arg input bytestream
-+ * \param iv_arg initialization vector
-+ * \param nbytes length of bytestream
-+ * \param encdec 1 for encrypt; 0 for decrypt
-+ * \param mode operation mode such as ebc, cbc
-+*/
-+static void deu_des_core(void *ctx_arg,
-+ u8 *out_arg,
-+ const u8 *in_arg,
-+ u8 *iv_arg,
-+ u32 nbytes,
-+ int encdec,
-+ int mode)
-+#endif
-+{
-+ volatile struct deu_des *des = (struct deu_des *) DES_3DES_START;
-+ struct des_ctx *dctx = ctx_arg;
-+ u32 *key = dctx->expkey;
-+ ulong flag;
-+
-+#ifndef CONFIG_CRYPTO_DEV_LANTIQ_DMA
-+ int i = 0;
-+ int nblocks = 0;
-+#else
-+ volatile struct deu_dma *dma = (struct deu_dma *) LQ_DEU_DMA_CON;
-+ struct dma_device_info *dma_device = lq_deu[0].dma_device;
-+ /* struct deu_drv_priv *deu_priv =
-+ * (struct deu_drv_priv *)dma_device->priv; */
-+ int wlen = 0;
-+ u32 *outcopy = NULL;
-+ u32 *dword_mem_aligned_in = NULL;
-+
-+#ifdef CONFIG_CRYPTO_DEV_LANTIQ_POLL_DMA
-+ u32 timeout = 0;
-+ u32 *out_dma = NULL;
-+#endif
-+
-+#endif
-+
-+ DPRINTF(0, "ctx @%p, mode %d, encdec %d\n", dctx, mode, encdec);
-+
-+ CRTCL_SECT_START;
-+
-+ des->ctrl.E_D = !encdec; /* encryption */
-+ des->ctrl.O = mode; /* 0 ECB, 1 CBC, 2 OFB, 3 CFB, 4 CTR */
-+ des->ctrl.SM = 1; /* start after writing input register */
-+ des->ctrl.DAU = 0; /* Disable Automatic Update of init vect */
-+ des->ctrl.ARS = 1; /* Autostart Select - write to IHR */
-+
-+ des->ctrl.M = dctx->controlr_M;
-+ /* write keys */
-+ if (dctx->controlr_M == 0) {
-+ /* DES mode */
-+ des->K1HR = DEU_ENDIAN_SWAP(*((u32 *) key + 0));
-+ des->K1LR = DEU_ENDIAN_SWAP(*((u32 *) key + 1));
-+#ifdef CRYPTO_DEBUG
-+ printk("key1: %x\n", (*((u32 *) key + 0)));
-+ printk("key2: %x\n", (*((u32 *) key + 1)));
-+#endif
-+ } else {
-+ /* 3DES mode (EDE-x) */
-+ switch (dctx->key_length) {
-+ case 24:
-+ des->K3HR = DEU_ENDIAN_SWAP(*((u32 *) key + 4));
-+ des->K3LR = DEU_ENDIAN_SWAP(*((u32 *) key + 5));
-+ /* no break; */
-+ case 16:
-+ des->K2HR = DEU_ENDIAN_SWAP(*((u32 *) key + 2));
-+ des->K2LR = DEU_ENDIAN_SWAP(*((u32 *) key + 3));
-+ /* no break; */
-+ case 8:
-+ des->K1HR = DEU_ENDIAN_SWAP(*((u32 *) key + 0));
-+ des->K1LR = DEU_ENDIAN_SWAP(*((u32 *) key + 1));
-+ break;
-+ default:
-+ CRTCL_SECT_END;
-+ return;
-+ }
-+ }
-+
-+ /* write init vector (not required for ECB mode) */
-+ if (mode > 0) {
-+ des->IVHR = DEU_ENDIAN_SWAP(*(u32 *) iv_arg);
-+ des->IVLR = DEU_ENDIAN_SWAP(*((u32 *) iv_arg + 1));
-+ }
-+
-+#ifndef CONFIG_CRYPTO_DEV_LANTIQ_DMA
-+ nblocks = nbytes / 4;
-+
-+ for (i = 0; i < nblocks; i += 2) {
-+ /* wait for busy bit to clear */
-+
-+ /*--- Workaround ---------------------------------------------
-+ do a dummy read to the busy flag because it is not raised
-+ early enough in CFB/OFB 3DES modes */
-+#ifdef CRYPTO_DEBUG
-+ printk("ihr: %x\n", (*((u32 *) in_arg + i)));
-+ printk("ilr: %x\n", (*((u32 *) in_arg + 1 + i)));
-+#endif
-+ des->IHR = INPUT_ENDIAN_SWAP(*((u32 *) in_arg + i));
-+ /* start crypto */
-+ des->ILR = INPUT_ENDIAN_SWAP(*((u32 *) in_arg + 1 + i));
-+
-+ while (des->ctrl.BUS) {
-+ /* this will not take long */
-+ }
-+
-+ *((u32 *) out_arg + 0 + i) = des->OHR;
-+ *((u32 *) out_arg + 1 + i) = des->OLR;
-+
-+#ifdef CRYPTO_DEBUG
-+ printk("ohr: %x\n", (*((u32 *) out_arg + i)));
-+ printk("olr: %x\n", (*((u32 *) out_arg + 1 + i)));
-+#endif
-+ }
-+
-+#else /* dma mode */
-+
-+ /* Prepare Rx buf length used in dma psuedo interrupt */
-+ /* deu_priv->deu_rx_buf = out_arg; */
-+ /* deu_priv->deu_rx_len = nbytes; */
-+
-+ /* memory alignment issue */
-+ dword_mem_aligned_in = (u32 *) DEU_DWORD_REORDERING(in_arg, des_buff_in,
-+ BUFFER_IN, nbytes);
-+
-+ dma->ctrl.ALGO = 0; /* DES */
-+ des->ctrl.DAU = 0;
-+ dma->ctrl.BS = 0;
-+ dma->ctrl.EN = 1;
-+
-+ while (des->ctrl.BUS) {
-+ /* wait for AES to be ready */
-+ };
-+
-+ wlen = dma_device_write(dma_device, (u8 *) dword_mem_aligned_in, nbytes,
-+ NULL);
-+ if (wlen != nbytes) {
-+ dma->ctrl.EN = 0;
-+ CRTCL_SECT_END;
-+ printk(KERN_ERR "[%s %s %d]: dma_device_write fail!\n",
-+ __FILE__, __func__, __LINE__);
-+ return; /* -EINVAL; */
-+ }
-+
-+ WAIT_DES_DMA_READY();
-+
-+#ifdef CONFIG_CRYPTO_DEV_LANTIQ_POLL_DMA
-+ outcopy = (u32 *) DEU_DWORD_REORDERING(out_arg, des_buff_out,
-+ BUFFER_OUT, nbytes);
-+
-+ /* polling DMA rx channel */
-+ while ((dma_device_read(dma_device, (u8 **) &out_dma, NULL)) == 0) {
-+ timeout++;
-+
-+ if (timeout >= 333000) {
-+ dma->ctrl.EN = 0;
-+ CRTCL_SECT_END;
-+ printk(KERN_ERR "[%s %s %d]: timeout!!\n",
-+ __FILE__, __func__, __LINE__);
-+ return; /* -EINVAL; */
-+ }
-+ }
-+
-+ WAIT_DES_DMA_READY();
-+
-+ DES_MEMORY_COPY(outcopy, out_dma, out_arg, nbytes);
-+#else
-+ CRTCL_SECT_END; /* Sleep and wait for Rx finished */
-+ DEU_WAIT_EVENT(deu_priv->deu_thread_wait, DEU_EVENT,
-+ deu_priv->deu_event_flags);
-+ CRTCL_SECT_START;
-+#endif
-+
-+#endif /* dma mode */
-+
-+ if (mode > 0) {
-+ *(u32 *) iv_arg = DEU_ENDIAN_SWAP(des->IVHR);
-+ *((u32 *) iv_arg + 1) = DEU_ENDIAN_SWAP(des->IVLR);
-+ };
-+
-+ CRTCL_SECT_END;
-+}
-+
-+/* definitions from linux/include/crypto.h:
-+#define CRYPTO_TFM_MODE_ECB 0x00000001
-+#define CRYPTO_TFM_MODE_CBC 0x00000002
-+#define CRYPTO_TFM_MODE_CFB 0x00000004
-+#define CRYPTO_TFM_MODE_CTR 0x00000008
-+#define CRYPTO_TFM_MODE_OFB 0x00000010
-+but hardware definition: 0 ECB 1 CBC 2 OFB 3 CFB 4 CTR */
-+
-+/** \fn void deu_des(void *ctx_arg, u8 *out_arg, const u8 *in_arg, u8 *iv_arg, u32 nbytes, int encdec, int mode)
-+ * \ingroup LQ_DES_FUNCTIONS
-+ * \brief main interface to DES hardware
-+ * \param ctx_arg crypto algo context
-+ * \param out_arg output bytestream
-+ * \param in_arg input bytestream
-+ * \param iv_arg initialization vector
-+ * \param nbytes length of bytestream
-+ * \param encdec 1 for encrypt; 0 for decrypt
-+ * \param mode operation mode such as ebc, cbc
-+*/
-+
-+#ifdef CONFIG_CRYPTO_DEV_LANTIQ_DMA
-+static void deu_des(void *ctx_arg,
-+ u8 *out_arg,
-+ const u8 *in_arg,
-+ u8 *iv_arg,
-+ u32 nbytes,
-+ int encdec,
-+ int mode)
-+{
-+ u32 remain = nbytes;
-+ u32 inc;
-+
-+ DPRINTF(0, "\n");
-+
-+ while (remain > 0) {
-+ if (remain >= DEU_MAX_PACKET_SIZE)
-+ inc = DEU_MAX_PACKET_SIZE;
-+ else
-+ inc = remain;
-+
-+ remain -= inc;
-+
-+ deu_des_core(ctx_arg, out_arg, in_arg, iv_arg, inc, encdec,
-+ mode);
-+
-+ out_arg += inc;
-+ in_arg += inc;
-+ }
-+}
-+#endif
-+
-+/** \fn void deu_des_ecb(void *ctx, uint8_t *dst, const uint8_t *src, uint8_t *iv, size_t nbytes, int encdec, int inplace)
-+ * \ingroup LQ_DES_FUNCTIONS
-+ * \brief sets DES hardware to ECB mode
-+ * \param ctx crypto algo context
-+ * \param dst output bytestream
-+ * \param src input bytestream
-+ * \param iv initialization vector
-+ * \param nbytes length of bytestream
-+ * \param encdec 1 for encrypt; 0 for decrypt
-+ * \param inplace not used
-+*/
-+
-+static void deu_des_ecb(void *ctx,
-+ uint8_t *dst,
-+ const uint8_t *src,
-+ uint8_t *iv,
-+ size_t nbytes,
-+ int encdec,
-+ int inplace)
-+{
-+ DPRINTF(0, "ctx @%p\n", ctx);
-+ deu_des(ctx, dst, src, NULL, nbytes, encdec, 0);
-+}
-+
-+/** \fn void deu_des_cbc(void *ctx, uint8_t *dst, const uint8_t *src, uint8_t *iv, size_t nbytes, int encdec, int inplace)
-+ * \ingroup LQ_DES_FUNCTIONS
-+ * \brief sets DES hardware to CBC mode
-+ * \param ctx crypto algo context
-+ * \param dst output bytestream
-+ * \param src input bytestream
-+ * \param iv initialization vector
-+ * \param nbytes length of bytestream
-+ * \param encdec 1 for encrypt; 0 for decrypt
-+ * \param inplace not used
-+*/
-+static void deu_des_cbc(void *ctx,
-+ uint8_t *dst,
-+ const uint8_t *src,
-+ uint8_t *iv,
-+ size_t nbytes,
-+ int encdec,
-+ int inplace)
-+{
-+ DPRINTF(0, "ctx @%p\n", ctx);
-+ deu_des(ctx, dst, src, iv, nbytes, encdec, 1);
-+}
-+
-+#if 0
-+/** \fn void deu_des_ofb(void *ctx, uint8_t *dst, const uint8_t *src, uint8_t *iv, size_t nbytes, int encdec, int inplace)
-+ * \ingroup LQ_DES_FUNCTIONS
-+ * \brief sets DES hardware to OFB mode
-+ * \param ctx crypto algo context
-+ * \param dst output bytestream
-+ * \param src input bytestream
-+ * \param iv initialization vector
-+ * \param nbytes length of bytestream
-+ * \param encdec 1 for encrypt; 0 for decrypt
-+ * \param inplace not used
-+*/
-+static void deu_des_ofb(void *ctx,
-+ uint8_t *dst,
-+ const uint8_t *src,
-+ uint8_t *iv,
-+ size_t nbytes,
-+ int encdec,
-+ int inplace)
-+{
-+ DPRINTF(0, "ctx @%p\n", ctx);
-+ deu_des(ctx, dst, src, iv, nbytes, encdec, 2);
-+}
-+
-+/** \fn void deu_des_cfb(void *ctx, uint8_t *dst, const uint8_t *src, uint8_t *iv, size_t nbytes, int encdec, int inplace)
-+ \ingroup LQ_DES_FUNCTIONS
-+ \brief sets DES hardware to CFB mode
-+ \param ctx crypto algo context
-+ \param dst output bytestream
-+ \param src input bytestream
-+ \param iv initialization vector
-+ \param nbytes length of bytestream
-+ \param encdec 1 for encrypt; 0 for decrypt
-+ \param inplace not used
-+*/
-+static void deu_des_cfb(void *ctx,
-+ uint8_t *dst,
-+ const uint8_t *src,
-+ uint8_t *iv,
-+ size_t nbytes,
-+ int encdec,
-+ int inplace)
-+{
-+ DPRINTF(0, "ctx @%p\n", ctx);
-+ deu_des(ctx, dst, src, iv, nbytes, encdec, 3);
-+}
-+
-+/** \fn void deu_des_ctr(void *ctx, uint8_t *dst, const uint8_t *src, uint8_t *iv, size_t nbytes, int encdec, int inplace)
-+ * \ingroup LQ_DES_FUNCTIONS
-+ * \brief sets DES hardware to CTR mode
-+ * \param ctx crypto algo context
-+ * \param dst output bytestream
-+ * \param src input bytestream
-+ * \param iv initialization vector
-+ * \param nbytes length of bytestream
-+ * \param encdec 1 for encrypt; 0 for decrypt
-+ * \param inplace not used
-+*/
-+static void deu_des_ctr(void *ctx,
-+ uint8_t *dst,
-+ const uint8_t *src,
-+ uint8_t *iv,
-+ size_t nbytes,
-+ int encdec,
-+ int inplace)
-+{
-+ DPRINTF(0, "ctx @%p\n", ctx);
-+ deu_des(ctx, dst, src, iv, nbytes, encdec, 4);
-+}
-+#endif
-+
-+/** \fn void des_encrypt(struct crypto_tfm *tfm, uint8_t *out, const uint8_t *in)
-+ * \ingroup LQ_DES_FUNCTIONS
-+ * \brief encrypt DES_BLOCK_SIZE of data
-+ * \param tfm linux crypto algo transform
-+ * \param out output bytestream
-+ * \param in input bytestream
-+*/
-+static void des_encrypt(struct crypto_tfm *tfm, uint8_t *out, const uint8_t *in)
-+{
-+ struct des_ctx *ctx = crypto_tfm_ctx(tfm);
-+ DPRINTF(0, "ctx @%p\n", ctx);
-+ deu_des(ctx, out, in, NULL, DES_BLOCK_SIZE, CRYPTO_DIR_ENCRYPT, 0);
-+}
-+
-+/** \fn void des_decrypt(struct crypto_tfm *tfm, uint8_t *out, const uint8_t *in)
-+ * \ingroup LQ_DES_FUNCTIONS
-+ * \brief encrypt DES_BLOCK_SIZE of data
-+ * \param tfm linux crypto algo transform
-+ * \param out output bytestream
-+ * \param in input bytestream
-+*/
-+static void des_decrypt(struct crypto_tfm *tfm, uint8_t *out, const uint8_t *in)
-+{
-+ struct des_ctx *ctx = crypto_tfm_ctx(tfm);
-+ DPRINTF(0, "ctx @%p\n", ctx);
-+ deu_des(ctx, out, in, NULL, DES_BLOCK_SIZE, CRYPTO_DIR_DECRYPT, 0);
-+}
-+
-+/*
-+ * \brief RFC2451:
-+ *
-+ * For DES-EDE3, there is no known need to reject weak or
-+ * complementation keys. Any weakness is obviated by the use of
-+ * multiple keys.
-+ *
-+ * However, if the first two or last two independent 64-bit keys are
-+ * equal (k1 == k2 or k2 == k3), then the DES3 operation is simply the
-+ * same as DES. Implementers MUST reject keys that exhibit this
-+ * property.
-+ *
-+ */
-+
-+/** \fn int des3_ede_setkey(struct crypto_tfm *tfm, const u8 *key, unsigned int keylen)
-+ * \ingroup LQ_DES_FUNCTIONS
-+ * \brief sets 3DES key
-+ * \param tfm linux crypto algo transform
-+ * \param key input key
-+ * \param keylen key length
-+*/
-+static int des3_ede_setkey(struct crypto_tfm *tfm,
-+ const u8 *key,
-+ unsigned int key_len)
-+{
-+ struct des_ctx *ctx = crypto_tfm_ctx(tfm);
-+
-+ DPRINTF(0, "ctx @%p, key_len %d\n", ctx, key_len);
-+
-+ ctx->controlr_M = key_len / 8 + 1; /* 3DES EDE1 / EDE2 / EDE3 Mode */
-+ ctx->key_length = key_len;
-+
-+ memcpy((u8 *)(ctx->expkey), key, key_len);
-+
-+ return 0;
-+}
-+
-+/*
-+ * \brief DES function mappings
-+*/
-+static struct crypto_alg des_alg = {
-+ .cra_name = "des",
-+ .cra_driver_name = "lq_deu-des",
-+ .cra_flags = CRYPTO_ALG_TYPE_CIPHER,
-+ .cra_blocksize = DES_BLOCK_SIZE,
-+ .cra_ctxsize = sizeof(struct des_ctx),
-+ .cra_module = THIS_MODULE,
-+ .cra_alignmask = 3,
-+ .cra_list = LIST_HEAD_INIT(des_alg.cra_list),
-+ .cra_u = {
-+ .cipher = {
-+ .cia_min_keysize = DES_KEY_SIZE,
-+ .cia_max_keysize = DES_KEY_SIZE,
-+ .cia_setkey = des_setkey,
-+ .cia_encrypt = des_encrypt,
-+ .cia_decrypt = des_decrypt
-+ }
-+ }
-+};
-+
-+/*
-+ * \brief DES function mappings
-+*/
-+static struct crypto_alg des3_ede_alg = {
-+ .cra_name = "des3_ede",
-+ .cra_driver_name = "lq_deu-des3_ede",
-+ .cra_flags = CRYPTO_ALG_TYPE_CIPHER,
-+ .cra_blocksize = DES_BLOCK_SIZE,
-+ .cra_ctxsize = sizeof(struct des_ctx),
-+ .cra_module = THIS_MODULE,
-+ .cra_alignmask = 3,
-+ .cra_list = LIST_HEAD_INIT(des3_ede_alg.cra_list),
-+ .cra_u = {
-+ .cipher = {
-+ .cia_min_keysize = DES_KEY_SIZE,
-+ .cia_max_keysize = DES_KEY_SIZE,
-+ .cia_setkey = des3_ede_setkey,
-+ .cia_encrypt = des_encrypt,
-+ .cia_decrypt = des_decrypt
-+ }
-+ }
-+};
-+
-+/** \fn int ecb_des_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst, struct scatterlist *src, unsigned int nbytes)
-+ * \ingroup LQ_DES_FUNCTIONS
-+ * \brief ECB DES encrypt using linux crypto blkcipher
-+ * \param desc blkcipher descriptor
-+ * \param dst output scatterlist
-+ * \param src input scatterlist
-+ * \param nbytes data size in bytes
-+*/
-+static int ecb_des_encrypt(struct blkcipher_desc *desc,
-+ struct scatterlist *dst,
-+ struct scatterlist *src,
-+ unsigned int nbytes)
-+{
-+ struct des_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
-+ struct blkcipher_walk walk;
-+ int err;
-+
-+ DPRINTF(0, "ctx @%p\n", ctx);
-+
-+ blkcipher_walk_init(&walk, dst, src, nbytes);
-+ err = blkcipher_walk_virt(desc, &walk);
-+
-+ while ((nbytes = walk.nbytes)) {
-+ nbytes -= (nbytes % DES_BLOCK_SIZE);
-+ deu_des_ecb(ctx, walk.dst.virt.addr, walk.src.virt.addr,
-+ NULL, nbytes, CRYPTO_DIR_ENCRYPT, 0);
-+ nbytes &= DES_BLOCK_SIZE - 1;
-+ err = blkcipher_walk_done(desc, &walk, nbytes);
-+ }
-+
-+ return err;
-+}
-+
-+/** \fn int ecb_des_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst, struct scatterlist *src, unsigned int nbytes)
-+ * \ingroup LQ_DES_FUNCTIONS
-+ * \brief ECB DES decrypt using linux crypto blkcipher
-+ * \param desc blkcipher descriptor
-+ * \param dst output scatterlist
-+ * \param src input scatterlist
-+ * \param nbytes data size in bytes
-+ * \return err
-+*/
-+static int ecb_des_decrypt(struct blkcipher_desc *desc,
-+ struct scatterlist *dst,
-+ struct scatterlist *src,
-+ unsigned int nbytes)
-+{
-+ struct des_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
-+ struct blkcipher_walk walk;
-+ int err;
-+
-+ DPRINTF(0, "ctx @%p\n", ctx);
-+
-+ blkcipher_walk_init(&walk, dst, src, nbytes);
-+ err = blkcipher_walk_virt(desc, &walk);
-+
-+ while ((nbytes = walk.nbytes)) {
-+ nbytes -= (nbytes % DES_BLOCK_SIZE);
-+ deu_des_ecb(ctx, walk.dst.virt.addr, walk.src.virt.addr,
-+ NULL, nbytes, CRYPTO_DIR_DECRYPT, 0);
-+ nbytes &= DES_BLOCK_SIZE - 1;
-+ err = blkcipher_walk_done(desc, &walk, nbytes);
-+ }
-+
-+ return err;
-+}
-+
-+/*
-+ * \brief DES function mappings
-+*/
-+static struct crypto_alg ecb_des_alg = {
-+ .cra_name = "ecb(des)",
-+ .cra_driver_name = "lq_deu-ecb(des)",
-+ .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
-+ .cra_blocksize = DES_BLOCK_SIZE,
-+ .cra_ctxsize = sizeof(struct des_ctx),
-+ .cra_type = &crypto_blkcipher_type,
-+ .cra_module = THIS_MODULE,
-+ .cra_list = LIST_HEAD_INIT(ecb_des_alg.cra_list),
-+ .cra_u = {
-+ .blkcipher = {
-+ .min_keysize = DES_KEY_SIZE,
-+ .max_keysize = DES_KEY_SIZE,
-+ .setkey = des_setkey,
-+ .encrypt = ecb_des_encrypt,
-+ .decrypt = ecb_des_decrypt,
-+ }
-+ }
-+};
-+
-+/*
-+ * \brief DES function mappings
-+*/
-+static struct crypto_alg ecb_des3_ede_alg = {
-+ .cra_name = "ecb(des3_ede)",
-+ .cra_driver_name = "lq_deu-ecb(des3_ede)",
-+ .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
-+ .cra_blocksize = DES3_EDE_BLOCK_SIZE,
-+ .cra_ctxsize = sizeof(struct des_ctx),
-+ .cra_type = &crypto_blkcipher_type,
-+ .cra_module = THIS_MODULE,
-+ .cra_list = LIST_HEAD_INIT(ecb_des3_ede_alg.cra_list),
-+ .cra_u = {
-+ .blkcipher = {
-+ .min_keysize = DES3_EDE_KEY_SIZE,
-+ .max_keysize = DES3_EDE_KEY_SIZE,
-+ .setkey = des3_ede_setkey,
-+ .encrypt = ecb_des_encrypt,
-+ .decrypt = ecb_des_decrypt,
-+ }
-+ }
-+};
-+
-+/** \fn int cbc_des_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst, struct scatterlist *src, unsigned int nbytes)
-+ * \ingroup LQ_DES_FUNCTIONS
-+ * \brief CBC DES encrypt using linux crypto blkcipher
-+ * \param desc blkcipher descriptor
-+ * \param dst output scatterlist
-+ * \param src input scatterlist
-+ * \param nbytes data size in bytes
-+ * \return err
-+*/
-+static int cbc_des_encrypt(struct blkcipher_desc *desc,
-+ struct scatterlist *dst,
-+ struct scatterlist *src,
-+ unsigned int nbytes)
-+{
-+ struct des_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
-+ struct blkcipher_walk walk;
-+ int err;
-+
-+ DPRINTF(0, "ctx @%p\n", ctx);
-+
-+ blkcipher_walk_init(&walk, dst, src, nbytes);
-+ err = blkcipher_walk_virt(desc, &walk);
-+
-+ while ((nbytes = walk.nbytes)) {
-+ u8 *iv = walk.iv;
-+ /* printk("iv = %08x\n", *(u32 *)iv); */
-+ nbytes -= (nbytes % DES_BLOCK_SIZE);
-+ deu_des_cbc(ctx, walk.dst.virt.addr, walk.src.virt.addr,
-+ iv, nbytes, CRYPTO_DIR_ENCRYPT, 0);
-+ nbytes &= DES_BLOCK_SIZE - 1;
-+ err = blkcipher_walk_done(desc, &walk, nbytes);
-+ }
-+
-+ return err;
-+}
-+
-+/** \fn int cbc_des_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst, struct scatterlist *src, unsigned int nbytes)
-+ * \ingroup LQ_DES_FUNCTIONS
-+ * \brief CBC DES decrypt using linux crypto blkcipher
-+ * \param desc blkcipher descriptor
-+ * \param dst output scatterlist
-+ * \param src input scatterlist
-+ * \param nbytes data size in bytes
-+ * \return err
-+*/
-+static int cbc_des_decrypt(struct blkcipher_desc *desc,
-+ struct scatterlist *dst,
-+ struct scatterlist *src,
-+ unsigned int nbytes)
-+{
-+ struct des_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
-+ struct blkcipher_walk walk;
-+ int err;
-+
-+ DPRINTF(0, "ctx @%p\n", ctx);
-+
-+ blkcipher_walk_init(&walk, dst, src, nbytes);
-+ err = blkcipher_walk_virt(desc, &walk);
-+
-+ while ((nbytes = walk.nbytes)) {
-+ u8 *iv = walk.iv;
-+ /* printk("iv = %08x\n", *(u32 *)iv); */
-+ nbytes -= (nbytes % DES_BLOCK_SIZE);
-+ deu_des_cbc(ctx, walk.dst.virt.addr, walk.src.virt.addr,
-+ iv, nbytes, CRYPTO_DIR_DECRYPT, 0);
-+ nbytes &= DES_BLOCK_SIZE - 1;
-+ err = blkcipher_walk_done(desc, &walk, nbytes);
-+ }
-+
-+ return err;
-+}
-+
-+/*
-+ * \brief DES function mappings
-+*/
-+static struct crypto_alg cbc_des_alg = {
-+ .cra_name = "cbc(des)",
-+ .cra_driver_name = "lq_deu-cbc(des)",
-+ .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
-+ .cra_blocksize = DES_BLOCK_SIZE,
-+ .cra_ctxsize = sizeof(struct des_ctx),
-+ .cra_type = &crypto_blkcipher_type,
-+ .cra_module = THIS_MODULE,
-+ .cra_list = LIST_HEAD_INIT(cbc_des_alg.cra_list),
-+ .cra_u = {
-+ .blkcipher = {
-+ .min_keysize = DES_KEY_SIZE,
-+ .max_keysize = DES_KEY_SIZE,
-+ .ivsize = DES_BLOCK_SIZE,
-+ .setkey = des_setkey,
-+ .encrypt = cbc_des_encrypt,
-+ .decrypt = cbc_des_decrypt,
-+ }
-+ }
-+};
-+
-+/*
-+ * \brief DES function mappings
-+*/
-+static struct crypto_alg cbc_des3_ede_alg = {
-+ .cra_name = "cbc(des3_ede)",
-+ .cra_driver_name = "lq_deu-cbc(des3_ede)",
-+ .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
-+ .cra_blocksize = DES3_EDE_BLOCK_SIZE,
-+ .cra_ctxsize = sizeof(struct des_ctx),
-+ .cra_type = &crypto_blkcipher_type,
-+ .cra_module = THIS_MODULE,
-+ .cra_list = LIST_HEAD_INIT(cbc_des3_ede_alg.cra_list),
-+ .cra_u = {
-+ .blkcipher = {
-+ .min_keysize = DES3_EDE_KEY_SIZE,
-+ .max_keysize = DES3_EDE_KEY_SIZE,
-+ .ivsize = DES_BLOCK_SIZE,
-+ .setkey = des3_ede_setkey,
-+ .encrypt = cbc_des_encrypt,
-+ .decrypt = cbc_des_decrypt,
-+ }
-+ }
-+};
-+
-+/** \fn int lq_deu_init_des(void)
-+ * \ingroup LQ_DES_FUNCTIONS
-+ * \brief initialize des driver
-+*/
-+int lq_deu_init_des(void)
-+{
-+ int ret = 0;
-+
-+ ret = crypto_register_alg(&des_alg);
-+ if (ret < 0)
-+ goto des_err;
-+
-+ ret = crypto_register_alg(&ecb_des_alg);
-+ if (ret < 0)
-+ goto ecb_des_err;
-+
-+ ret = crypto_register_alg(&cbc_des_alg);
-+ if (ret < 0)
-+ goto cbc_des_err;
-+
-+ ret = crypto_register_alg(&des3_ede_alg);
-+ if (ret < 0)
-+ goto des3_ede_err;
-+
-+ ret = crypto_register_alg(&ecb_des3_ede_alg);
-+ if (ret < 0)
-+ goto ecb_des3_ede_err;
-+
-+ ret = crypto_register_alg(&cbc_des3_ede_alg);
-+ if (ret < 0)
-+ goto cbc_des3_ede_err;
-+
-+ deu_des_chip_init();
-+
-+ CRTCL_SECT_INIT;
-+
-+#ifdef CONFIG_CRYPTO_DEV_LANTIQ_DMA
-+ if (ALLOCATE_MEMORY(BUFFER_IN, DES_ALGO) < 0) {
-+ printk(KERN_ERR "[%s %s %d]: malloc memory fail!\n",
-+ __FILE__, __func__, __LINE__);
-+ goto cbc_des3_ede_err;
-+ }
-+ if (ALLOCATE_MEMORY(BUFFER_OUT, DES_ALGO) < 0) {
-+ printk(KERN_ERR "[%s %s %d]: malloc memory fail!\n",
-+ __FILE__, __func__, __LINE__);
-+ goto cbc_des3_ede_err;
-+ }
-+#endif
-+
-+ printk(KERN_NOTICE "Lantiq DEU DES initialized%s.\n",
-+ disable_deudma ? "" : " (DMA)");
-+ return ret;
-+
-+des_err:
-+ crypto_unregister_alg(&des_alg);
-+ printk(KERN_ERR "Lantiq des initialization failed!\n");
-+
-+ return ret;
-+
-+ecb_des_err:
-+ crypto_unregister_alg(&ecb_des_alg);
-+ printk(KERN_ERR "Lantiq ecb_des initialization failed!\n");
-+
-+ return ret;
-+
-+cbc_des_err:
-+ crypto_unregister_alg(&cbc_des_alg);
-+ printk(KERN_ERR "Lantiq cbc_des initialization failed!\n");
-+
-+ return ret;
-+
-+des3_ede_err:
-+ crypto_unregister_alg(&des3_ede_alg);
-+ printk(KERN_ERR "Lantiq des3_ede initialization failed!\n");
-+
-+ return ret;
-+
-+ecb_des3_ede_err:
-+ crypto_unregister_alg(&ecb_des3_ede_alg);
-+ printk(KERN_ERR "Lantiq ecb_des3_ede initialization failed!\n");
-+
-+ return ret;
-+
-+cbc_des3_ede_err:
-+ crypto_unregister_alg(&cbc_des3_ede_alg);
-+ printk(KERN_ERR "Lantiq cbc_des3_ede initialization failed!\n");
-+
-+ return ret;
-+}
-+
-+/** \fn void lq_deu_fini_des(void)
-+ * \ingroup LQ_DES_FUNCTIONS
-+ * \brief unregister des driver
-+*/
-+void lq_deu_fini_des(void)
-+{
-+ crypto_unregister_alg(&des_alg);
-+ crypto_unregister_alg(&ecb_des_alg);
-+ crypto_unregister_alg(&cbc_des_alg);
-+ crypto_unregister_alg(&des3_ede_alg);
-+ crypto_unregister_alg(&ecb_des3_ede_alg);
-+ crypto_unregister_alg(&cbc_des3_ede_alg);
-+
-+#ifdef CONFIG_CRYPTO_DEV_LANTIQ_DMA
-+ FREE_MEMORY(des_buff_in);
-+ FREE_MEMORY(des_buff_out);
-+#endif /* CONFIG_CRYPTO_DEV_LANTIQ_DMA_DANUBE */
-+}
-+
-+#endif
---- /dev/null
-+++ b/drivers/crypto/lantiq/deu.c
-@@ -0,0 +1,195 @@
-+/*
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
-+ *
-+ * Copyright (C) 2010 Ralph Hempel <ralph.hempel@lantiq.com>
-+ * Copyright (C) 2009 Mohammad Firdaus
-+ */
-+
-+/**
-+ \defgroup LQ_DEU LQ_DEU_DRIVERS
-+ \ingroup API
-+ \brief Lantiq DEU driver module
-+*/
-+
-+/**
-+ \file deu.c
-+ \ingroup LQ_DEU
-+ \brief main DEU driver file
-+*/
-+
-+/**
-+ \defgroup LQ_DEU_FUNCTIONS LQ_DEU_FUNCTIONS
-+ \ingroup LQ_DEU
-+ \brief Lantiq DEU functions
-+*/
-+
-+#include <linux/version.h>
-+#if defined(CONFIG_MODVERSIONS)
-+#define MODVERSIONS
-+#include <linux/modversions.h>
-+#endif
-+#include <linux/module.h>
-+#include <linux/init.h>
-+#include <linux/types.h>
-+#include <linux/errno.h>
-+#include <linux/crypto.h>
-+#include <linux/proc_fs.h>
-+#include <linux/fs.h> /* Stuff about file systems that we need */
-+#include <asm/byteorder.h>
-+
-+#if 0
-+#ifdef CONFIG_SOC_LANTIQ_XWAY
-+# include <lq_pmu.h>
-+#endif
-+#endif
-+
-+#include "deu.h"
-+
-+struct lq_crypto_priv lq_crypto_ops;
-+
-+#ifdef CONFIG_CRYPTO_DEV_LANTIQ_DMA
-+int disable_deudma = 0;
-+#else
-+int disable_deudma = 1;
-+#endif /* CONFIG_CRYPTO_DEV_LANTIQ_DMA */
-+
-+#ifdef CRYPTO_DEBUG
-+char deu_debug_level = 3;
-+#endif
-+
-+#ifdef CONFIG_CRYPTO_DEV_LANTIQ_MODULE
-+# define STATIC static
-+#else
-+# define STATIC
-+#endif
-+
-+/** \fn static int lq_deu_init(void)
-+ * \ingroup LQ_DEU_FUNCTIONS
-+ * \brief link all modules that have been selected in kernel config for Lantiq HW crypto support
-+ * \return ret
-+*/
-+int lq_deu_init(void)
-+{
-+ int ret = -ENOSYS;
-+ u32 config;
-+
-+ printk(KERN_INFO "Lantiq crypto hardware driver version %s\n",
-+ LQ_DEU_DRV_VERSION);
-+
-+ config = deu_chip_init();
-+
-+#ifdef CONFIG_CRYPTO_DEV_LANTIQ_DMA
-+ deu_dma_init();
-+#endif
-+
-+#if defined(CONFIG_CRYPTO_DEV_LANTIQ_AES)
-+ if(config & LQ_DEU_ID_AES) {
-+ if ((ret = lq_deu_init_aes())) {
-+ printk(KERN_ERR "Lantiq AES initialization failed!\n");
-+ }
-+ } else {
-+ printk(KERN_ERR "Lantiq AES not supported!\n");
-+ }
-+#endif
-+
-+#ifdef CONFIG_SOL_LANTIQ_XWAY
-+#if defined(CONFIG_CRYPTO_DEV_LANTIQ_DES)
-+ if(config & LQ_DEU_ID_DES) {
-+ if ((ret = lq_deu_init_des())) {
-+ printk(KERN_ERR "Lantiq DES initialization failed!\n");
-+ }
-+ } else {
-+ printk(KERN_ERR "Lantiq DES not supported!\n");
-+ }
-+#endif
-+#if defined(CONFIG_CRYPTO_DEV_LANTIQ_ARC4) && defined(CONFIG_CRYPTO_DEV_LANTIQ_DMA)
-+ if ((ret = lq_deu_init_arc4())) {
-+ printk(KERN_ERR "Lantiq ARC4 initialization failed!\n");
-+ }
-+#endif
-+#endif
-+
-+#if defined(CONFIG_CRYPTO_DEV_LANTIQ_SHA1)
-+ if(config & LQ_DEU_ID_HASH) {
-+ if ((ret = lq_deu_init_sha1())) {
-+ printk(KERN_ERR "Lantiq SHA1 initialization failed!\n");
-+ }
-+ } else {
-+ printk(KERN_ERR "Lantiq SHA1 not supported!\n");
-+ }
-+#endif
-+#if defined(CONFIG_CRYPTO_DEV_LANTIQ_MD5)
-+ if(config & LQ_DEU_ID_HASH) {
-+ if ((ret = lq_deu_init_md5())) {
-+ printk(KERN_ERR "Lantiq MD5 initialization failed!\n");
-+ }
-+ } else {
-+ printk(KERN_ERR "Lantiq MD5 not supported!\n");
-+ }
-+#endif
-+#if defined(CONFIG_CRYPTO_DEV_LANTIQ_SHA1_HMAC)
-+ if ((ret = lq_deu_init_sha1_hmac())) {
-+ printk(KERN_ERR "Lantiq SHA1_HMAC initialization failed!\n");
-+ }
-+#endif
-+#if defined(CONFIG_CRYPTO_DEV_LANTIQ_MD5_HMAC)
-+ if ((ret = lq_deu_init_md5_hmac())) {
-+ printk(KERN_ERR "Lantiq MD5_HMAC initialization failed!\n");
-+ }
-+#endif
-+ return ret;
-+}
-+
-+/** \fn static void lq_deu_fini(void)
-+ * \ingroup LQ_DEU_FUNCTIONS
-+ * \brief remove the loaded crypto algorithms
-+*/
-+void lq_deu_exit(void)
-+{
-+#if defined(CONFIG_CRYPTO_DEV_LANTIQ_AES)
-+ lq_deu_fini_aes();
-+#endif
-+#ifdef CONFIG_SOL_LANTIQ_XWAY
-+#if defined(CONFIG_CRYPTO_DEV_LANTIQ_DES)
-+ lq_deu_fini_des();
-+#endif
-+#if defined(CONFIG_CRYPTO_DEV_LANTIQ_ARC4) \
-+ && defined(CONFIG_CRYPTO_DEV_LANTIQ_DMA)
-+ lq_deu_fini_arc4();
-+#endif
-+#endif
-+#if defined(CONFIG_CRYPTO_DEV_LANTIQ_SHA1)
-+ lq_deu_fini_sha1();
-+#endif
-+#if defined(CONFIG_CRYPTO_DEV_LANTIQ_MD5)
-+ lq_deu_fini_md5();
-+#endif
-+#if defined(CONFIG_CRYPTO_DEV_LANTIQ_SHA1_HMAC)
-+ lq_deu_fini_sha1_hmac();
-+#endif
-+#if defined(CONFIG_CRYPTO_DEV_LANTIQ_MD5_HMAC)
-+ lq_deu_fini_md5_hmac();
-+#endif
-+
-+ printk("DEU has exited successfully\n");
-+
-+#if defined(CONFIG_CRYPTO_DEV_LANTIQ_DMA)
-+ deu_dma_exit();
-+ printk("DMA has deregistered successfully\n");
-+#endif
-+}
-+
-+EXPORT_SYMBOL(lq_deu_init);
-+EXPORT_SYMBOL(lq_deu_exit);
---- /dev/null
-+++ b/drivers/crypto/lantiq/deu.h
-@@ -0,0 +1,248 @@
-+/*
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
-+ *
-+ * Copyright (C) 2010 Ralph Hempel <ralph.hempel@lantiq.com>
-+ * Copyright (C) 2009 Mohammad Firdaus
-+ */
-+
-+/**
-+ \defgroup LQ_DEU LQ_DEU_DRIVERS
-+ \ingroup API
-+ \brief Lantiq DEU driver module
-+*/
-+
-+/**
-+ \file deu.h
-+ \brief Main DEU driver header file
-+*/
-+
-+/**
-+ \defgroup LQ_DEU_DEFINITIONS LQ_DEU_DEFINITIONS
-+ \ingroup LQ_DEU
-+ \brief Lantiq DEU definitions
-+*/
-+
-+
-+#ifndef DEU_H
-+#define DEU_H
-+
-+#undef CRYPTO_DEBUG
-+
-+#define LQ_DEU_DRV_VERSION "1.0.1"
-+
-+#if defined(CONFIG_LANTIQ_DANUBE)
-+# include "deu_danube.h"
-+#elif defined(CONFIG_LANTIQ_AR9)
-+# include "deu_ar9.h"
-+#elif defined(CONFIG_SOC_LANTIQ_FALCON)
-+# include "deu_falcon.h"
-+#else
-+//# error "Unknown platform"
-+# include "deu_danube.h"
-+#endif
-+
-+struct lq_crypto_priv {
-+#ifdef CONFIG_CRYPTO_DEV_LANTIQ_DMA
-+ u32 *des_buff_in;
-+ u32 *des_buff_out;
-+ u32 *aes_buff_in;
-+ u32 *aes_buff_out;
-+
-+ int (*dma_init)(void);
-+ void (*dma_exit)(void);
-+ u32 (*dma_align)(const u8 *, u32 *, int, int);
-+ void (*aes_dma_memcpy)(u32 *, u32 *, u8 *, int);
-+ void (*des_dma_memcpy)(u32 *, u32 *, u8 *, int);
-+ int (*aes_dma_malloc)(int);
-+ int (*des_dma_malloc)(int);
-+ void (*dma_free)(u32 *);
-+#endif
-+
-+ u32 (*endian_swap)(u32);
-+ u32 (*input_swap)(u32);
-+ void (*aes_chip_init)(void);
-+ void (*des_chip_init)(void);
-+ u32 (*chip_init)(void);
-+};
-+
-+extern struct lq_crypto_priv lq_crypto_ops;
-+
-+#define LQ_DEU_ALIGNMENT 16
-+
-+#define PFX "lq_deu: "
-+
-+#define LQ_DEU_CRA_PRIORITY 300
-+#define LQ_DEU_COMPOSITE_PRIORITY 400
-+
-+#define CRYPTO_DIR_ENCRYPT 1
-+#define CRYPTO_DIR_DECRYPT 0
-+
-+#define CRTCL_SECT_INIT spin_lock_init(&cipher_lock)
-+#define CRTCL_SECT_START spin_lock_irqsave(&cipher_lock, flag)
-+#define CRTCL_SECT_END spin_unlock_irqrestore(&cipher_lock, flag)
-+
-+#define LQ_DEU_ID_REV 0x00001F
-+#define LQ_DEU_ID_ID 0x00FF00
-+#define LQ_DEU_ID_DMA 0x010000
-+#define LQ_DEU_ID_HASH 0x020000
-+#define LQ_DEU_ID_AES 0x040000
-+#define LQ_DEU_ID_3DES 0x080000
-+#define LQ_DEU_ID_DES 0x100000
-+
-+extern int disable_deudma;
-+
-+int lq_deu_init(void);
-+void lq_deu_exit(void);
-+
-+int lq_deu_init_des(void);
-+int lq_deu_init_aes(void);
-+int lq_deu_init_arc4(void);
-+int lq_deu_init_sha1(void);
-+int lq_deu_init_md5(void);
-+int lq_deu_init_sha1_hmac(void);
-+int lq_deu_init_md5_hmac(void);
-+
-+void lq_deu_fini_des(void);
-+void lq_deu_fini_aes(void);
-+void lq_deu_fini_arc4(void);
-+void lq_deu_fini_sha1(void);
-+void lq_deu_fini_md5(void);
-+void lq_deu_fini_sha1_hmac(void);
-+void lq_deu_fini_md5_hmac(void);
-+
-+/* board specific functions */
-+/* { */
-+static inline u32 deu_chip_init(void)
-+{
-+ return lq_crypto_ops.chip_init();
-+}
-+
-+static inline void deu_des_chip_init(void)
-+{
-+ lq_crypto_ops.des_chip_init();
-+}
-+
-+static inline void deu_aes_chip_init(void)
-+{
-+ lq_crypto_ops.aes_chip_init();
-+}
-+
-+static inline u32 deu_input_swap(u32 input)
-+{
-+ return lq_crypto_ops.input_swap(input);
-+}
-+
-+static inline u32 deu_endian_swap(u32 input)
-+{
-+ return lq_crypto_ops.endian_swap(input);
-+}
-+
-+#ifdef CONFIG_CRYPTO_DEV_LANTIQ_DMA
-+static inline int deu_aes_dma_malloc(int value)
-+{
-+ return lq_crypto_ops.aes_dma_malloc(value);
-+}
-+
-+static inline int deu_des_dma_malloc(int value)
-+{
-+ return lq_crypto_ops.des_dma_malloc(value);
-+}
-+
-+static inline u32 *deu_dma_align(const u8 *arg,
-+ u32 *buff_alloc,
-+ int in_out,
-+ int nbytes)
-+{
-+ return lq_crypto_ops.dma_align(arg, buff_alloc, in_out, nbytes);
-+}
-+
-+static inline void deu_aes_dma_memcpy(u32 *outcopy,
-+ u32 *out_dma,
-+ u8 *out_arg,
-+ int nbytes)
-+{
-+ lq_crypto_ops.aes_dma_memcpy(outcopy, out_dma, out_arg, nbytes);
-+}
-+
-+static inline void deu_des_dma_memcpy(u32 *outcopy,
-+ u32 *out_dma,
-+ u8 *out_arg,
-+ int nbytes)
-+{
-+ lq_crypto_ops.des_dma_memcpy(outcopy, out_dma, out_arg, nbytes);
-+}
-+
-+static inline void deu_dma_free(u32 *addr)
-+{
-+ lq_crypto_ops.dma_free(addr);
-+}
-+
-+static inline int deu_dma_init(void)
-+{
-+ lq_crypto_ops.dma_init();
-+}
-+
-+static inline void deu_dma_exit(void)
-+{
-+ lq_crypto_ops.dma_exit();
-+}
-+#endif
-+
-+/* } */
-+
-+#define DEU_WAKELIST_INIT(queue) \
-+ init_waitqueue_head(&queue)
-+
-+#define DEU_WAIT_EVENT_TIMEOUT(queue, event, flags, timeout) \
-+ do { \
-+ wait_event_interruptible_timeout((queue), \
-+ test_bit((event), \
-+ &(flags)), (timeout)); \
-+ clear_bit((event), &(flags)); \
-+ }while (0)
-+
-+
-+#define DEU_WAKEUP_EVENT(queue, event, flags) \
-+ do { \
-+ set_bit((event), &(flags)); \
-+ wake_up_interruptible(&(queue)); \
-+ }while (0)
-+
-+#define DEU_WAIT_EVENT(queue, event, flags) \
-+ do { \
-+ wait_event_interruptible(queue, \
-+ test_bit((event), &(flags))); \
-+ clear_bit((event), &(flags)); \
-+ }while (0)
-+
-+struct deu_drv_priv {
-+ wait_queue_head_t deu_thread_wait;
-+#define DEU_EVENT 1
-+ volatile long deu_event_flags;
-+ u8 *deu_rx_buf;
-+ u32 deu_rx_len;
-+};
-+
-+#ifdef CRYPTO_DEBUG
-+extern char deu_debug_level;
-+# define DPRINTF(level, format, args...) \
-+ if (level < deu_debug_level) \
-+ printk(KERN_INFO "[%s %s %d]: " format, \
-+ __FILE__, __func__, __LINE__, ##args)
-+#else
-+# define DPRINTF(level, format, args...) do { } while(0)
-+#endif
-+
-+#endif /* DEU_H */
---- /dev/null
-+++ b/drivers/crypto/lantiq/deu_ar9.c
-@@ -0,0 +1,327 @@
-+/*
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
-+ *
-+ * Copyright (C) 2010 Ralph Hempel <ralph.hempel@lantiq.com>
-+ * Copyright (C) 2009 Mohammad Firdaus
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/init.h>
-+#include <linux/types.h>
-+#include <linux/errno.h>
-+#include <asm/io.h> /* dma_cache_inv */
-+#include <linux/platform_device.h>
-+
-+#ifdef CONFIG_SOC_LANTIQ_XWAY
-+
-+#include "deu.h"
-+
-+/**
-+ \defgroup LQ_DEU LQ_DEU_DRIVERS
-+ \ingroup API
-+ \brief Lantiq DEU driver module
-+*/
-+
-+/**
-+ \file deu_ar9.c
-+ \brief Lantiq DEU board specific driver file for ar9
-+*/
-+
-+/**
-+ \defgroup BOARD_SPECIFIC_FUNCTIONS LQ_BOARD_SPECIFIC_FUNCTIONS
-+ \ingroup LQ_DEU
-+ \brief board specific functions
-+*/
-+
-+#ifdef CONFIG_CRYPTO_DEV_LANTIQ_DMA
-+struct lq_deu_device lq_deu[1];
-+
-+static u8 *g_dma_page_ptr = NULL;
-+static u8 *g_dma_block = NULL;
-+static u8 *g_dma_block2 = NULL;
-+
-+/** \fn int dma_init(void)
-+ * \ingroup BOARD_SPECIFIC_FUNCTIONS
-+ * \brief Initialize DMA for DEU usage. DMA specific registers are
-+ * intialized here, including a pointer to the device, memory
-+ * space for the device and DEU-DMA descriptors
-+ * \return -1: fail, 0: SUCCESS
-+*/
-+static int dma_init(void)
-+{
-+ volatile struct deu_dma *dma = (struct deu_dma *) LQ_DEU_DMA_CON;
-+ struct dma_device_info *dma_device = NULL;
-+ int i = 0;
-+
-+ struct dma_device_info *deu_dma_device_ptr;
-+
-+ /* get one free page and share between g_dma_block and g_dma_block2 */
-+ printk("PAGE_SIZE = %ld\n", PAGE_SIZE);
-+ /* need 16-byte alignment memory block */
-+ g_dma_page_ptr = (u8 *)__get_free_page(GFP_KERNEL);
-+ /* need 16-byte alignment memory block */
-+ g_dma_block = g_dma_page_ptr;
-+ /* need 16-byte alignment memory block */
-+ g_dma_block2 = (u8 *)(g_dma_page_ptr + (PAGE_SIZE >> 1));
-+
-+ /* deu_dma_priv_init(); */
-+
-+ deu_dma_device_ptr = dma_device_reserve("DEU");
-+ if (!deu_dma_device_ptr) {
-+ printk("DEU: reserve DMA fail!\n");
-+ return -1;
-+ }
-+ lq_deu[0].dma_device = deu_dma_device_ptr;
-+
-+ dma_device = deu_dma_device_ptr;
-+ /* dma_device->priv = &deu_dma_priv; */
-+ dma_device->buffer_alloc = &deu_dma_buffer_alloc;
-+ dma_device->buffer_free = &deu_dma_buffer_free;
-+ dma_device->intr_handler = &deu_dma_intr_handler;
-+
-+ dma_device->tx_endianness_mode = LQ_DMA_ENDIAN_TYPE3;
-+ dma_device->rx_endianness_mode = LQ_DMA_ENDIAN_TYPE3;
-+ dma_device->port_num = 1;
-+ dma_device->tx_burst_len = 2;
-+ dma_device->rx_burst_len = 2;
-+ dma_device->max_rx_chan_num = 1;
-+ dma_device->max_tx_chan_num = 1;
-+ dma_device->port_packet_drop_enable = 0;
-+
-+ for (i = 0; i < dma_device->max_rx_chan_num; i++) {
-+ dma_device->rx_chan[i]->packet_size = DEU_MAX_PACKET_SIZE;
-+ dma_device->rx_chan[i]->desc_len = 1;
-+ dma_device->rx_chan[i]->control = LQ_DMA_CH_ON;
-+ dma_device->rx_chan[i]->byte_offset = 0;
-+ dma_device->rx_chan[i]->chan_poll_enable = 1;
-+ }
-+
-+ for (i = 0; i < dma_device->max_tx_chan_num; i++) {
-+ dma_device->tx_chan[i]->control = LQ_DMA_CH_ON;
-+ dma_device->tx_chan[i]->desc_len = 1;
-+ dma_device->tx_chan[i]->chan_poll_enable = 1;
-+ }
-+
-+ dma_device->current_tx_chan = 0;
-+ dma_device->current_rx_chan = 0;
-+
-+ i = dma_device_register(dma_device);
-+ for (i = 0; i < dma_device->max_rx_chan_num; i++) {
-+ (dma_device->rx_chan[i])->open(dma_device->rx_chan[i]);
-+ }
-+
-+ dma->ctrl.BS = 0;
-+ dma->ctrl.RXCLS = 0;
-+ dma->ctrl.EN = 1;
-+
-+ return 0;
-+}
-+
-+/** \fn u32 *dma_align(const u8 *arg, u32 *buffer_alloc, int in_buff, int nbytes)
-+ * \ingroup BOARD_SPECIFIC_FUNCTIONS
-+ * \brief Not used for AR9
-+ * \param arg Pointer to the input / output memory address
-+ * \param buffer_alloc A pointer to the buffer
-+ * \param in_buff Input (if == 1) or Output (if == 0) buffer
-+ * \param nbytes Number of bytes of data
-+*/
-+static u32 *dma_align(const u8 *arg, u32 *buffer_alloc, int in_buff, int nbytes)
-+{
-+ return (u32 *) arg;
-+}
-+
-+/** \fn void aes_dma_memcpy(u32 *outcopy, u32 *out_dma, u8 *out_arg, int nbytes)
-+ * \ingroup BOARD_SPECIFIC_FUNCTIONS
-+ * \brief copy the DMA data to the memory address space for AES
-+ * \param outcopy Not used
-+ * \param out_dma A pointer to the memory address that stores the DMA data
-+ * \param out_arg The pointer to the memory address that needs to be copied to]
-+ * \param nbytes Number of bytes of data
-+*/
-+static void aes_dma_memcpy(u32 *outcopy, u32 *out_dma, u8 *out_arg, int nbytes)
-+{
-+ memcpy(out_arg, out_dma, nbytes);
-+}
-+
-+/** \fn void des_dma_memcpy(u32 *outcopy, u32 *out_dma, u8 *out_arg, int nbytes)
-+ * \ingroup BOARD_SPECIFIC_FUNCTIONS
-+ * \brief copy the DMA data to the memory address space for DES
-+ * \param outcopy Not used
-+ * \param out_dma A pointer to the memory address that stores the DMA data
-+ * \param out_arg The pointer to the memory address that needs to be copied to]
-+ * \param nbytes Number of bytes of data
-+*/
-+static void des_dma_memcpy(u32 *outcopy, u32 *out_dma, u8 *out_arg, int nbytes)
-+{
-+ memcpy(out_arg, out_dma, nbytes);
-+}
-+
-+/** \fn dma_exit(void)
-+ * \ingroup BOARD_SPECIFIC_FUNCTIONS
-+ * \brief unregister dma devices after exit
-+*/
-+static void dma_exit(void)
-+{
-+ if (g_dma_page_ptr)
-+ free_page((u32) g_dma_page_ptr);
-+ dma_device_release(lq_deu[0].dma_device);
-+ dma_device_unregister(lq_deu[0].dma_device);
-+}
-+#endif /* CONFIG_CRYPTO_DEV_LANTIQ_DMA */
-+
-+/** \fn u32 endian_swap(u32 input)
-+ * \ingroup BOARD_SPECIFIC_FUNCTIONS
-+ * \brief Swap data given to the function
-+ * \param input Data input to be swapped
-+ * \return either the swapped data or the input data depending on whether it is in DMA mode or FPI mode
-+*/
-+static u32 endian_swap(u32 input)
-+{
-+#ifdef CONFIG_CRYPTO_DEV_LANTIQ_DMA
-+ u8 *ptr = (u8 *)&input;
-+ return ((ptr[3] << 24) | (ptr[2] << 16) | (ptr[1] << 8) | ptr[0]);
-+#else
-+ return input;
-+#endif
-+}
-+
-+/** \fn u32 input_swap(u32 input)
-+ * \ingroup BOARD_SPECIFIC_FUNCTIONS
-+ * \brief Not used
-+ * \return input
-+*/
-+static u32 input_swap(u32 input)
-+{
-+ return input;
-+}
-+
-+/** \fn void aes_chip_init(void)
-+ * \ingroup BOARD_SPECIFIC_FUNCTIONS
-+ * \brief initialize AES hardware
-+*/
-+static void aes_chip_init(void)
-+{
-+ volatile struct deu_aes *aes = (struct deu_aes *) AES_START;
-+
-+ aes->ctrl.SM = 1;
-+#ifndef CONFIG_CRYPTO_DEV_LANTIQ_DMA
-+ aes->ctrl.ARS = 1;
-+#else
-+ aes->ctrl.NDC = 1; /* to write to ENDI */
-+ asm("sync");
-+ aes->ctrl.ENDI = 0;
-+ asm("sync");
-+ aes->ctrl.ARS = 0; /* 0 for dma */
-+ asm("sync");
-+#endif
-+}
-+
-+/** \fn void des_chip_init(void)
-+ * \ingroup BOARD_SPECIFIC_FUNCTIONS
-+ * \brief initialize DES hardware
-+*/
-+static void des_chip_init(void)
-+{
-+ volatile struct deu_des *des = (struct deu_des *) DES_3DES_START;
-+
-+#ifndef CONFIG_CRYPTO_DEV_LANTIQ_DMA
-+ /* start crypto engine with write to ILR */
-+ des->ctrl.SM = 1;
-+ asm("sync");
-+ des->ctrl.ARS = 1;
-+#else
-+ des->ctrl.SM = 1;
-+ des->ctrl.NDC = 1;
-+ asm("sync");
-+ des->ctrl.ENDI = 0;
-+ asm("sync");
-+ des->ctrl.ARS = 0; /* 0 for dma */
-+
-+#endif
-+}
-+
-+static u32 chip_init(void)
-+{
-+ volatile struct deu_clk_ctrl *clc = (struct deu_clk_ctrl *) LQ_DEU_CLK;
-+
-+#if 0
-+ lq_pmu_enable(1<<20);
-+#endif
-+
-+ clc->FSOE = 0;
-+ clc->SBWE = 0;
-+ clc->SPEN = 0;
-+ clc->SBWE = 0;
-+ clc->DISS = 0;
-+ clc->DISR = 0;
-+
-+ return *LQ_DEU_ID;
-+}
-+
-+static int lq_crypto_probe(struct platform_device *pdev)
-+{
-+#ifdef CONFIG_CRYPTO_DEV_LANTIQ_DMA
-+ lq_crypto_ops.dma_init = dma_init;
-+ lq_crypto_ops.dma_exit = dma_exit;
-+ lq_crypto_ops.aes_dma_memcpy = aes_dma_memcpy;
-+ lq_crypto_ops.des_dma_memcpy = des_dma_memcpy;
-+ lq_crypto_ops.aes_dma_malloc = aes_dma_malloc;
-+ lq_crypto_ops.des_dma_malloc = des_dma_malloc;
-+ lq_crypto_ops.dma_align = dma_align;
-+ lq_crypto_ops.dma_free = dma_free;
-+#endif
-+
-+ lq_crypto_ops.endian_swap = endian_swap;
-+ lq_crypto_ops.input_swap = input_swap;
-+ lq_crypto_ops.aes_chip_init = aes_chip_init;
-+ lq_crypto_ops.des_chip_init = des_chip_init;
-+ lq_crypto_ops.chip_init = chip_init;
-+
-+ printk("lq_ar9_deu: driver loaded!\n");
-+
-+ lq_deu_init();
-+
-+ return 0;
-+}
-+
-+static int lq_crypto_remove(struct platform_device *pdev)
-+{
-+ lq_deu_exit();
-+
-+ return 0;
-+}
-+
-+static struct platform_driver lq_crypto = {
-+ .probe = lq_crypto_probe,
-+ .remove = lq_crypto_remove,
-+ .driver = {
-+ .owner = THIS_MODULE,
-+ .name = "lq_ar9_deu"
-+ }
-+};
-+
-+static int __init lq_crypto_init(void)
-+{
-+ return platform_driver_register(&lq_crypto);
-+}
-+module_init(lq_crypto_init);
-+
-+static void __exit lq_crypto_exit(void)
-+{
-+ platform_driver_unregister(&lq_crypto);
-+}
-+module_exit(lq_crypto_exit);
-+
-+#endif
---- /dev/null
-+++ b/drivers/crypto/lantiq/deu_ar9.h
-@@ -0,0 +1,291 @@
-+/*
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
-+ *
-+ * Copyright (C) 2010 Ralph Hempel <ralph.hempel@lantiq.com>
-+ * Copyright (C) 2009 Mohammad Firdaus / Infineon Technologies
-+ */
-+
-+/**
-+ \defgroup LQ_DEU LQ_DEU_DRIVERS
-+ \ingroup API
-+ \brief DEU driver module
-+*/
-+
-+/**
-+ \defgroup LQ_DEU_DEFINITIONS LQ_DEU_DEFINITIONS
-+ \ingroup LQ_DEU
-+ \brief Lantiq DEU definitions
-+*/
-+
-+/**
-+ \file deu_ar9.h
-+ \brief DEU driver header file
-+*/
-+
-+
-+#ifndef DEU_AR9_H
-+#define DEU_AR9_H
-+
-+#define LQ_DEU_BASE_ADDR (KSEG1 | 0x1E103100)
-+#define LQ_DEU_CLK ((volatile u32 *)(LQ_DEU_BASE_ADDR + 0x0000))
-+#define LQ_DEU_ID ((volatile u32 *)(LQ_DEU_BASE_ADDR + 0x0008))
-+#define LQ_DES_CON ((volatile u32 *)(LQ_DEU_BASE_ADDR + 0x0010))
-+#define LQ_AES_CON ((volatile u32 *)(LQ_DEU_BASE_ADDR + 0x0050))
-+#define LQ_HASH_CON ((volatile u32 *)(LQ_DEU_BASE_ADDR + 0x00B0))
-+#define LQ_ARC4_CON ((volatile u32 *)(LQ_DEU_BASE_ADDR + 0x0100))
-+
-+#define ARC4_START LQ_ARC4_CON
-+#define DES_3DES_START LQ_DES_CON
-+#define HASH_START LQ_HASH_CON
-+#define AES_START LQ_AES_CON
-+
-+#ifdef CONFIG_CRYPTO_DEV_DMA
-+# include "deu_dma.h"
-+# define DEU_DWORD_REORDERING(ptr, buffer, in_out, bytes) \
-+ deu_dma_align(ptr, buffer, in_out, bytes)
-+# define AES_MEMORY_COPY(outcopy, out_dma, out_arg, nbytes) \
-+ deu_aes_dma_memcpy(outcopy, out_dma, out_arg, nbytes)
-+# define DES_MEMORY_COPY(outcopy, out_dma, out_arg, nbytes) \
-+ deu_des_dma_memcpy(outcopy, out_dma, out_arg, nbytes)
-+# define BUFFER_IN 1
-+# define BUFFER_OUT 0
-+# define AES_ALGO 1
-+# define DES_ALGO 0
-+# define ALLOCATE_MEMORY(val, type) 1
-+# define FREE_MEMORY(buff)
-+extern struct lq_deu_device lq_deu[1];
-+#endif /* CONFIG_CRYPTO_DEV_DMA */
-+
-+/* SHA CONSTANTS */
-+#define HASH_CON_VALUE 0x0700002C
-+
-+#define INPUT_ENDIAN_SWAP(input) deu_input_swap(input)
-+#define DEU_ENDIAN_SWAP(input) deu_endian_swap(input)
-+#define DELAY_PERIOD 10
-+#define FIND_DEU_CHIP_VERSION chip_version()
-+
-+#define WAIT_AES_DMA_READY() \
-+ do { \
-+ int i; \
-+ volatile struct deu_dma *dma = \
-+ (struct deu_dma *) LQ_DEU_DMA_CON; \
-+ volatile struct deu_aes *aes = \
-+ (volatile struct deu_aes *) AES_START; \
-+ for (i = 0; i < 10; i++) \
-+ udelay(DELAY_PERIOD); \
-+ while (dma->ctrl.BSY) {}; \
-+ while (aes->ctrl.BUS) {}; \
-+ } while (0)
-+
-+#define WAIT_DES_DMA_READY() \
-+ do { \
-+ int i; \
-+ volatile struct deu_dma *dma = \
-+ (struct deu_dma *) LQ_DEU_DMA_CON; \
-+ volatile struct deu_des *des = \
-+ (struct deu_des *) DES_3DES_START; \
-+ for (i = 0; i < 10; i++) \
-+ udelay(DELAY_PERIOD); \
-+ while (dma->ctrl.BSY) {}; \
-+ while (des->ctrl.BUS) {}; \
-+ } while (0)
-+
-+#define AES_DMA_MISC_CONFIG() \
-+ do { \
-+ volatile struct deu_aes *aes = \
-+ (volatile struct deu_aes *) AES_START; \
-+ aes->ctrl.KRE = 1; \
-+ aes->ctrl.GO = 1; \
-+ } while(0)
-+
-+#define SHA_HASH_INIT \
-+ do { \
-+ volatile struct deu_hash *hash = \
-+ (struct deu_hash *) HASH_START; \
-+ hash->ctrl.SM = 1; \
-+ hash->ctrl.ALGO = 0; \
-+ hash->ctrl.INIT = 1; \
-+ } while(0)
-+
-+/* DEU Common Structures for AR9*/
-+
-+struct deu_clk_ctrl {
-+ u32 Res:26;
-+ u32 FSOE:1;
-+ u32 SBWE:1;
-+ u32 EDIS:1;
-+ u32 SPEN:1;
-+ u32 DISS:1;
-+ u32 DISR:1;
-+};
-+
-+struct deu_des {
-+ struct deu_des_ctrl { /* 10h */
-+ u32 KRE:1;
-+ u32 reserved1:5;
-+ u32 GO:1;
-+ u32 STP:1;
-+ u32 Res2:6;
-+ u32 NDC:1;
-+ u32 ENDI:1;
-+ u32 Res3:2;
-+ u32 F:3;
-+ u32 O:3;
-+ u32 BUS:1;
-+ u32 DAU:1;
-+ u32 ARS:1;
-+ u32 SM:1;
-+ u32 E_D:1;
-+ u32 M:3;
-+ } ctrl;
-+
-+ u32 IHR; /* 14h */
-+ u32 ILR; /* 18h */
-+ u32 K1HR; /* 1c */
-+ u32 K1LR;
-+ u32 K2HR;
-+ u32 K2LR;
-+ u32 K3HR;
-+ u32 K3LR; /* 30h */
-+ u32 IVHR; /* 34h */
-+ u32 IVLR; /* 38 */
-+ u32 OHR; /* 3c */
-+ u32 OLR; /* 40 */
-+};
-+
-+struct deu_aes {
-+ struct deu_aes_ctrl {
-+ u32 KRE:1;
-+ u32 reserved1:4;
-+ u32 PNK:1;
-+ u32 GO:1;
-+ u32 STP:1;
-+ u32 reserved2:6;
-+ u32 NDC:1;
-+ u32 ENDI:1;
-+ u32 reserved3:2;
-+ u32 F:3; /* fbs */
-+ u32 O:3; /* om */
-+ u32 BUS:1; /* bsy */
-+ u32 DAU:1;
-+ u32 ARS:1;
-+ u32 SM:1;
-+ u32 E_D:1;
-+ u32 KV:1;
-+ u32 K:2; /* KL */
-+ } ctrl;
-+
-+ u32 ID3R; /* 80h */
-+ u32 ID2R; /* 84h */
-+ u32 ID1R; /* 88h */
-+ u32 ID0R; /* 8Ch */
-+ u32 K7R; /* 90h */
-+ u32 K6R; /* 94h */
-+ u32 K5R; /* 98h */
-+ u32 K4R; /* 9Ch */
-+ u32 K3R; /* A0h */
-+ u32 K2R; /* A4h */
-+ u32 K1R; /* A8h */
-+ u32 K0R; /* ACh */
-+ u32 IV3R; /* B0h */
-+ u32 IV2R; /* B4h */
-+ u32 IV1R; /* B8h */
-+ u32 IV0R; /* BCh */
-+ u32 OD3R; /* D4h */
-+ u32 OD2R; /* D8h */
-+ u32 OD1R; /* DCh */
-+ u32 OD0R; /* E0h */
-+};
-+
-+struct deu_arc4 {
-+ struct arc4_controlr {
-+ u32 KRE:1;
-+ u32 KLEN:4;
-+ u32 KSAE:1;
-+ u32 GO:1;
-+ u32 STP:1;
-+ u32 reserved1:6;
-+ u32 NDC:1;
-+ u32 ENDI:1;
-+ u32 reserved2:8;
-+ u32 BUS:1; /* bsy */
-+ u32 reserved3:1;
-+ u32 ARS:1;
-+ u32 SM:1;
-+ u32 reserved4:4;
-+ } ctrl;
-+
-+ u32 K3R; /* 104h */
-+ u32 K2R; /* 108h */
-+ u32 K1R; /* 10Ch */
-+ u32 K0R; /* 110h */
-+ u32 IDLEN; /* 114h */
-+ u32 ID3R; /* 118h */
-+ u32 ID2R; /* 11Ch */
-+ u32 ID1R; /* 120h */
-+ u32 ID0R; /* 124h */
-+ u32 OD3R; /* 128h */
-+ u32 OD2R; /* 12Ch */
-+ u32 OD1R; /* 130h */
-+ u32 OD0R; /* 134h */
-+};
-+
-+struct deu_hash {
-+ struct deu_hash_ctrl {
-+ u32 reserved1:5;
-+ u32 KHS:1;
-+ u32 GO:1;
-+ u32 INIT:1;
-+ u32 reserved2:6;
-+ u32 NDC:1;
-+ u32 ENDI:1;
-+ u32 reserved3:7;
-+ u32 DGRY:1;
-+ u32 BSY:1;
-+ u32 reserved4:1;
-+ u32 IRCL:1;
-+ u32 SM:1;
-+ u32 KYUE:1;
-+ u32 HMEN:1;
-+ u32 SSEN:1;
-+ u32 ALGO:1;
-+ } ctrl;
-+
-+ u32 MR; /* B4h */
-+ u32 D1R; /* B8h */
-+ u32 D2R; /* BCh */
-+ u32 D3R; /* C0h */
-+ u32 D4R; /* C4h */
-+ u32 D5R; /* C8h */
-+ u32 dummy; /* CCh */
-+ u32 KIDX; /* D0h */
-+ u32 KEY; /* D4h */
-+ u32 DBN; /* D8h */
-+};
-+
-+struct deu_dma {
-+ struct deu_dma_ctrl {
-+ u32 reserved1:22;
-+ u32 BS:2;
-+ u32 BSY:1;
-+ u32 reserved2:1;
-+ u32 ALGO:2;
-+ u32 RXCLS:2;
-+ u32 reserved3:1;
-+ u32 EN:1;
-+ } ctrl;
-+};
-+
-+#endif /* DEU_AR9_H */
---- /dev/null
-+++ b/drivers/crypto/lantiq/deu_danube.c
-@@ -0,0 +1,484 @@
-+/*
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
-+ *
-+ * Copyright (C) 2010 Ralph Hempel <ralph.hempel@lantiq.com>
-+ * Copyright (C) 2009 Mohammad Firdaus
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/init.h>
-+#include <linux/types.h>
-+#include <linux/errno.h>
-+#include <asm/io.h> /* dma_cache_inv */
-+#include <linux/platform_device.h>
-+
-+#ifdef CONFIG_SOC_LANTIQ_XWAY
-+
-+#include "deu.h"
-+
-+/**
-+ \defgroup LQ_DEU LQ_DEU_DRIVERS
-+ \ingroup API
-+ \brief DEU driver module
-+*/
-+
-+/**
-+ \file deu_danube.c
-+ \ingroup LQ_DEU
-+ \brief board specific DEU driver file for danube
-+*/
-+
-+/**
-+ \defgroup BOARD_SPECIFIC_FUNCTIONS LQ_BOARD_SPECIFIC_FUNCTIONS
-+ \ingroup LQ_DEU
-+ \brief board specific DEU functions
-+*/
-+
-+static int danube_pre_1_4;
-+
-+#ifdef CONFIG_CRYPTO_DEV_LANTIQ_DMA
-+u32 *des_buff_in = NULL;
-+u32 *des_buff_out = NULL;
-+u32 *aes_buff_in = NULL;
-+u32 *aes_buff_out = NULL;
-+
-+struct lq_deu_device lq_deu[1];
-+
-+static u8 *g_dma_page_ptr = NULL;
-+static u8 *g_dma_block = NULL;
-+static u8 *g_dma_block2 = NULL;
-+
-+/** \fn int dma_init(void)
-+ * \ingroup BOARD_SPECIFIC_FUNCTIONS
-+ * \brief Initialize DMA for DEU usage. DMA specific registers are
-+ * intialized here, including a pointer to the device, memory
-+ * space for the device and DEU-DMA descriptors
-+ * \return -1 if fail, otherwise return 0
-+*/
-+static int dma_init(void)
-+{
-+ struct dma_device_info *dma_device = NULL;
-+ int i = 0;
-+ volatile struct deu_dma *dma = (struct deu_dma *) LQ_DEU_DMA_CON;
-+ struct dma_device_info *deu_dma_device_ptr;
-+
-+ /* get one free page and share between g_dma_block and g_dma_block2 */
-+ printk("PAGE_SIZE = %ld\n", PAGE_SIZE);
-+ /* need 16-byte alignment memory block */
-+ g_dma_page_ptr = (u8 *)__get_free_page(GFP_KERNEL);
-+ /* need 16-byte alignment memory block */
-+ g_dma_block = g_dma_page_ptr;
-+ /* need 16-byte alignment memory block */
-+ g_dma_block2 = (u8 *)(g_dma_page_ptr + (PAGE_SIZE >> 1));
-+
-+ deu_dma_device_ptr = dma_device_reserve("DEU");
-+ if (!deu_dma_device_ptr) {
-+ printk("DEU: reserve DMA fail!\n");
-+ return -1;
-+ }
-+ lq_deu[0].dma_device = deu_dma_device_ptr;
-+ dma_device = deu_dma_device_ptr;
-+ /* dma_device->priv = &deu_dma_priv; */
-+ dma_device->buffer_alloc = &deu_dma_buffer_alloc;
-+ dma_device->buffer_free = &deu_dma_buffer_free;
-+ dma_device->intr_handler = &deu_dma_intr_handler;
-+ dma_device->tx_endianness_mode = LQ_DMA_ENDIAN_TYPE3;
-+ dma_device->rx_endianness_mode = LQ_DMA_ENDIAN_TYPE3;
-+ dma_device->port_num = 1;
-+ dma_device->tx_burst_len = 4;
-+ dma_device->max_rx_chan_num = 1;
-+ dma_device->max_tx_chan_num = 1;
-+ dma_device->port_packet_drop_enable = 0;
-+
-+ for (i = 0; i < dma_device->max_rx_chan_num; i++) {
-+ dma_device->rx_chan[i]->packet_size = DEU_MAX_PACKET_SIZE;
-+ dma_device->rx_chan[i]->desc_len = 1;
-+ dma_device->rx_chan[i]->control = LQ_DMA_CH_ON;
-+ dma_device->rx_chan[i]->byte_offset = 0;
-+ dma_device->rx_chan[i]->chan_poll_enable = 1;
-+
-+ }
-+
-+ for (i = 0; i < dma_device->max_tx_chan_num; i++) {
-+ dma_device->tx_chan[i]->control = LQ_DMA_CH_ON;
-+ dma_device->tx_chan[i]->desc_len = 1;
-+ dma_device->tx_chan[i]->chan_poll_enable = 1;
-+ }
-+
-+ dma_device->current_tx_chan = 0;
-+ dma_device->current_rx_chan = 0;
-+
-+ dma_device_register(dma_device);
-+ for (i = 0; i < dma_device->max_rx_chan_num; i++) {
-+ (dma_device->rx_chan[i])->open(dma_device->rx_chan[i]);
-+ }
-+
-+ dma->ctrl.BS = 0;
-+ dma->ctrl.RXCLS = 0;
-+ dma->ctrl.EN = 1;
-+
-+
-+ *LQ_DMA_PS = 1;
-+
-+ /* DANUBE PRE 1.4 SOFTWARE FIX */
-+ if (danube_pre_1_4)
-+ *LQ_DMA_PCTRL = 0x14;
-+ else
-+ *LQ_DMA_PCTRL = 0xF14;
-+
-+ return 0;
-+}
-+
-+/** \fn u32 *dma_align(const u8 *arg, u32 *buffer_alloc, int in_buff, int nbytes)
-+ * \ingroup BOARD_SPECIFIC_FUNCTIONS
-+ * \brief A fix to align mis-aligned address for Danube version 1.3 chips
-+ * which has memory alignment issues.
-+ * \param arg Pointer to the input / output memory address
-+ * \param buffer_alloc A pointer to the buffer
-+ * \param in_buff Input (if == 1) or Output (if == 0) buffer
-+ * \param nbytes Number of bytes of data
-+ * \return returns arg: if address is aligned, buffer_alloc: if memory address is not aligned
-+*/
-+static u32 *dma_align(const u8 *arg, u32 *buffer_alloc, int in_buff, int nbytes)
-+{
-+ if (danube_pre_1_4) {
-+ /* for input buffer */
-+ if (in_buff) {
-+ if (((u32) arg) & 0xF) {
-+ memcpy(buffer_alloc, arg, nbytes);
-+ return (u32 *) buffer_alloc;
-+ } else {
-+ return (u32 *) arg;
-+ }
-+ }
-+ else {
-+ /* for output buffer */
-+ if (((u32) arg) & 0x3)
-+ return buffer_alloc;
-+ else
-+ return (u32 *) arg;
-+ }
-+ }
-+
-+ return (u32 *) arg;
-+}
-+
-+/** \fn void aes_dma_memcpy(u32 *outcopy, u32 *out_dma, u8 *out_arg, int nbytes)
-+ * \ingroup BOARD_SPECIFIC_FUNCTIONS
-+ * \brief copy the DMA data to the memory address space for AES. The swaping
-+ * of the 4 bytes is done only for Danube version 1.3 (FIX). Otherwise,
-+ * it is a direct memory copy to out_arg pointer
-+ * \param outcopy Pointer to the address to store swapped copy
-+ * \param out_dma A pointer to the memory address that stores the DMA data
-+ * \param out_arg The pointer to the memory address that needs to be copied to
-+ * \param nbytes Number of bytes of data
-+*/
-+static void aes_dma_memcpy(u32 *outcopy, u32 *out_dma, u8 *out_arg, int nbytes)
-+{
-+ int i = 0;
-+ int x = 0;
-+
-+ /* DANUBE PRE 1.4 SOFTWARE FIX */
-+ if (danube_pre_1_4) {
-+ for (i = 0; i < (nbytes / 4); i++) {
-+ x = i ^ 0x3;
-+ outcopy[i] = out_dma[x];
-+
-+ }
-+ if (((u32) out_arg) & 0x3) {
-+ memcpy((u8 *)out_arg, outcopy, nbytes);
-+ }
-+ } else {
-+ memcpy(out_arg, out_dma, nbytes);
-+ }
-+}
-+
-+/** \fn void des_dma_memcpy(u32 *outcopy, u32 *out_dma, u8 *out_arg, int nbytes)
-+ * \ingroup BOARD_SPECIFIC_FUNCTIONS
-+ * \brief copy the DMA data to the memory address space for DES. The swaping
-+ * of the 4 bytes is done only for Danube version 1.3 (FIX). Otherwise,
-+ * it is a direct memory copy to out_arg pointer
-+ * \param outcopy Pointer to the address to store swapped copy
-+ * \param out_dma A pointer to the memory address that stores the DMA data
-+ * \param out_arg The pointer to the memory address that needs to be copied to
-+ * \param nbytes Number of bytes of data
-+*/
-+static void des_dma_memcpy(u32 *outcopy, u32 *out_dma, u8 *out_arg, int nbytes)
-+{
-+ int i = 0;
-+ int x = 0;
-+
-+ /* DANUBE PRE 1.4 SOFTWARE FIX */
-+ if (danube_pre_1_4) {
-+ for (i = 0; i < (nbytes / 4); i++) {
-+ x = i ^ 1;
-+ outcopy[i] = out_dma[x];
-+
-+ }
-+ if (((u32) out_arg) & 0x3) {
-+ memcpy((u8 *)out_arg, outcopy, nbytes);
-+ }
-+ } else {
-+ memcpy(out_arg, out_dma, nbytes);
-+ }
-+}
-+
-+/** \fn int des_dma_malloc(int value)
-+ * \ingroup BOARD_SPECIFIC_FUNCTIONS
-+ * \brief allocates memory to the necessary memory input/output buffer
-+ * location, used during the DES algorithm DMA transfer (memory
-+ * alignment issues)
-+ * \param value value determinds whether the calling of the function is for a
-+ * input buffer or for an output buffer memory allocation
-+*/
-+static int des_dma_malloc(int value)
-+{
-+ if (danube_pre_1_4) {
-+ if (value == BUFFER_IN) {
-+ des_buff_in = kmalloc(DEU_MAX_PACKET_SIZE, GFP_ATOMIC);
-+ if (!des_buff_in)
-+ return -1;
-+ else
-+ return 0;
-+ }
-+ else {
-+ des_buff_out = kmalloc(DEU_MAX_PACKET_SIZE, GFP_ATOMIC);
-+ if (!des_buff_out)
-+ return -1;
-+ else
-+ return 0;
-+ }
-+ } else {
-+ return 0;
-+ }
-+}
-+
-+/** \fn int aes_dma_malloc(int value)
-+ * \ingroup BOARD_SPECIFIC_FUNCTIONS
-+ * \brief allocates memory to the necessary memory input/output buffer
-+ * location, used during the AES algorithm DMA transfer (memory
-+ * alignment issues)
-+ * \param value value determinds whether the calling of the function is for a
-+ * input buffer or for an output buffer memory allocation
-+*/
-+static int aes_dma_malloc(int value)
-+{
-+ if (danube_pre_1_4) {
-+ if (value == BUFFER_IN) {
-+ aes_buff_in = kmalloc(DEU_MAX_PACKET_SIZE, GFP_ATOMIC);
-+ if (!aes_buff_in)
-+ return -1;
-+ else
-+ return 0;
-+ }
-+ else {
-+ aes_buff_out = kmalloc(DEU_MAX_PACKET_SIZE, GFP_ATOMIC);
-+ if (!aes_buff_out)
-+ return -1;
-+ else
-+ return 0;
-+ }
-+ } else {
-+ return 0;
-+ }
-+}
-+
-+/** \fn void dma_free(u32 *addr)
-+ * \ingroup BOARD_SPECIFIC_FUNCTIONS
-+ * \brief frees previously allocated memory
-+ * \param addr memory address of the buffer that needs to be freed
-+*/
-+static void dma_free(u32 *addr)
-+{
-+ if (addr)
-+ kfree(addr);
-+ return;
-+}
-+
-+/** \fn dma_exit(void)
-+ * \ingroup BOARD_SPECIFIC_FUNCTIONS
-+ * \brief unregister dma devices after exit
-+*/
-+static void dma_exit(void)
-+{
-+ if (g_dma_page_ptr)
-+ free_page((u32) g_dma_page_ptr);
-+ dma_device_release(lq_deu[0].dma_device);
-+ dma_device_unregister(lq_deu[0].dma_device);
-+}
-+#endif /* CONFIG_CRYPTO_DEV_LANTIQ_DMA */
-+
-+/** \fn u32 endian_swap(u32 input)
-+ * \ingroup BOARD_SPECIFIC_FUNCTIONS
-+ * \brief function is not used
-+ * \param input Data input to be swapped
-+ * \return input
-+*/
-+static u32 endian_swap(u32 input)
-+{
-+ return input;
-+}
-+
-+/** \fn u32 input_swap(u32 input)
-+ * \ingroup BOARD_SPECIFIC_FUNCTIONS
-+ * \brief Swap the input data if the current chip is Danube version
-+ * 1.4 and do nothing to the data if the current chip is
-+ * Danube version 1.3
-+ * \param input data that needs to be swapped
-+ * \return input or swapped input
-+*/
-+static u32 input_swap(u32 input)
-+{
-+ if (!danube_pre_1_4) {
-+ u8 *ptr = (u8 *)&input;
-+ return ((ptr[3] << 24) | (ptr[2] << 16) | (ptr[1] << 8) | ptr[0]);
-+ } else {
-+ return input;
-+ }
-+}
-+
-+/** \fn void aes_chip_init(void)
-+ * \ingroup BOARD_SPECIFIC_FUNCTIONS
-+ * \brief initialize AES hardware
-+*/
-+static void aes_chip_init(void)
-+{
-+ volatile struct deu_aes *aes = (struct deu_aes *) AES_START;
-+
-+#ifndef CONFIG_CRYPTO_DEV_LANTIQ_DMA
-+ /* start crypto engine with write to ILR */
-+ aes->ctrl.SM = 1;
-+ aes->ctrl.ARS = 1;
-+#else
-+ aes->ctrl.SM = 1;
-+ aes->ctrl.ARS = 1; /* 0 for dma */
-+#endif
-+}
-+
-+/** \fn void des_chip_init(void)
-+ * \ingroup BOARD_SPECIFIC_FUNCTIONS
-+ * \brief initialize DES hardware
-+*/
-+static void des_chip_init(void)
-+{
-+ volatile struct deu_des *des = (struct deu_des *) DES_3DES_START;
-+
-+#ifndef CONFIG_CRYPTO_DEV_LANTIQ_DMA
-+ /* start crypto engine with write to ILR */
-+ des->ctrl.SM = 1;
-+ des->ctrl.ARS = 1;
-+#else
-+ des->ctrl.SM = 1;
-+ des->ctrl.ARS = 1; /* 0 for dma */
-+#endif
-+}
-+
-+/** \fn void deu_chip_version(void)
-+ * \ingroup LQ_DES_FUNCTIONS
-+ * \brief To find the version of the chip by looking at the chip ID
-+ * \param danube_pre_1_4 (sets to 1 if Chip is Danube less than v1.4)
-+*/
-+static void deu_chip_version(void)
-+{
-+ /* DANUBE PRE 1.4 SOFTWARE FIX */
-+ int chip_id = 0;
-+ chip_id = *LQ_MPS_CHIPID;
-+ chip_id >>= 28;
-+
-+ if (chip_id >= 4) {
-+ danube_pre_1_4 = 0;
-+ printk("Danube Chip ver. 1.4 detected. \n");
-+ }
-+ else {
-+ danube_pre_1_4 = 1;
-+ printk("Danube Chip ver. 1.3 or below detected. \n");
-+ }
-+}
-+
-+static u32 chip_init(void)
-+{
-+ volatile struct deu_clk_ctrl *clc = (struct deu_clk_ctrl *) LQ_DEU_CLK;
-+
-+#if 0
-+ lq_pmu_enable(1<<20);
-+#endif
-+
-+ deu_chip_version();
-+
-+ clc->FSOE = 0;
-+ clc->SBWE = 0;
-+ clc->SPEN = 0;
-+ clc->SBWE = 0;
-+ clc->DISS = 0;
-+ clc->DISR = 0;
-+
-+ return *LQ_DEU_ID;
-+}
-+
-+static int lq_crypto_probe(struct platform_device *pdev)
-+{
-+#ifdef CONFIG_CRYPTO_DEV_LANTIQ_DMA
-+ lq_crypto_ops.dma_init = dma_init;
-+ lq_crypto_ops.dma_exit = dma_exit;
-+ lq_crypto_ops.aes_dma_memcpy = aes_dma_memcpy;
-+ lq_crypto_ops.des_dma_memcpy = des_dma_memcpy;
-+ lq_crypto_ops.aes_dma_malloc = aes_dma_malloc;
-+ lq_crypto_ops.des_dma_malloc = des_dma_malloc;
-+ lq_crypto_ops.dma_align = dma_align;
-+ lq_crypto_ops.dma_free = dma_free;
-+#endif
-+
-+ lq_crypto_ops.endian_swap = endian_swap;
-+ lq_crypto_ops.input_swap = input_swap;
-+ lq_crypto_ops.aes_chip_init = aes_chip_init;
-+ lq_crypto_ops.des_chip_init = des_chip_init;
-+ lq_crypto_ops.chip_init = chip_init;
-+
-+ printk("lq_danube_deu: driver loaded!\n");
-+
-+ lq_deu_init();
-+
-+ return 0;
-+}
-+
-+static int lq_crypto_remove(struct platform_device *pdev)
-+{
-+ lq_deu_exit();
-+
-+ return 0;
-+}
-+
-+static struct platform_driver lq_crypto = {
-+ .probe = lq_crypto_probe,
-+ .remove = lq_crypto_remove,
-+ .driver = {
-+ .owner = THIS_MODULE,
-+ .name = "lq_danube_deu"
-+ }
-+};
-+
-+static int __init lq_crypto_init(void)
-+{
-+ return platform_driver_register(&lq_crypto);
-+}
-+module_init(lq_crypto_init);
-+
-+static void __exit lq_crypto_exit(void)
-+{
-+ platform_driver_unregister(&lq_crypto);
-+}
-+module_exit(lq_crypto_exit);
-+
-+#endif
---- /dev/null
-+++ b/drivers/crypto/lantiq/deu_danube.h
-@@ -0,0 +1,255 @@
-+/*
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
-+ *
-+ * Copyright (C) 2010 Ralph Hempel <ralph.hempel@lantiq.com>
-+ * Copyright (C) 2009 Mohammad Firdaus / Infineon Technologies
-+ */
-+
-+/**
-+ \defgroup LQ_DEU LQ_DEU_DRIVERS
-+ \ingroup API
-+ \brief DEU driver module
-+*/
-+
-+/**
-+ \file deu_danube.h
-+ \brief board specific driver header file for danube
-+*/
-+
-+/**
-+ \defgroup BOARD_SPECIFIC_FUNCTIONS LQ_BOARD_SPECIFIC_FUNCTIONS
-+ \ingroup LQ_DEU
-+ \brief board specific DEU header files
-+*/
-+
-+#ifndef DEU_DANUBE_H
-+#define DEU_DANUBE_H
-+
-+#define LQ_DEU_BASE_ADDR (KSEG1 | 0x1E103100)
-+#define LQ_DEU_CLK ((volatile u32 *)(LQ_DEU_BASE_ADDR + 0x0000))
-+#define LQ_DEU_ID ((volatile u32 *)(LQ_DEU_BASE_ADDR + 0x0008))
-+#define LQ_DES_CON ((volatile u32 *)(LQ_DEU_BASE_ADDR + 0x0010))
-+#define LQ_AES_CON ((volatile u32 *)(LQ_DEU_BASE_ADDR + 0x0050))
-+#define LQ_HASH_CON ((volatile u32 *)(LQ_DEU_BASE_ADDR + 0x00B0))
-+#define LQ_ARC4_CON ((volatile u32 *)(LQ_DEU_BASE_ADDR + 0x0100))
-+
-+#define ARC4_START LQ_ARC4_CON
-+#define DES_3DES_START LQ_DES_CON
-+#define HASH_START LQ_HASH_CON
-+#define AES_START LQ_AES_CON
-+
-+#define LQ_MPS (KSEG1 | 0x1F107000)
-+#define LQ_MPS_CHIPID ((volatile u32*)(LQ_MPS + 0x0344))
-+#define LQ_MPS_CHIPID_VERSION_GET(value) (((value) >> 28) & 0xF)
-+#define LQ_MPS_CHIPID_VERSION_SET(value) (((value) & 0xF) << 28)
-+#define LQ_MPS_CHIPID_PARTNUM_GET(value) (((value) >> 12) & 0xFFFF)
-+#define LQ_MPS_CHIPID_PARTNUM_SET(value) (((value) & 0xFFFF) << 12)
-+#define LQ_MPS_CHIPID_MANID_GET(value) (((value) >> 1) & 0x7FF)
-+#define LQ_MPS_CHIPID_MANID_SET(value) (((value) & 0x7FF) << 1)
-+
-+#ifdef CONFIG_CRYPTO_DEV_DMA
-+# define DEU_DWORD_REORDERING(ptr, buffer, in_out, bytes) \
-+ deu_dma_align(ptr, buffer, in_out, bytes)
-+# define AES_MEMORY_COPY(outcopy, out_dma, out_arg, nbytes) \
-+ deu_aes_dma_memcpy(outcopy, out_dma, out_arg, nbytes)
-+# define DES_MEMORY_COPY(outcopy, out_dma, out_arg, nbytes) \
-+ deu_des_dma_memcpy(outcopy, out_dma, out_arg, nbytes)
-+# define BUFFER_IN 1
-+# define BUFFER_OUT 0
-+# define DELAY_PERIOD 9
-+# define AES_ALGO 1
-+# define DES_ALGO 0
-+# define FREE_MEMORY(buff) deu_dma_free(buff)
-+# define ALLOCATE_MEMORY(val, type) type ? \
-+ deu_aes_dma_malloc(val) : \
-+ deu_des_dma_malloc(val)
-+#endif /* CONFIG_CRYPTO_DEV_DMA */
-+
-+#define INPUT_ENDIAN_SWAP(input) deu_input_swap(input)
-+#define DEU_ENDIAN_SWAP(input) deu_endian_swap(input)
-+#define AES_DMA_MISC_CONFIG()
-+
-+#define WAIT_AES_DMA_READY() \
-+ do { \
-+ int i; \
-+ volatile struct deu_dma *dma = \
-+ (struct deu_dma *) LQ_DEU_DMA_CON; \
-+ volatile struct deu_aes *aes = \
-+ (volatile struct deu_aes *) AES_START; \
-+ for (i = 0; i < 10; i++) \
-+ udelay(DELAY_PERIOD); \
-+ while (dma->ctrl.BSY) {}; \
-+ while (aes->ctrl.BUS) {}; \
-+ } while (0)
-+
-+#define WAIT_DES_DMA_READY() \
-+ do { \
-+ int i; \
-+ volatile struct deu_dma *dma = \
-+ (struct deu_dma *) LQ_DEU_DMA_CON; \
-+ volatile struct deu_des *des = \
-+ (struct deu_des *) DES_3DES_START; \
-+ for (i = 0; i < 10; i++) \
-+ udelay(DELAY_PERIOD); \
-+ while (dma->ctrl.BSY) {}; \
-+ while (des->ctrl.BUS) {}; \
-+ } while (0)
-+
-+#define SHA_HASH_INIT \
-+ do { \
-+ volatile struct deu_hash *hash = \
-+ (struct deu_hash *) HASH_START; \
-+ hash->ctrl.SM = 1; \
-+ hash->ctrl.ALGO = 0; \
-+ hash->ctrl.INIT = 1; \
-+ } while(0)
-+
-+/* DEU STRUCTURES */
-+
-+struct deu_clk_ctrl {
-+ u32 Res:26;
-+ u32 FSOE:1;
-+ u32 SBWE:1;
-+ u32 EDIS:1;
-+ u32 SPEN:1;
-+ u32 DISS:1;
-+ u32 DISR:1;
-+};
-+
-+struct deu_des {
-+ struct deu_des_ctrl {
-+ u32 KRE:1;
-+ u32 reserved1:5;
-+ u32 GO:1;
-+ u32 STP:1;
-+ u32 Res2:6;
-+ u32 NDC:1;
-+ u32 ENDI:1;
-+ u32 Res3:2;
-+ u32 F:3;
-+ u32 O:3;
-+ u32 BUS:1;
-+ u32 DAU:1;
-+ u32 ARS:1;
-+ u32 SM:1;
-+ u32 E_D:1;
-+ u32 M:3;
-+ } ctrl;
-+
-+ u32 IHR;
-+ u32 ILR;
-+ u32 K1HR;
-+ u32 K1LR;
-+ u32 K2HR;
-+ u32 K2LR;
-+ u32 K3HR;
-+ u32 K3LR;
-+ u32 IVHR;
-+ u32 IVLR;
-+ u32 OHR;
-+ u32 OLR;
-+};
-+
-+struct deu_aes {
-+ struct deu_aes_ctrl {
-+ u32 KRE:1;
-+ u32 reserved1:4;
-+ u32 PNK:1;
-+ u32 GO:1;
-+ u32 STP:1;
-+ u32 reserved2:6;
-+ u32 NDC:1;
-+ u32 ENDI:1;
-+ u32 reserved3:2;
-+ u32 F:3; /* fbs */
-+ u32 O:3; /* om */
-+ u32 BUS:1; /* bsy */
-+ u32 DAU:1;
-+ u32 ARS:1;
-+ u32 SM:1;
-+ u32 E_D:1;
-+ u32 KV:1;
-+ u32 K:2; /* KL */
-+ } ctrl;
-+
-+ u32 ID3R; /* 80h */
-+ u32 ID2R; /* 84h */
-+ u32 ID1R; /* 88h */
-+ u32 ID0R; /* 8Ch */
-+ u32 K7R; /* 90h */
-+ u32 K6R; /* 94h */
-+ u32 K5R; /* 98h */
-+ u32 K4R; /* 9Ch */
-+ u32 K3R; /* A0h */
-+ u32 K2R; /* A4h */
-+ u32 K1R; /* A8h */
-+ u32 K0R; /* ACh */
-+ u32 IV3R; /* B0h */
-+ u32 IV2R; /* B4h */
-+ u32 IV1R; /* B8h */
-+ u32 IV0R; /* BCh */
-+ u32 OD3R; /* D4h */
-+ u32 OD2R; /* D8h */
-+ u32 OD1R; /* DCh */
-+ u32 OD0R; /* E0h */
-+};
-+
-+struct deu_hash {
-+ struct deu_hash_ctrl {
-+ u32 reserved1:5;
-+ u32 KHS:1;
-+ u32 GO:1;
-+ u32 INIT:1;
-+ u32 reserved2:6;
-+ u32 NDC:1;
-+ u32 ENDI:1;
-+ u32 reserved3:7;
-+ u32 DGRY:1;
-+ u32 BSY:1;
-+ u32 reserved4:1;
-+ u32 IRCL:1;
-+ u32 SM:1;
-+ u32 KYUE:1;
-+ u32 HMEN:1;
-+ u32 SSEN:1;
-+ u32 ALGO:1;
-+ } ctrl;
-+
-+ u32 MR; /* B4h */
-+ u32 D1R; /* B8h */
-+ u32 D2R; /* BCh */
-+ u32 D3R; /* C0h */
-+ u32 D4R; /* C4h */
-+ u32 D5R; /* C8h */
-+ u32 dummy; /* CCh */
-+ u32 KIDX; /* D0h */
-+ u32 KEY; /* D4h */
-+ u32 DBN; /* D8h */
-+};
-+
-+struct deu_dma {
-+ struct deu_dma_ctrl {
-+ u32 reserved1:22;
-+ u32 BS:2;
-+ u32 BSY:1;
-+ u32 reserved2:1;
-+ u32 ALGO:2;
-+ u32 RXCLS:2;
-+ u32 reserved3:1;
-+ u32 EN:1;
-+ } ctrl;
-+};
-+
-+#endif /* DEU_DANUBE_H */
---- /dev/null
-+++ b/drivers/crypto/lantiq/deu_dma.c
-@@ -0,0 +1,147 @@
-+/*
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
-+ *
-+ * Copyright (C) 2010 Ralph Hempel <ralph.hempel@lantiq.com>
-+ * Copyright (C) 2009 Mohammad Firdaus
-+ */
-+
-+/**
-+ \defgroup LQ_DEU LQ_DEU_DRIVERS
-+ \ingroup LQ_API
-+ \brief Lantiq DEU driver module
-+*/
-+
-+/**
-+ \file deu_dma.c
-+ \ingroup LQ_DEU
-+ \brief DMA DEU driver file
-+*/
-+
-+/**
-+ \defgroup LQ_DMA_FUNCTIONS LQ_DMA_FUNCTIONS
-+ \ingroup LQ_DEU
-+ \brief DMA DEU driver functions
-+*/
-+
-+#include <linux/module.h>
-+#include <linux/init.h>
-+#include <linux/types.h>
-+#include <linux/errno.h>
-+#include <linux/delay.h>
-+#include <asm/io.h>
-+#include "deu.h"
-+#include "deu_dma.h"
-+
-+/* extern struct deu_drv_priv deu_dma_priv; */
-+
-+/** \fn int deu_dma_intr_handler(struct dma_device_info *dma_dev, int status)
-+ * \ingroup LQ_DMA_FUNCTIONS
-+ * \brief callback function for DEU DMA interrupt
-+ * \param dma_dev dma device
-+ * \param status not used
-+*/
-+int deu_dma_intr_handler(struct dma_device_info *dma_dev, int status)
-+{
-+#if 0
-+ int len = 0;
-+ while (len <= 20000) { len++; }
-+ u8 *buf;
-+ int len = 0;
-+
-+ struct deu_drv_priv *deu_priv = (struct deu_drv_priv *)dma_dev->priv;
-+ /* printk("status:%d \n",status); */
-+ switch(status) {
-+ case RCV_INT:
-+ len = dma_device_read(dma_dev, (u8 **)&buf, NULL);
-+ if ( len != deu_priv->deu_rx_len) {
-+ printk(KERN_ERR "%s packet length %d is not "
-+ "equal to expect %d\n",
-+ __func__, len, deu_priv->deu_rx_len);
-+ return -1;
-+ }
-+ memcpy(deu_priv->deu_rx_buf, buf, deu_priv->deu_rx_len);
-+ /* Reset for next usage */
-+ deu_priv->deu_rx_buf = NULL;
-+ deu_priv->deu_rx_len = 0;
-+ DEU_WAKEUP_EVENT(deu_priv->deu_thread_wait, DEU_EVENT,
-+ deu_priv->deu_event_flags);
-+ break;
-+ case TX_BUF_FULL_INT:
-+ /* delay for buffer to be cleared */
-+ while (len <= 20000) { len++; }
-+ break;
-+
-+ case TRANSMIT_CPT_INT:
-+ break;
-+ default:
-+ break;
-+ }
-+#endif
-+ return 0;
-+}
-+
-+extern u8 *g_dma_block;
-+extern u8 *g_dma_block2;
-+
-+/** \fn u8 *deu_dma_buffer_alloc(int len, int *byte_offset, void **opt)
-+ * \ingroup LQ_DMA_FUNCTIONS
-+ * \brief callback function for allocating buffers for dma receive descriptors
-+ * \param len not used
-+ * \param byte_offset dma byte offset
-+ * \param *opt not used
-+ *
-+*/
-+u8 *deu_dma_buffer_alloc(int len, int *byte_offset, void **opt)
-+{
-+ u8 *swap = NULL;
-+
-+ /* dma-core needs at least 2 blocks of memory */
-+ swap = g_dma_block;
-+ g_dma_block = g_dma_block2;
-+ g_dma_block2 = swap;
-+
-+ /* dma_cache_wback_inv((unsigned long) g_dma_block,(PAGE_SIZE >> 1)); */
-+ *byte_offset = 0;
-+
-+ return g_dma_block;
-+}
-+
-+/** \fn int deu_dma_buffer_free(u8 * dataptr, void *opt)
-+ * \ingroup LQ_DMA_FUNCTIONS
-+ * \brief callback function for freeing dma transmit descriptors
-+ * \param dataptr data pointer to be freed
-+ * \param opt not used
-+*/
-+int deu_dma_buffer_free(u8 *dataptr, void *opt)
-+{
-+#if 0
-+ printk("Trying to free memory buffer\n");
-+ if (dataptr == NULL && opt == NULL)
-+ return 0;
-+ else if (opt == NULL) {
-+ kfree(dataptr);
-+ return 1;
-+ }
-+ else if (dataptr == NULL) {
-+ kfree(opt);
-+ return 1;
-+ }
-+ else {
-+ kfree(opt);
-+ kfree(dataptr);
-+ }
-+#endif
-+ return 0;
-+}
---- /dev/null
-+++ b/drivers/crypto/lantiq/deu_dma.h
-@@ -0,0 +1,78 @@
-+/*
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
-+ *
-+ * Copyright (C) 2010 Ralph Hempel <ralph.hempel@lantiq.com>
-+ * Copyright (C) 2009 Mohammad Firdaus
-+ */
-+
-+/**
-+ \addtogroup LQ_DEU LQ_DEU_DRIVERS
-+ \ingroup API
-+ \brief Lantiq DEU driver module
-+*/
-+
-+/**
-+ \file deu_dma.h
-+ \ingroup LQ_DEU
-+ \brief DMA DEU driver header file
-+*/
-+
-+#ifndef DEU_DMA_H
-+#define DEU_DMA_H
-+
-+#include <linux/init.h>
-+#include <linux/module.h>
-+#include <linux/mm.h>
-+#include <linux/crypto.h>
-+#include <asm/scatterlist.h>
-+#include <asm/byteorder.h>
-+#include <linux/skbuff.h>
-+#include <linux/netdevice.h>
-+
-+#include <asm/ifx/irq.h>
-+#include <asm/ifx/ifx_dma_core.h>
-+#ifndef CONFIG_CRYPTO_DEV_POLL_DMA
-+# define CONFIG_CRYPTO_DEV_POLL_DMA
-+#endif
-+
-+/* must match the size of memory block allocated for
-+ * g_dma_block and g_dma_block2 */
-+#define DEU_MAX_PACKET_SIZE (PAGE_SIZE >> 1)
-+
-+struct lq_deu_device {
-+ struct dma_device_info *dma_device;
-+ u8 *dst;
-+ u8 *src;
-+ int len;
-+ int dst_count;
-+ int src_count;
-+ int recv_count;
-+ int packet_size;
-+ int packet_num;
-+ wait_queue_t wait;
-+};
-+
-+extern struct lq_deu_device lq_deu[1];
-+
-+extern int deu_dma_intr_handler(struct dma_device_info *, int);
-+extern u8 *deu_dma_buffer_alloc(int, int *, void **);
-+extern int deu_dma_buffer_free(u8 *, void *);
-+extern void deu_dma_inactivate_poll(struct dma_device_info* dma_dev);
-+extern void deu_dma_activate_poll(struct dma_device_info* dma_dev);
-+extern struct dma_device_info* deu_dma_reserve(struct dma_device_info**
-+ dma_device);
-+extern int deu_dma_release(struct dma_device_info** dma_device);
-+
-+#endif /* IFMIPS_DEU_DMA_H */
---- /dev/null
-+++ b/drivers/crypto/lantiq/md5.c
-@@ -0,0 +1,285 @@
-+/*
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
-+ *
-+ * Copyright (C) 2010 Ralph Hempel <ralph.hempel@lantiq.com>
-+ * Copyright (C) 2009 Mohammad Firdaus
-+ */
-+
-+/**
-+ \defgroup LQ_DEU LQ_DEU_DRIVERS
-+ \ingroup API
-+ \brief Lantiq DEU driver module
-+*/
-+
-+/**
-+ \file md5.c
-+ \ingroup LQ_DEU
-+ \brief MD5 encryption DEU driver file
-+*/
-+
-+/**
-+ \defgroup LQ_MD5_FUNCTIONS LQ_MD5_FUNCTIONS
-+ \ingroup LQ_DEU
-+ \brief Lantiq DEU MD5 functions
-+*/
-+
-+#include <crypto/internal/hash.h>
-+#include <linux/init.h>
-+#include <linux/module.h>
-+#include <linux/string.h>
-+#include <linux/crypto.h>
-+#include <linux/types.h>
-+#include <asm/byteorder.h>
-+#include "deu.h"
-+
-+#define MD5_DIGEST_SIZE 16
-+#define MD5_HMAC_BLOCK_SIZE 64
-+#define MD5_BLOCK_WORDS 16
-+#define MD5_HASH_WORDS 4
-+
-+static spinlock_t cipher_lock;
-+
-+struct md5_ctx {
-+ u32 hash[MD5_HASH_WORDS];
-+ u32 block[MD5_BLOCK_WORDS];
-+ u64 byte_count;
-+};
-+
-+/** \fn static u32 md5_endian_swap(u32 input)
-+ * \ingroup LQ_MD5_FUNCTIONS
-+ * \brief perform dword level endian swap
-+ * \param input value of dword that requires to be swapped
-+*/
-+static u32 md5_endian_swap(u32 input)
-+{
-+ u8 *ptr = (u8 *)&input;
-+
-+ return ((ptr[3] << 24) | (ptr[2] << 16) | (ptr[1] << 8) | ptr[0]);
-+}
-+
-+/** \fn static void md5_transform(u32 *hash, u32 const *in)
-+ * \ingroup LQ_MD5_FUNCTIONS
-+ * \brief main interface to md5 hardware
-+ * \param hash current hash value
-+ * \param in 64-byte block of input
-+*/
-+static void md5_transform(u32 *hash, u32 const *in)
-+{
-+ int i;
-+ volatile struct deu_hash *hashs = (struct deu_hash *) HASH_START;
-+ ulong flag;
-+
-+ CRTCL_SECT_START;
-+
-+ for (i = 0; i < 16; i++) {
-+ hashs->MR = md5_endian_swap(in[i]);
-+ };
-+
-+ /* wait for processing */
-+ while (hashs->ctrl.BSY) {
-+ /* this will not take long */
-+ }
-+
-+ CRTCL_SECT_END;
-+}
-+
-+/** \fn static inline void md5_transform_helper(struct md5_ctx *ctx)
-+ * \ingroup LQ_MD5_FUNCTIONS
-+ * \brief interfacing function for md5_transform()
-+ * \param ctx crypto context
-+*/
-+static inline void md5_transform_helper(struct md5_ctx *ctx)
-+{
-+ /* le32_to_cpu_array(ctx->block, sizeof(ctx->block) / sizeof(u32)); */
-+ md5_transform(ctx->hash, ctx->block);
-+}
-+
-+/** \fn static void md5_init(struct crypto_tfm *tfm)
-+ * \ingroup LQ_MD5_FUNCTIONS
-+ * \brief initialize md5 hardware
-+ * \param tfm linux crypto algo transform
-+*/
-+static int md5_init(struct shash_desc *desc)
-+{
-+ struct md5_ctx *mctx = shash_desc_ctx(desc);
-+ volatile struct deu_hash *hash = (struct deu_hash *) HASH_START;
-+
-+ hash->ctrl.SM = 1;
-+ hash->ctrl.ALGO = 1; /* 1 = md5 0 = sha1 */
-+ hash->ctrl.INIT = 1; /* Initialize the hash operation by writing
-+ a '1' to the INIT bit. */
-+
-+ mctx->byte_count = 0;
-+
-+ return 0;
-+}
-+
-+/** \fn static void md5_update(struct crypto_tfm *tfm, const u8 *data, unsigned int len)
-+ * \ingroup LQ_MD5_FUNCTIONS
-+ * \brief on-the-fly md5 computation
-+ * \param tfm linux crypto algo transform
-+ * \param data input data
-+ * \param len size of input data
-+*/
-+static int md5_update(struct shash_desc *desc, const u8 *data, unsigned int len)
-+{
-+ struct md5_ctx *mctx = shash_desc_ctx(desc);
-+ const u32 avail = sizeof(mctx->block) - (mctx->byte_count & 0x3f);
-+
-+ mctx->byte_count += len;
-+
-+ if (avail > len) {
-+ memcpy((char *)mctx->block + (sizeof(mctx->block) - avail),
-+ data, len);
-+ return 0;
-+ }
-+
-+ memcpy((char *)mctx->block + (sizeof(mctx->block) - avail),
-+ data, avail);
-+
-+ md5_transform_helper(mctx);
-+ data += avail;
-+ len -= avail;
-+
-+ while (len >= sizeof(mctx->block)) {
-+ memcpy(mctx->block, data, sizeof(mctx->block));
-+ md5_transform_helper(mctx);
-+ data += sizeof(mctx->block);
-+ len -= sizeof(mctx->block);
-+ }
-+
-+ memcpy(mctx->block, data, len);
-+
-+ return 0;
-+}
-+
-+/** \fn static void md5_final(struct crypto_tfm *tfm, u8 *out)
-+ * \ingroup LQ_MD5_FUNCTIONS
-+ * \brief compute final md5 value
-+ * \param tfm linux crypto algo transform
-+ * \param out final md5 output value
-+*/
-+static int md5_final(struct shash_desc *desc, u8 *out)
-+{
-+ struct md5_ctx *mctx = shash_desc_ctx(desc);
-+ const unsigned int offset = mctx->byte_count & 0x3f;
-+ char *p = (char *)mctx->block + offset;
-+ int padding = 56 - (offset + 1);
-+ volatile struct deu_hash *hashs = (struct deu_hash *) HASH_START;
-+ unsigned long flag;
-+
-+ *p++ = 0x80;
-+ if (padding < 0) {
-+ memset(p, 0x00, padding + sizeof (u64));
-+ md5_transform_helper(mctx);
-+ p = (char *)mctx->block;
-+ padding = 56;
-+ }
-+
-+ memset(p, 0, padding);
-+ mctx->block[14] = md5_endian_swap(mctx->byte_count << 3);
-+ mctx->block[15] = md5_endian_swap(mctx->byte_count >> 29);
-+
-+#if 0
-+ le32_to_cpu_array(mctx->block, (sizeof(mctx->block) -
-+ sizeof(u64)) / sizeof(u32));
-+#endif
-+
-+ md5_transform(mctx->hash, mctx->block);
-+
-+ CRTCL_SECT_START;
-+
-+ *((u32 *) out + 0) = md5_endian_swap(hashs->D1R);
-+ *((u32 *) out + 1) = md5_endian_swap(hashs->D2R);
-+ *((u32 *) out + 2) = md5_endian_swap(hashs->D3R);
-+ *((u32 *) out + 3) = md5_endian_swap(hashs->D4R);
-+
-+ CRTCL_SECT_END;
-+
-+ /* Wipe context */
-+ memset(mctx, 0, sizeof(*mctx));
-+
-+ return 0;
-+}
-+
-+static int md5_export(struct shash_desc *desc, void *out)
-+{
-+ struct md5_ctx *sctx = shash_desc_ctx(desc);
-+
-+ memcpy(out, sctx, sizeof(*sctx));
-+ return 0;
-+}
-+
-+static int md5_import(struct shash_desc *desc, const void *in)
-+{
-+ struct md5_ctx *sctx = shash_desc_ctx(desc);
-+
-+ memcpy(sctx, in, sizeof(*sctx));
-+ return 0;
-+}
-+
-+/*
-+ * \brief MD5 function mappings
-+*/
-+static struct shash_alg md5_alg = {
-+ .digestsize = MD5_DIGEST_SIZE,
-+ .init = md5_init,
-+ .update = md5_update,
-+ .final = md5_final,
-+ .export = md5_export,
-+ .import = md5_import,
-+ .descsize = sizeof(struct md5_ctx),
-+ .statesize = sizeof(struct md5_ctx),
-+ .base = {
-+ .cra_name = "md5",
-+ .cra_driver_name = "lq_deu-md5",
-+ .cra_flags = CRYPTO_ALG_TYPE_SHASH,
-+ .cra_blocksize = MD5_HMAC_BLOCK_SIZE,
-+ .cra_module = THIS_MODULE,
-+ }
-+};
-+
-+/** \fn int lq_deu_init_md5(void)
-+ * \ingroup LQ_MD5_FUNCTIONS
-+ * \brief initialize md5 driver
-+*/
-+int lq_deu_init_md5(void)
-+{
-+ int ret;
-+
-+ if ((ret = crypto_register_shash(&md5_alg)))
-+ goto md5_err;
-+
-+ CRTCL_SECT_INIT;
-+
-+ printk(KERN_NOTICE "Lantiq DEU MD5 initialized%s.\n",
-+ disable_deudma ? "" : " (DMA)");
-+ return ret;
-+
-+md5_err:
-+ printk(KERN_ERR "Lantiq DEU MD5 initialization failed!\n");
-+ return ret;
-+}
-+
-+/** \fn void lq_deu_fini_md5(void)
-+ * \ingroup LQ_MD5_FUNCTIONS
-+ * \brief unregister md5 driver
-+*/
-+
-+void lq_deu_fini_md5(void)
-+{
-+ crypto_unregister_shash(&md5_alg);
-+}
-+
---- /dev/null
-+++ b/drivers/crypto/lantiq/md5_hmac.c
-@@ -0,0 +1,329 @@
-+/*
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
-+ *
-+ * Copyright (C) 2010 Ralph Hempel <ralph.hempel@lantiq.com>
-+ * Copyright (C) 2009 Mohammad Firdaus
-+ */
-+
-+/**
-+ \defgroup LQ_DEU LQ_DEU_DRIVERS
-+ \ingroup API
-+ \brief Lantiq DEU driver module
-+*/
-+
-+/**
-+ \file md5_hmac.c
-+ \ingroup LQ_DEU
-+ \brief MD5-HMAC encryption DEU driver file
-+*/
-+
-+/**
-+ \defgroup LQ_MD5_HMAC_FUNCTIONS LQ_MD5_HMAC_FUNCTIONS
-+ \ingroup LQ_DEU
-+ \brief Lantiq md5-hmac driver functions
-+*/
-+
-+#include <crypto/internal/hash.h>
-+#include <linux/init.h>
-+#include <linux/module.h>
-+#include <linux/string.h>
-+#include <linux/crypto.h>
-+#include <linux/types.h>
-+#include <asm/byteorder.h>
-+#include "deu.h"
-+
-+#define MD5_DIGEST_SIZE 16
-+#define MD5_HMAC_BLOCK_SIZE 64
-+#define MD5_BLOCK_WORDS 16
-+#define MD5_HASH_WORDS 4
-+#define MD5_HMAC_DBN_TEMP_SIZE 1024 /* size in dword,
-+ needed for dbn workaround */
-+
-+static spinlock_t cipher_lock;
-+
-+struct md5_hmac_ctx {
-+ u32 hash[MD5_HASH_WORDS];
-+ u32 block[MD5_BLOCK_WORDS];
-+ u64 byte_count;
-+ u32 dbn;
-+ u32 temp[MD5_HMAC_DBN_TEMP_SIZE];
-+};
-+
-+/** \fn static u32 md5_endian_swap(u32 input)
-+ * \ingroup LQ_MD5_HMAC_FUNCTIONS
-+ * \brief perform dword level endian swap
-+ * \param input value of dword that requires to be swapped
-+*/
-+static u32 md5_endian_swap(u32 input)
-+{
-+ u8 *ptr = (u8 *)&input;
-+
-+ return ((ptr[3] << 24) | (ptr[2] << 16) | (ptr[1] << 8) | ptr[0]);
-+}
-+
-+/** \fn static void md5_hmac_transform(struct crypto_tfm *tfm, u32 const *in)
-+ * \ingroup LQ_MD5_HMAC_FUNCTIONS
-+ * \brief save input block to context
-+ * \param tfm linux crypto algo transform
-+ * \param in 64-byte block of input
-+*/
-+static void md5_hmac_transform(struct shash_desc *desc, u32 const *in)
-+{
-+ struct md5_hmac_ctx *mctx = shash_desc_ctx(desc);
-+
-+ memcpy(&mctx->temp[mctx->dbn<<4], in, 64); /* dbn workaround */
-+ mctx->dbn += 1;
-+
-+ if ( (mctx->dbn<<4) > MD5_HMAC_DBN_TEMP_SIZE )
-+ {
-+ printk("MD5_HMAC_DBN_TEMP_SIZE exceeded\n");
-+ }
-+}
-+
-+/** \fn int md5_hmac_setkey(struct crypto_tfm *tfm, const u8 *key, unsigned int keylen)
-+ * \ingroup LQ_MD5_HMAC_FUNCTIONS
-+ * \brief sets md5 hmac key
-+ * \param tfm linux crypto algo transform
-+ * \param key input key
-+ * \param keylen key length greater than 64 bytes IS NOT SUPPORTED
-+*/
-+static int md5_hmac_setkey(struct crypto_shash *tfm,
-+ const u8 *key,
-+ unsigned int keylen)
-+{
-+ volatile struct deu_hash *hash = (struct deu_hash *) HASH_START;
-+ int i, j;
-+ u32 *in_key = (u32 *)key;
-+
-+ hash->KIDX = 0x80000000; /* reset all 16 words of the key to '0' */
-+ asm("sync");
-+
-+ j = 0;
-+ for (i = 0; i < keylen; i+=4)
-+ {
-+ hash->KIDX = j;
-+ asm("sync");
-+ hash->KEY = *((u32 *) in_key + j);
-+ j++;
-+ }
-+
-+ return 0;
-+}
-+
-+/** \fn void md5_hmac_init(struct crypto_tfm *tfm)
-+ * \ingroup LQ_MD5_HMAC_FUNCTIONS
-+ * \brief initialize md5 hmac context
-+ * \param tfm linux crypto algo transform
-+*/
-+static int md5_hmac_init(struct shash_desc *desc)
-+{
-+ struct md5_hmac_ctx *mctx = shash_desc_ctx(desc);
-+
-+ memset(mctx, 0, sizeof(struct md5_hmac_ctx));
-+ mctx->dbn = 0; /* dbn workaround */
-+ return 0;
-+}
-+
-+/** \fn void md5_hmac_update(struct crypto_tfm *tfm, const u8 *data, unsigned int len)
-+ * \ingroup LQ_MD5_HMAC_FUNCTIONS
-+ * \brief on-the-fly md5 hmac computation
-+ * \param tfm linux crypto algo transform
-+ * \param data input data
-+ * \param len size of input data
-+*/
-+static int md5_hmac_update(struct shash_desc *desc,
-+ const u8 *data,
-+ unsigned int len)
-+{
-+ struct md5_hmac_ctx *mctx = shash_desc_ctx(desc);
-+ const u32 avail = sizeof(mctx->block) - (mctx->byte_count & 0x3f);
-+
-+ mctx->byte_count += len;
-+
-+ if (avail > len) {
-+ memcpy((char *)mctx->block + (sizeof(mctx->block) - avail),
-+ data, len);
-+ return 0;
-+ }
-+
-+ memcpy((char *)mctx->block + (sizeof(mctx->block) - avail),
-+ data, avail);
-+
-+ md5_hmac_transform(desc, mctx->block);
-+ data += avail;
-+ len -= avail;
-+
-+ while (len >= sizeof(mctx->block)) {
-+ memcpy(mctx->block, data, sizeof(mctx->block));
-+ md5_hmac_transform(desc, mctx->block);
-+ data += sizeof(mctx->block);
-+ len -= sizeof(mctx->block);
-+ }
-+
-+ memcpy(mctx->block, data, len);
-+
-+ return 0;
-+}
-+
-+/** \fn void md5_hmac_final(struct crypto_tfm *tfm, u8 *out)
-+ * \ingroup LQ_MD5_HMAC_FUNCTIONS
-+ * \brief compute final md5 hmac value
-+ * \param tfm linux crypto algo transform
-+ * \param out final md5 hmac output value
-+*/
-+static int md5_hmac_final(struct shash_desc *desc, u8 *out)
-+{
-+ struct md5_hmac_ctx *mctx = shash_desc_ctx(desc);
-+ const unsigned int offset = mctx->byte_count & 0x3f;
-+ char *p = (char *)mctx->block + offset;
-+ int padding = 56 - (offset + 1);
-+ volatile struct deu_hash *hashs = (struct deu_hash *) HASH_START;
-+ u32 flag;
-+ int i = 0;
-+ int dbn;
-+ u32 *in = &mctx->temp[0];
-+
-+ *p++ = 0x80;
-+ if (padding < 0) {
-+ memset(p, 0x00, padding + sizeof (u64));
-+ md5_hmac_transform(desc, mctx->block);
-+ p = (char *)mctx->block;
-+ padding = 56;
-+ }
-+
-+ memset(p, 0, padding);
-+ /* need to add 512 bit of the IPAD operation */
-+ mctx->block[14] = md5_endian_swap((mctx->byte_count + 64) << 3);
-+ mctx->block[15] = 0x00000000;
-+
-+ md5_hmac_transform(desc, mctx->block);
-+
-+ CRTCL_SECT_START;
-+
-+ printk("dbn = %d\n", mctx->dbn);
-+ hashs->DBN = mctx->dbn;
-+
-+ /* khs, go, init, ndc, endi, kyue, hmen, md5 */
-+ *LQ_HASH_CON = 0x0703002D;
-+
-+ /* wait for processing */
-+ while (hashs->ctrl.BSY) {
-+ /* this will not take long */
-+ }
-+
-+ for (dbn = 0; dbn < mctx->dbn; dbn++)
-+ {
-+ for (i = 0; i < 16; i++) {
-+ hashs->MR = in[i];
-+ };
-+
-+ hashs->ctrl.GO = 1;
-+ asm("sync");
-+
-+ /* wait for processing */
-+ while (hashs->ctrl.BSY) {
-+ /* this will not take long */
-+ }
-+
-+ in += 16;
-+ }
-+
-+#if 1
-+ /* wait for digest ready */
-+ while (! hashs->ctrl.DGRY) {
-+ /* this will not take long */
-+ }
-+#endif
-+
-+ *((u32 *) out + 0) = hashs->D1R;
-+ *((u32 *) out + 1) = hashs->D2R;
-+ *((u32 *) out + 2) = hashs->D3R;
-+ *((u32 *) out + 3) = hashs->D4R;
-+ *((u32 *) out + 4) = hashs->D5R;
-+
-+ CRTCL_SECT_END;
-+
-+ return 0;
-+}
-+
-+static int md5_hmac_export(struct shash_desc *desc, void *out)
-+{
-+ struct md5_hmac_ctx *sctx = shash_desc_ctx(desc);
-+
-+ memcpy(out, sctx, sizeof(*sctx));
-+ return 0;
-+}
-+
-+static int md5_hmac_import(struct shash_desc *desc, const void *in)
-+{
-+ struct md5_hmac_ctx *sctx = shash_desc_ctx(desc);
-+
-+ memcpy(sctx, in, sizeof(*sctx));
-+ return 0;
-+}
-+
-+/*
-+ * \brief MD5_HMAC function mappings
-+*/
-+static struct shash_alg md5_hmac_alg = {
-+ .digestsize = MD5_DIGEST_SIZE,
-+ .init = md5_hmac_init,
-+ .update = md5_hmac_update,
-+ .final = md5_hmac_final,
-+ .setkey = md5_hmac_setkey,
-+ .export = md5_hmac_export,
-+ .import = md5_hmac_import,
-+ .descsize = sizeof(struct md5_hmac_ctx),
-+ .statesize = sizeof(struct md5_hmac_ctx),
-+ .base = {
-+ .cra_name = "hmac(md5)",
-+ .cra_driver_name = "lq_deu-md5_hmac",
-+ .cra_flags = CRYPTO_ALG_TYPE_SHASH,
-+ .cra_blocksize = MD5_HMAC_BLOCK_SIZE,
-+ .cra_module = THIS_MODULE,
-+ }
-+};
-+
-+/** \fn int lq_deu_init_md5_hmac(void)
-+ * \ingroup LQ_MD5_HMAC_FUNCTIONS
-+ * \brief initialize md5 hmac driver
-+*/
-+int lq_deu_init_md5_hmac(void)
-+{
-+ int ret;
-+
-+ if ((ret = crypto_register_shash(&md5_hmac_alg)))
-+ goto md5_hmac_err;
-+
-+ CRTCL_SECT_INIT;
-+
-+ printk(KERN_NOTICE "Lantiq DEU MD5_HMAC initialized%s.\n",
-+ disable_deudma ? "" : " (DMA)");
-+ return ret;
-+
-+md5_hmac_err:
-+ printk(KERN_ERR "Lantiq DEU MD5_HMAC initialization failed!\n");
-+ return ret;
-+}
-+
-+/** \fn void lq_deu_fini_md5_hmac(void)
-+ * \ingroup LQ_MD5_HMAC_FUNCTIONS
-+ * \brief unregister md5 hmac driver
-+*/
-+void lq_deu_fini_md5_hmac(void)
-+{
-+ crypto_unregister_shash(&md5_hmac_alg);
-+}
-+
---- /dev/null
-+++ b/drivers/crypto/lantiq/sha1.c
-@@ -0,0 +1,262 @@
-+/*
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
-+ *
-+ * Copyright (C) 2010 Ralph Hempel <ralph.hempel@lantiq.com>
-+ * Copyright (C) 2009 Mohammad Firdaus
-+ */
-+
-+/**
-+ \defgroup LQ_DEU LQ_DEU_DRIVERS
-+ \ingroup API
-+ \brief Lantiq DEU driver module
-+*/
-+
-+/**
-+ \file sha1.c
-+ \ingroup LQ_DEU
-+ \brief SHA1 encryption DEU driver file
-+*/
-+
-+/**
-+ \defgroup LQ_SHA1_FUNCTIONS LQ_SHA1_FUNCTIONS
-+ \ingroup LQ_DEU
-+ \brief Lantiq DEU sha1 functions
-+*/
-+
-+
-+#include <crypto/internal/hash.h>
-+#include <linux/init.h>
-+#include <linux/module.h>
-+#include <linux/mm.h>
-+#include <linux/crypto.h>
-+#include <linux/cryptohash.h>
-+#include <crypto/sha.h>
-+#include <linux/types.h>
-+#include <asm/scatterlist.h>
-+#include <asm/byteorder.h>
-+#include "deu.h"
-+
-+#define SHA1_DIGEST_SIZE 20
-+#define SHA1_HMAC_BLOCK_SIZE 64
-+
-+static spinlock_t cipher_lock;
-+
-+/*
-+ * \brief SHA1 private structure
-+*/
-+struct sha1_ctx {
-+ u64 count;
-+ u32 state[5];
-+ u8 buffer[64];
-+};
-+
-+/** \fn static void sha1_transform(u32 *state, const u32 *in)
-+ * \ingroup LQ_SHA1_FUNCTIONS
-+ * \brief main interface to sha1 hardware
-+ * \param state current state
-+ * \param in 64-byte block of input
-+*/
-+static void sha1_transform(u32 *state, const u32 *in)
-+{
-+ int i = 0;
-+ volatile struct deu_hash *hashs = (struct deu_hash *) HASH_START;
-+ unsigned long flag;
-+
-+ CRTCL_SECT_START;
-+
-+ for (i = 0; i < 16; i++) {
-+ hashs->MR = in[i];
-+ };
-+
-+ /* wait for processing */
-+ while (hashs->ctrl.BSY) {
-+ /* this will not take long */
-+ }
-+
-+ CRTCL_SECT_END;
-+}
-+
-+/** \fn static void sha1_init(struct crypto_tfm *tfm)
-+ * \ingroup LQ_SHA1_FUNCTIONS
-+ * \brief initialize sha1 hardware
-+ * \param tfm linux crypto algo transform
-+*/
-+static int sha1_init(struct shash_desc *desc)
-+{
-+ struct sha1_ctx *sctx = shash_desc_ctx(desc);
-+
-+ SHA_HASH_INIT;
-+
-+ sctx->count = 0;
-+
-+ return 0;
-+}
-+
-+/** \fn static void sha1_update(struct crypto_tfm *tfm, const u8 *data, unsigned int len)
-+ * \ingroup LQ_SHA1_FUNCTIONS
-+ * \brief on-the-fly sha1 computation
-+ * \param tfm linux crypto algo transform
-+ * \param data input data
-+ * \param len size of input data
-+*/
-+static int sha1_update(struct shash_desc *desc, const u8 *data, unsigned int len)
-+{
-+ struct sha1_ctx *sctx = shash_desc_ctx(desc);
-+ unsigned int i, j;
-+
-+ j = (sctx->count >> 3) & 0x3f;
-+ sctx->count += len << 3;
-+
-+ if ((j + len) > 63) {
-+ memcpy(&sctx->buffer[j], data, (i = 64 - j));
-+ sha1_transform(sctx->state, (const u32 *)sctx->buffer);
-+ for (; i + 63 < len; i += 64) {
-+ sha1_transform(sctx->state, (const u32 *)&data[i]);
-+ }
-+
-+ j = 0;
-+ } else {
-+ i = 0;
-+ }
-+
-+ memcpy(&sctx->buffer[j], &data[i], len - i);
-+
-+ return 0;
-+}
-+
-+/** \fn static void sha1_final(struct crypto_tfm *tfm, u8 *out)
-+ * \ingroup LQ_SHA1_FUNCTIONS
-+ * \brief compute final sha1 value
-+ * \param tfm linux crypto algo transform
-+ * \param out final md5 output value
-+*/
-+static int sha1_final(struct shash_desc *desc, u8 *out)
-+{
-+ struct sha1_ctx *sctx = shash_desc_ctx(desc);
-+ u32 index, padlen;
-+ u64 t;
-+ u8 bits[8] = { 0, };
-+ static const u8 padding[64] = { 0x80, };
-+ volatile struct deu_hash *hashs = (struct deu_hash *) HASH_START;
-+ ulong flag;
-+
-+ t = sctx->count;
-+ bits[7] = 0xff & t;
-+ t >>= 8;
-+ bits[6] = 0xff & t;
-+ t >>= 8;
-+ bits[5] = 0xff & t;
-+ t >>= 8;
-+ bits[4] = 0xff & t;
-+ t >>= 8;
-+ bits[3] = 0xff & t;
-+ t >>= 8;
-+ bits[2] = 0xff & t;
-+ t >>= 8;
-+ bits[1] = 0xff & t;
-+ t >>= 8;
-+ bits[0] = 0xff & t;
-+
-+ /* Pad out to 56 mod 64 */
-+ index = (sctx->count >> 3) & 0x3f;
-+ padlen = (index < 56) ? (56 - index) : ((64 + 56) - index);
-+ sha1_update(desc, padding, padlen);
-+
-+ /* Append length */
-+ sha1_update(desc, bits, sizeof bits);
-+
-+ CRTCL_SECT_START;
-+
-+ *((u32 *) out + 0) = hashs->D1R;
-+ *((u32 *) out + 1) = hashs->D2R;
-+ *((u32 *) out + 2) = hashs->D3R;
-+ *((u32 *) out + 3) = hashs->D4R;
-+ *((u32 *) out + 4) = hashs->D5R;
-+
-+ CRTCL_SECT_END;
-+
-+ /* Wipe context*/
-+ memset(sctx, 0, sizeof *sctx);
-+
-+ return 0;
-+}
-+
-+static int sha1_export(struct shash_desc *desc, void *out)
-+{
-+ struct sha1_ctx *sctx = shash_desc_ctx(desc);
-+
-+ memcpy(out, sctx, sizeof(*sctx));
-+ return 0;
-+}
-+
-+static int sha1_import(struct shash_desc *desc, const void *in)
-+{
-+ struct sha1_ctx *sctx = shash_desc_ctx(desc);
-+
-+ memcpy(sctx, in, sizeof(*sctx));
-+ return 0;
-+}
-+
-+/*
-+ * \brief SHA1 function mappings
-+*/
-+static struct shash_alg deu_sha1_alg = {
-+ .digestsize = SHA1_DIGEST_SIZE,
-+ .init = sha1_init,
-+ .update = sha1_update,
-+ .final = sha1_final,
-+ .export = sha1_export,
-+ .import = sha1_import,
-+ .descsize = sizeof(struct sha1_ctx),
-+ .statesize = sizeof(struct sha1_ctx),
-+ .base = {
-+ .cra_name = "sha1",
-+ .cra_driver_name = "lq_deu-sha1",
-+ .cra_flags = CRYPTO_ALG_TYPE_SHASH,
-+ .cra_blocksize = SHA1_HMAC_BLOCK_SIZE,
-+ .cra_module = THIS_MODULE,
-+ }
-+};
-+
-+/** \fn int lq_deu_init_sha1(void)
-+ * \ingroup LQ_SHA1_FUNCTIONS
-+ * \brief initialize sha1 driver
-+*/
-+int lq_deu_init_sha1(void)
-+{
-+ int ret;
-+
-+ if ((ret = crypto_register_shash(&deu_sha1_alg)))
-+ goto sha1_err;
-+
-+ CRTCL_SECT_INIT;
-+
-+ printk(KERN_NOTICE "Lantiq DEU SHA1 initialized%s.\n",
-+ disable_deudma ? "" : " (DMA)");
-+ return ret;
-+
-+sha1_err:
-+ printk(KERN_ERR "Lantiq DEU SHA1 initialization failed!\n");
-+ return ret;
-+}
-+
-+/** \fn void lq_deu_fini_sha1(void)
-+ * \ingroup LQ_SHA1_FUNCTIONS
-+ * \brief unregister sha1 driver
-+*/
-+void lq_deu_fini_sha1(void)
-+{
-+ crypto_unregister_shash(&deu_sha1_alg);
-+}
---- /dev/null
-+++ b/drivers/crypto/lantiq/sha1_hmac.c
-@@ -0,0 +1,325 @@
-+/*
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
-+ *
-+ * Copyright (C) 2010 Ralph Hempel <ralph.hempel@lantiq.com>
-+ * Copyright (C) 2009 Mohammad Firdaus
-+ */
-+
-+/**
-+ \defgroup LQ_DEU LQ_DEU_DRIVERS
-+ \ingroup API
-+ \brief Lantiq DEU driver module
-+*/
-+
-+/**
-+ \file sha1_hmac.c
-+ \ingroup LQ_DEU
-+ \brief SHA1-HMAC DEU driver file
-+*/
-+
-+/**
-+ \defgroup LQ_SHA1_HMAC_FUNCTIONS LQ_SHA1_HMAC_FUNCTIONS
-+ \ingroup LQ_DEU
-+ \brief Lantiq sha1 hmac functions
-+*/
-+
-+
-+#include <crypto/internal/hash.h>
-+#include <linux/init.h>
-+#include <linux/module.h>
-+#include <linux/mm.h>
-+#include <linux/crypto.h>
-+#include <linux/cryptohash.h>
-+#include <linux/types.h>
-+#include <asm/scatterlist.h>
-+#include <asm/byteorder.h>
-+#include <linux/delay.h>
-+#include "deu.h"
-+
-+#ifdef CONFIG_CRYPTO_DEV_LANTIQ_SHA1_HMAC
-+
-+#define SHA1_DIGEST_SIZE 20
-+#define SHA1_HMAC_BLOCK_SIZE 64
-+/* size in dword, needed for dbn workaround */
-+#define SHA1_HMAC_DBN_TEMP_SIZE 1024
-+
-+static spinlock_t cipher_lock;
-+
-+struct sha1_hmac_ctx {
-+ u64 count;
-+ u32 state[5];
-+ u8 buffer[64];
-+ u32 dbn;
-+ u32 temp[SHA1_HMAC_DBN_TEMP_SIZE];
-+};
-+
-+/** \fn static void sha1_hmac_transform(struct crypto_tfm *tfm, u32 const *in)
-+ * \ingroup LQ_SHA1_HMAC_FUNCTIONS
-+ * \brief save input block to context
-+ * \param tfm linux crypto algo transform
-+ * \param in 64-byte block of input
-+*/
-+static void sha1_hmac_transform(struct shash_desc *desc, u32 const *in)
-+{
-+ struct sha1_hmac_ctx *sctx = shash_desc_ctx(desc);
-+
-+ memcpy(&sctx->temp[sctx->dbn<<4], in, 64); /* dbn workaround */
-+ sctx->dbn += 1;
-+
-+ if ((sctx->dbn<<4) > SHA1_HMAC_DBN_TEMP_SIZE) {
-+ printk("SHA1_HMAC_DBN_TEMP_SIZE exceeded\n");
-+ }
-+}
-+
-+/** \fn int sha1_hmac_setkey(struct crypto_tfm *tfm, const u8 *key, unsigned int keylen)
-+ * \ingroup LQ_SHA1_HMAC_FUNCTIONS
-+ * \brief sets sha1 hmac key
-+ * \param tfm linux crypto algo transform
-+ * \param key input key
-+ * \param keylen key length greater than 64 bytes IS NOT SUPPORTED
-+*/
-+static int sha1_hmac_setkey(struct crypto_shash *tfm,
-+ const u8 *key,
-+ unsigned int keylen)
-+{
-+ volatile struct deu_hash *hash = (struct deu_hash *) HASH_START;
-+ int i, j;
-+ u32 *in_key = (u32 *)key;
-+
-+ hash->KIDX = 0x80000000; /* reset all 16 words of the key to '0' */
-+ asm("sync");
-+
-+ j = 0;
-+ for (i = 0; i < keylen; i+=4)
-+ {
-+ hash->KIDX = j;
-+ asm("sync");
-+ hash->KEY = *((u32 *) in_key + j);
-+ j++;
-+ }
-+
-+ return 0;
-+}
-+
-+static int sha1_hmac_export(struct shash_desc *desc, void *out)
-+{
-+ struct sha1_hmac_ctx *sctx = shash_desc_ctx(desc);
-+
-+ memcpy(out, sctx, sizeof(*sctx));
-+ return 0;
-+}
-+
-+static int sha1_hmac_import(struct shash_desc *desc, const void *in)
-+{
-+ struct sha1_hmac_ctx *sctx = shash_desc_ctx(desc);
-+
-+ memcpy(sctx, in, sizeof(*sctx));
-+ return 0;
-+}
-+
-+/** \fn void sha1_hmac_init(struct crypto_tfm *tfm)
-+ * \ingroup LQ_SHA1_HMAC_FUNCTIONS
-+ * \brief initialize sha1 hmac context
-+ * \param tfm linux crypto algo transform
-+*/
-+static int sha1_hmac_init(struct shash_desc *desc)
-+{
-+ struct sha1_hmac_ctx *sctx = shash_desc_ctx(desc);
-+
-+ memset(sctx, 0, sizeof(struct sha1_hmac_ctx));
-+ sctx->dbn = 0; /* dbn workaround */
-+
-+ return 0;
-+}
-+
-+/** \fn static void sha1_hmac_update(struct crypto_tfm *tfm, const u8 *data, unsigned int len)
-+ * \ingroup LQ_SHA1_HMAC_FUNCTIONS
-+ * \brief on-the-fly sha1 hmac computation
-+ * \param tfm linux crypto algo transform
-+ * \param data input data
-+ * \param len size of input data
-+*/
-+static int sha1_hmac_update(struct shash_desc *desc, const u8 *data,
-+ unsigned int len)
-+{
-+ struct sha1_hmac_ctx *sctx = shash_desc_ctx(desc);
-+ unsigned int i, j;
-+
-+ j = (sctx->count >> 3) & 0x3f;
-+ sctx->count += len << 3;
-+ /* printk("sctx->count = %d\n", (sctx->count >> 3)); */
-+
-+ if ((j + len) > 63) {
-+ memcpy(&sctx->buffer[j], data, (i = 64 - j));
-+ sha1_hmac_transform(desc, (const u32 *)sctx->buffer);
-+ for (; i + 63 < len; i += 64) {
-+ sha1_hmac_transform(desc, (const u32 *)&data[i]);
-+ }
-+
-+ j = 0;
-+ } else {
-+ i = 0;
-+ }
-+
-+ memcpy(&sctx->buffer[j], &data[i], len - i);
-+
-+ return 0;
-+}
-+
-+/** \fn static void sha1_hmac_final(struct crypto_tfm *tfm, u8 *out)
-+ * \ingroup LQ_SHA1_HMAC_FUNCTIONS
-+ * \brief ompute final sha1 hmac value
-+ * \param tfm linux crypto algo transform
-+ * \param out final sha1 hmac output value
-+*/
-+static int sha1_hmac_final(struct shash_desc *desc, u8 *out)
-+{
-+ struct sha1_hmac_ctx *sctx = shash_desc_ctx(desc);
-+ u32 index, padlen;
-+ u64 t;
-+ u8 bits[8] = { 0, };
-+ static const u8 padding[64] = { 0x80, };
-+ volatile struct deu_hash *hashs = (struct deu_hash *) HASH_START;
-+ ulong flag;
-+ int i = 0;
-+ int dbn;
-+ u32 *in = &sctx->temp[0];
-+
-+ t = sctx->count + 512; /* need to add 512 bit of the IPAD operation */
-+ bits[7] = 0xff & t;
-+ t >>= 8;
-+ bits[6] = 0xff & t;
-+ t >>= 8;
-+ bits[5] = 0xff & t;
-+ t >>= 8;
-+ bits[4] = 0xff & t;
-+ t >>= 8;
-+ bits[3] = 0xff & t;
-+ t >>= 8;
-+ bits[2] = 0xff & t;
-+ t >>= 8;
-+ bits[1] = 0xff & t;
-+ t >>= 8;
-+ bits[0] = 0xff & t;
-+
-+ /* Pad out to 56 mod 64 */
-+ index = (sctx->count >> 3) & 0x3f;
-+ padlen = (index < 56) ? (56 - index) : ((64 + 56) - index);
-+ sha1_hmac_update(desc, padding, padlen);
-+
-+ /* Append length */
-+ sha1_hmac_update(desc, bits, sizeof bits);
-+
-+ CRTCL_SECT_START;
-+
-+ hashs->DBN = sctx->dbn;
-+
-+ /* for vr9 change, ENDI = 1 */
-+ *LQ_HASH_CON = HASH_CON_VALUE;
-+
-+ /* wait for processing */
-+ while (hashs->ctrl.BSY) {
-+ /* this will not take long */
-+ }
-+
-+ for (dbn = 0; dbn < sctx->dbn; dbn++)
-+ {
-+ for (i = 0; i < 16; i++) {
-+ hashs->MR = in[i];
-+ };
-+
-+ hashs->ctrl.GO = 1;
-+ asm("sync");
-+
-+ /* wait for processing */
-+ while (hashs->ctrl.BSY) {
-+ /* this will not take long */
-+ }
-+
-+ in += 16;
-+
-+ return 0;
-+ }
-+
-+#if 1
-+ /* wait for digest ready */
-+ while (! hashs->ctrl.DGRY) {
-+ /* this will not take long */
-+ }
-+#endif
-+
-+ *((u32 *) out + 0) = hashs->D1R;
-+ *((u32 *) out + 1) = hashs->D2R;
-+ *((u32 *) out + 2) = hashs->D3R;
-+ *((u32 *) out + 3) = hashs->D4R;
-+ *((u32 *) out + 4) = hashs->D5R;
-+
-+ CRTCL_SECT_END;
-+}
-+
-+/*
-+ * \brief SHA1-HMAC function mappings
-+*/
-+static struct shash_alg sha1_hmac_alg = {
-+ .digestsize = SHA1_DIGEST_SIZE,
-+ .init = sha1_hmac_init,
-+ .update = sha1_hmac_update,
-+ .final = sha1_hmac_final,
-+ .export = sha1_hmac_export,
-+ .import = sha1_hmac_import,
-+ .setkey = sha1_hmac_setkey,
-+ .descsize = sizeof(struct sha1_hmac_ctx),
-+ .statesize = sizeof(struct sha1_hmac_ctx),
-+ .base = {
-+ .cra_name = "hmac(sha1)",
-+ .cra_driver_name = "lq_deu-sha1_hmac",
-+ .cra_flags = CRYPTO_ALG_TYPE_SHASH,
-+ .cra_blocksize = SHA1_HMAC_BLOCK_SIZE,
-+ .cra_module = THIS_MODULE,
-+ }
-+};
-+
-+/** \fn int lq_deu_init_sha1_hmac(void)
-+ * \ingroup LQ_SHA1_HMAC_FUNCTIONS
-+ * \brief initialize sha1 hmac driver
-+*/
-+int lq_deu_init_sha1_hmac(void)
-+{
-+ int ret;
-+
-+ if ((ret = crypto_register_shash(&sha1_hmac_alg)))
-+ goto sha1_err;
-+
-+ CRTCL_SECT_INIT;
-+
-+ printk(KERN_NOTICE "Lantiq DEU SHA1_HMAC initialized%s.\n",
-+ disable_deudma ? "" : " (DMA)");
-+ return ret;
-+
-+sha1_err:
-+ printk(KERN_ERR "Lantiq DEU SHA1_HMAC initialization failed!\n");
-+ return ret;
-+}
-+
-+/** \fn void lq_deu_fini_sha1_hmac(void)
-+ * \ingroup LQ_SHA1_HMAC_FUNCTIONS
-+ * \brief unregister sha1 hmac driver
-+*/
-+void lq_deu_fini_sha1_hmac(void)
-+{
-+ crypto_unregister_shash(&sha1_hmac_alg);
-+}
-+
-+#endif
---- /dev/null
-+++ b/drivers/crypto/lantiq/deu_falcon.c
-@@ -0,0 +1,163 @@
-+/*
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
-+ *
-+ * Copyright (C) 2010 Ralph Hempel <ralph.hempel@lantiq.com>
-+ * Copyright (C) 2009 Mohammad Firdaus
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/init.h>
-+#include <linux/types.h>
-+#include <linux/errno.h>
-+#include <asm/io.h> /* dma_cache_inv */
-+#include <linux/platform_device.h>
-+
-+#ifdef CONFIG_SOC_LANTIQ_FALCON
-+
-+#include "deu.h"
-+
-+/**
-+ \defgroup LQ_DEU LQ_DEU_DRIVERS
-+ \ingroup API
-+ \brief Lantiq DEU driver module
-+*/
-+
-+/**
-+ \file deu_falcon.c
-+ \brief Lantiq DEU board specific driver file for ar9
-+*/
-+
-+/**
-+ \defgroup BOARD_SPECIFIC_FUNCTIONS LQ_BOARD_SPECIFIC_FUNCTIONS
-+ \ingroup LQ_DEU
-+ \brief board specific functions
-+*/
-+
-+#include <falcon/gpon_reg_base.h>
-+#include <falcon/sys1_reg.h>
-+#include <falcon/status_reg.h>
-+#include <falcon/sysctrl.h>
-+
-+#define reg_r32(reg) __raw_readl(reg)
-+#define reg_w32(val, reg) __raw_writel(val, reg)
-+#define reg_w32_mask(clear, set, reg) reg_w32((reg_r32(reg) & ~(clear)) | (set), reg)
-+
-+static gpon_sys1_t * const sys1 = (gpon_sys1_t *)GPON_SYS1_BASE;
-+static gpon_status_t * const status = (gpon_status_t *)GPON_STATUS_BASE;
-+
-+/** \fn u32 endian_swap(u32 input)
-+ * \ingroup BOARD_SPECIFIC_FUNCTIONS
-+ * \brief Swap data given to the function
-+ * \param input Data input to be swapped
-+ * \return either the swapped data or the input data depending on whether it is in DMA mode or FPI mode
-+*/
-+static u32 endian_swap(u32 input)
-+{
-+ return input;
-+}
-+
-+/** \fn u32 input_swap(u32 input)
-+ * \ingroup BOARD_SPECIFIC_FUNCTIONS
-+ * \brief Not used
-+ * \return input
-+*/
-+static u32 input_swap(u32 input)
-+{
-+ return input;
-+}
-+
-+/** \fn void aes_chip_init(void)
-+ * \ingroup BOARD_SPECIFIC_FUNCTIONS
-+ * \brief initialize AES hardware
-+*/
-+static void aes_chip_init(void)
-+{
-+ volatile struct deu_aes *aes = (struct deu_aes *) AES_START;
-+
-+ aes->ctrl.SM = 1;
-+ aes->ctrl.ARS = 1;
-+}
-+
-+/** \fn void des_chip_init(void)
-+ * \ingroup BOARD_SPECIFIC_FUNCTIONS
-+ * \brief initialize DES hardware
-+*/
-+static void des_chip_init(void)
-+{
-+}
-+
-+static u32 chip_init(void)
-+{
-+ sys1_hw_clk_enable(CLKEN_SHA1_SET | CLKEN_AES_SET);
-+ sys1_hw_activate(ACT_SHA1_SET | ACT_AES_SET);
-+
-+ return LQ_DEU_ID_AES | LQ_DEU_ID_HASH;
-+}
-+
-+static int lq_crypto_probe(struct platform_device *pdev)
-+{
-+#ifdef CONFIG_CRYPTO_DEV_LANTIQ_DMA
-+ lq_crypto_ops.dma_init = NULL;
-+ lq_crypto_ops.dma_exit = NULL;
-+ lq_crypto_ops.aes_dma_memcpy = NULL;
-+ lq_crypto_ops.des_dma_memcpy = NULL;
-+ lq_crypto_ops.aes_dma_malloc = NULL;
-+ lq_crypto_ops.des_dma_malloc = NULL;
-+ lq_crypto_ops.dma_align = NULL;
-+ lq_crypto_ops.dma_free = NULL;
-+#endif
-+
-+ lq_crypto_ops.endian_swap = endian_swap;
-+ lq_crypto_ops.input_swap = input_swap;
-+ lq_crypto_ops.aes_chip_init = aes_chip_init;
-+ lq_crypto_ops.des_chip_init = des_chip_init;
-+ lq_crypto_ops.chip_init = chip_init;
-+
-+ printk("lq_falcon_deu: driver loaded!\n");
-+
-+ lq_deu_init();
-+
-+ return 0;
-+}
-+
-+static int lq_crypto_remove(struct platform_device *pdev)
-+{
-+ lq_deu_exit();
-+
-+ return 0;
-+}
-+
-+static struct platform_driver lq_crypto = {
-+ .probe = lq_crypto_probe,
-+ .remove = lq_crypto_remove,
-+ .driver = {
-+ .owner = THIS_MODULE,
-+ .name = "lq_falcon_deu"
-+ }
-+};
-+
-+static int __init lq_crypto_init(void)
-+{
-+ return platform_driver_register(&lq_crypto);
-+}
-+module_init(lq_crypto_init);
-+
-+static void __exit lq_crypto_exit(void)
-+{
-+ platform_driver_unregister(&lq_crypto);
-+}
-+module_exit(lq_crypto_exit);
-+
-+#endif
---- /dev/null
-+++ b/drivers/crypto/lantiq/deu_falcon.h
-@@ -0,0 +1,281 @@
-+/*
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
-+ *
-+ * Copyright (C) 2010 Ralph Hempel <ralph.hempel@lantiq.com>
-+ * Copyright (C) 2009 Mohammad Firdaus / Infineon Technologies
-+ */
-+
-+/**
-+ \defgroup LQ_DEU LQ_DEU_DRIVERS
-+ \ingroup API
-+ \brief DEU driver module
-+*/
-+
-+/**
-+ \defgroup LQ_DEU_DEFINITIONS LQ_DEU_DEFINITIONS
-+ \ingroup LQ_DEU
-+ \brief Lantiq DEU definitions
-+*/
-+
-+/**
-+ \file deu_falcon.h
-+ \brief DEU driver header file
-+*/
-+
-+
-+#ifndef DEU_FALCON_H
-+#define DEU_FALCON_H
-+
-+#define HASH_START 0xbd008100
-+#define AES_START 0xbd008000
-+
-+#ifdef CONFIG_CRYPTO_DEV_DMA
-+# include "deu_dma.h"
-+# define DEU_DWORD_REORDERING(ptr, buffer, in_out, bytes) \
-+ deu_dma_align(ptr, buffer, in_out, bytes)
-+# define AES_MEMORY_COPY(outcopy, out_dma, out_arg, nbytes) \
-+ deu_aes_dma_memcpy(outcopy, out_dma, out_arg, nbytes)
-+# define DES_MEMORY_COPY(outcopy, out_dma, out_arg, nbytes) \
-+ deu_des_dma_memcpy(outcopy, out_dma, out_arg, nbytes)
-+# define BUFFER_IN 1
-+# define BUFFER_OUT 0
-+# define AES_ALGO 1
-+# define DES_ALGO 0
-+# define ALLOCATE_MEMORY(val, type) 1
-+# define FREE_MEMORY(buff)
-+extern struct lq_deu_device lq_deu[1];
-+#endif /* CONFIG_CRYPTO_DEV_DMA */
-+
-+/* SHA CONSTANTS */
-+#define HASH_CON_VALUE 0x0700002C
-+
-+#define INPUT_ENDIAN_SWAP(input) deu_input_swap(input)
-+#define DEU_ENDIAN_SWAP(input) deu_endian_swap(input)
-+#define DELAY_PERIOD 10
-+#define FIND_DEU_CHIP_VERSION chip_version()
-+
-+#define WAIT_AES_DMA_READY() \
-+ do { \
-+ int i; \
-+ volatile struct deu_dma *dma = \
-+ (struct deu_dma *) LQ_DEU_DMA_CON; \
-+ volatile struct deu_aes *aes = \
-+ (volatile struct deu_aes *) AES_START; \
-+ for (i = 0; i < 10; i++) \
-+ udelay(DELAY_PERIOD); \
-+ while (dma->ctrl.BSY) {}; \
-+ while (aes->ctrl.BUS) {}; \
-+ } while (0)
-+
-+#define WAIT_DES_DMA_READY() \
-+ do { \
-+ int i; \
-+ volatile struct deu_dma *dma = \
-+ (struct deu_dma *) LQ_DEU_DMA_CON; \
-+ volatile struct deu_des *des = \
-+ (struct deu_des *) DES_3DES_START; \
-+ for (i = 0; i < 10; i++) \
-+ udelay(DELAY_PERIOD); \
-+ while (dma->ctrl.BSY) {}; \
-+ while (des->ctrl.BUS) {}; \
-+ } while (0)
-+
-+#define AES_DMA_MISC_CONFIG() \
-+ do { \
-+ volatile struct deu_aes *aes = \
-+ (volatile struct deu_aes *) AES_START; \
-+ aes->ctrl.KRE = 1; \
-+ aes->ctrl.GO = 1; \
-+ } while(0)
-+
-+#define SHA_HASH_INIT \
-+ do { \
-+ volatile struct deu_hash *hash = \
-+ (struct deu_hash *) HASH_START; \
-+ hash->ctrl.SM = 1; \
-+ hash->ctrl.ALGO = 0; \
-+ hash->ctrl.INIT = 1; \
-+ } while(0)
-+
-+/* DEU Common Structures for Falcon*/
-+
-+struct deu_clk_ctrl {
-+ u32 Res:26;
-+ u32 FSOE:1;
-+ u32 SBWE:1;
-+ u32 EDIS:1;
-+ u32 SPEN:1;
-+ u32 DISS:1;
-+ u32 DISR:1;
-+};
-+
-+struct deu_des {
-+ struct deu_des_ctrl { /* 10h */
-+ u32 KRE:1;
-+ u32 reserved1:5;
-+ u32 GO:1;
-+ u32 STP:1;
-+ u32 Res2:6;
-+ u32 NDC:1;
-+ u32 ENDI:1;
-+ u32 Res3:2;
-+ u32 F:3;
-+ u32 O:3;
-+ u32 BUS:1;
-+ u32 DAU:1;
-+ u32 ARS:1;
-+ u32 SM:1;
-+ u32 E_D:1;
-+ u32 M:3;
-+ } ctrl;
-+
-+ u32 IHR; /* 14h */
-+ u32 ILR; /* 18h */
-+ u32 K1HR; /* 1c */
-+ u32 K1LR;
-+ u32 K2HR;
-+ u32 K2LR;
-+ u32 K3HR;
-+ u32 K3LR; /* 30h */
-+ u32 IVHR; /* 34h */
-+ u32 IVLR; /* 38 */
-+ u32 OHR; /* 3c */
-+ u32 OLR; /* 40 */
-+};
-+
-+struct deu_aes {
-+ struct deu_aes_ctrl {
-+ u32 KRE:1;
-+ u32 reserved1:4;
-+ u32 PNK:1;
-+ u32 GO:1;
-+ u32 STP:1;
-+ u32 reserved2:6;
-+ u32 NDC:1;
-+ u32 ENDI:1;
-+ u32 reserved3:2;
-+ u32 F:3; /* fbs */
-+ u32 O:3; /* om */
-+ u32 BUS:1; /* bsy */
-+ u32 DAU:1;
-+ u32 ARS:1;
-+ u32 SM:1;
-+ u32 E_D:1;
-+ u32 KV:1;
-+ u32 K:2; /* KL */
-+ } ctrl;
-+
-+ u32 ID3R; /* 80h */
-+ u32 ID2R; /* 84h */
-+ u32 ID1R; /* 88h */
-+ u32 ID0R; /* 8Ch */
-+ u32 K7R; /* 90h */
-+ u32 K6R; /* 94h */
-+ u32 K5R; /* 98h */
-+ u32 K4R; /* 9Ch */
-+ u32 K3R; /* A0h */
-+ u32 K2R; /* A4h */
-+ u32 K1R; /* A8h */
-+ u32 K0R; /* ACh */
-+ u32 IV3R; /* B0h */
-+ u32 IV2R; /* B4h */
-+ u32 IV1R; /* B8h */
-+ u32 IV0R; /* BCh */
-+ u32 OD3R; /* D4h */
-+ u32 OD2R; /* D8h */
-+ u32 OD1R; /* DCh */
-+ u32 OD0R; /* E0h */
-+};
-+
-+struct deu_arc4 {
-+ struct arc4_controlr {
-+ u32 KRE:1;
-+ u32 KLEN:4;
-+ u32 KSAE:1;
-+ u32 GO:1;
-+ u32 STP:1;
-+ u32 reserved1:6;
-+ u32 NDC:1;
-+ u32 ENDI:1;
-+ u32 reserved2:8;
-+ u32 BUS:1; /* bsy */
-+ u32 reserved3:1;
-+ u32 ARS:1;
-+ u32 SM:1;
-+ u32 reserved4:4;
-+ } ctrl;
-+
-+ u32 K3R; /* 104h */
-+ u32 K2R; /* 108h */
-+ u32 K1R; /* 10Ch */
-+ u32 K0R; /* 110h */
-+ u32 IDLEN; /* 114h */
-+ u32 ID3R; /* 118h */
-+ u32 ID2R; /* 11Ch */
-+ u32 ID1R; /* 120h */
-+ u32 ID0R; /* 124h */
-+ u32 OD3R; /* 128h */
-+ u32 OD2R; /* 12Ch */
-+ u32 OD1R; /* 130h */
-+ u32 OD0R; /* 134h */
-+};
-+
-+struct deu_hash {
-+ struct deu_hash_ctrl {
-+ u32 reserved1:5;
-+ u32 KHS:1;
-+ u32 GO:1;
-+ u32 INIT:1;
-+ u32 reserved2:6;
-+ u32 NDC:1;
-+ u32 ENDI:1;
-+ u32 reserved3:7;
-+ u32 DGRY:1;
-+ u32 BSY:1;
-+ u32 reserved4:1;
-+ u32 IRCL:1;
-+ u32 SM:1;
-+ u32 KYUE:1;
-+ u32 HMEN:1;
-+ u32 SSEN:1;
-+ u32 ALGO:1;
-+ } ctrl;
-+
-+ u32 MR; /* B4h */
-+ u32 D1R; /* B8h */
-+ u32 D2R; /* BCh */
-+ u32 D3R; /* C0h */
-+ u32 D4R; /* C4h */
-+ u32 D5R; /* C8h */
-+ u32 dummy; /* CCh */
-+ u32 KIDX; /* D0h */
-+ u32 KEY; /* D4h */
-+ u32 DBN; /* D8h */
-+};
-+
-+struct deu_dma {
-+ struct deu_dma_ctrl {
-+ u32 reserved1:22;
-+ u32 BS:2;
-+ u32 BSY:1;
-+ u32 reserved2:1;
-+ u32 ALGO:2;
-+ u32 RXCLS:2;
-+ u32 reserved3:1;
-+ u32 EN:1;
-+ } ctrl;
-+};
-+
-+#endif /* DEU_FALCON_H */
---- a/arch/mips/lantiq/xway/devices.h
-+++ b/arch/mips/lantiq/xway/devices.h
-@@ -24,5 +24,6 @@
- extern void __init lq_register_ethernet(struct lq_eth_data *eth);
- extern void __init lq_register_asc(int port);
- extern void __init lq_register_gpio_buttons(struct gpio_button *buttons, int cnt);
-+extern void __init lq_register_crypto(const char *name);
-
- #endif
---- a/arch/mips/lantiq/xway/mach-easy50712.c
-+++ b/arch/mips/lantiq/xway/mach-easy50712.c
-@@ -74,6 +74,7 @@
- lq_register_wdt();
- lq_register_pci(&lq_pci_data);
- lq_register_ethernet(&lq_eth_data);
-+ lq_register_crypto("lq_danube_deu");
- }
-
- MIPS_MACHINE(LANTIQ_MACH_EASY50712,
---- a/arch/mips/lantiq/xway/mach-easy50812.c
-+++ b/arch/mips/lantiq/xway/mach-easy50812.c
-@@ -73,6 +73,7 @@
- lq_register_wdt();
- lq_register_pci(&lq_pci_data);
- lq_register_ethernet(&lq_eth_data);
-+ lq_register_crypto("lq_ar9_deu");
- }
-
- MIPS_MACHINE(LANTIQ_MACH_EASY50812,