/* * Cryptographic API. * * Support for Infineon DEU hardware crypto engine. * * Copyright (c) 2005 Johannes Doering , INFINEON * * 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. * --------------------------------------------------------------------------- * Copyright (c) 2002, Dr Brian Gladman , Worcester, UK. * All rights reserved. * * LICENSE TERMS * * The free distribution and use of this software in both source and binary * form is allowed (with or without changes) provided that: * * 1. distributions of this source code include the above copyright * notice, this list of conditions and the following disclaimer; * * 2. distributions in binary form include the above copyright * notice, this list of conditions and the following disclaimer * in the documentation and/or other associated materials; * * 3. the copyright holder's name is not used to endorse products * built using this software without specific written permission. * * ALTERNATIVELY, provided that this notice is retained in full, this product * may be distributed under the terms of the GNU General Public License (GPL), * in which case the provisions of the GPL apply INSTEAD OF those given above. * * DISCLAIMER * * This software is provided 'as is' with no explicit or implied warranties * in respect of its properties, including, but not limited to, correctness * and/or fitness for purpose. * --------------------------------------------------------------------------- ** HISTORY ** $Date $Author $Comment * 9th Nov 2007 Teh Kok How Bug fixes * --------------------------------------------------------------------------- */ /** \addtogroup AMAZON_S_DEU \ingroup AMAZON_S_BSP \brief amazon_s deu driver module */ /*! \file amazon_s_deu_dma.c \ingroup AMAZON_S_DEU \brief deu dma driver file */ /*! \addtogroup AMAZON_S_DEU_FUNCTIONS \ingroup AMAZON_S_DEU \brief amazon_s deu driver functions */ #include #include #include #include #include //dma_cache_inv #include #include #include #include #include _ifx_deu_device ifx_deu[1]; static int deu_dma_device_reserved; /*! \fn int deu_dma_intr_handler (struct dma_device_info *dma_dev, int status) \ingroup AMAZON_S_DEU_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) { volatile struct deu_dma_t *dma = (struct deu_dma_t *) DMA_CON; while (dma->controlr.BSY) { // this will not take long } return 0; } u8 *g_dma_page_ptr = NULL; u8 *g_dma_block = NULL; u8 *g_dma_block2 = NULL; /*! \fn u8 *deu_dma_buffer_alloc (int len, int *byte_offset, void **opt) \ingroup AMAZON_S_DEU_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; *byte_offset = 0; return g_dma_block; } /*! \fn int deu_dma_buffer_free (u8 * dataptr, void *opt) \ingroup AMAZON_S_DEU_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) { return 0; } /*! \fn int deu_dma_reserve (void) \ingroup AMAZON_S_DEU_FUNCTIONS \brief reserve deu dma device */ int deu_dma_reserve (void) { if (deu_dma_device_reserved) return -EBUSY; deu_dma_device_reserved = 1; return 0; } /*! \fn int deu_dma_release (void) \ingroup AMAZON_S_DEU_FUNCTIONS \brief release deu dma device */ int deu_dma_release (void) { if (!deu_dma_device_reserved) return -1; deu_dma_device_reserved = 0; return 0; } /*! \fn int deu_dma_init (void) \ingroup AMAZON_S_DEU_FUNCTIONS \brief initialize DEU DMA mode */ int deu_dma_init (void) { struct dma_device_info *dma_device = NULL; int i = 0; volatile struct deu_dma_t *dma = (struct deu_dma_t *) DMA_CON; struct dma_device_info *deu_dma_device_ptr; deu_dma_device_reserved = 0; // get one free page and share between g_dma_block and g_dma_block2 printk("PAGE_SIZE = %lu\n", PAGE_SIZE); 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)); // need 16-byte alignment memory block deu_dma_device_ptr = dma_device_reserve ("DEU"); if (!deu_dma_device_ptr) { printk ("DEU: reserve DMA fail!\n"); return -1; } ifx_deu[0].dma_device = deu_dma_device_ptr; dma_device = deu_dma_device_ptr; 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->max_rx_chan_num = 1; dma_device->max_tx_chan_num = 1; dma_device->tx_burst_len = 4; 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 = AMAZON_S_DMA_CH_ON; dma_device->rx_chan[i]->byte_offset = 0; } for (i = 0; i < dma_device->max_tx_chan_num; i++) { dma_device->tx_chan[i]->control = AMAZON_S_DMA_CH_ON; dma_device->tx_chan[i]->desc_len = 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->controlr.BS = 0; dma->controlr.RXCLS = 0; dma->controlr.EN = 1; return 0; }