[libtapi]
[openwrt/svn-archive/archive.git] / target / linux / ifxmips / files / drivers / crypto / ifxmips / ifxmips_deu_danube.c
1 /*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; either version 2 of the License, or
5 * (at your option) any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
15 *
16 * Copyright (C) 2010 Ralph Hempel <ralph.hempel@lantiq.com>
17 * Copyright (C) 2009 Mohammad Firdaus
18 */
19
20 /*!
21 \defgroup IFX_DEU IFX_DEU_DRIVERS
22 \ingroup API
23 \brief deu driver module
24 */
25
26 /*!
27 \file ifxmips_deu_danube.c
28 \ingroup IFX_DEU
29 \brief board specific deu driver file for danube
30 */
31
32 /*!
33 \defgroup BOARD_SPECIFIC_FUNCTIONS IFX_BOARD_SPECIFIC_FUNCTIONS
34 \ingroup IFX_DEU
35 \brief board specific deu functions
36 */
37
38 /* Project header files */
39 #include <linux/module.h>
40 #include <linux/init.h>
41 #include <linux/types.h>
42 #include <linux/errno.h>
43 #include <asm/io.h> //dma_cache_inv
44 #include "ifxmips_deu.h"
45
46 #ifdef CONFIG_CRYPTO_DEV_IFXMIPS_DMA
47 u32 *des_buff_in = NULL;
48 u32 *des_buff_out = NULL;
49 u32 *aes_buff_in = NULL;
50 u32 *aes_buff_out = NULL;
51 _ifx_deu_device ifx_deu[1];
52 #endif
53
54 /* Function Declerations */
55 int aes_memory_allocate(int value);
56 int des_memory_allocate(int value);
57 void memory_release(u32 *addr);
58 int aes_chip_init (void);
59 void des_chip_init (void);
60 int deu_dma_init (void);
61 u32 endian_swap(u32 input);
62 u32* memory_alignment(const u8 *arg, u32 *buff_alloc, int in_out, int nbytes);
63 void dma_memory_copy(u32 *outcopy, u32 *out_dma, u8 *out_arg, int nbytes);
64 void __exit ifxdeu_fini_dma(void);
65
66 #define DES_3DES_START IFX_DES_CON
67 #define AES_START IFX_AES_CON
68
69 /* Variables definition */
70 int ifx_danube_pre_1_4;
71 u8 *g_dma_page_ptr = NULL;
72 u8 *g_dma_block = NULL;
73 u8 *g_dma_block2 = NULL;
74
75
76 /*! \fn int deu_dma_init (void)
77 * \ingroup BOARD_SPECIFIC_FUNCTIONS
78 * \brief Initialize DMA for DEU usage. DMA specific registers are
79 * intialized here, including a pointer to the device, memory
80 * space for the device and DEU-DMA descriptors
81 * \return -1 if fail, otherwise return 0
82 */
83
84 #ifdef CONFIG_CRYPTO_DEV_IFXMIPS_DMA
85 int deu_dma_init (void)
86 {
87 struct dma_device_info *dma_device = NULL;
88 int i = 0;
89 volatile struct deu_dma_t *dma = (struct deu_dma_t *) IFX_DEU_DMA_CON;
90 struct dma_device_info *deu_dma_device_ptr;
91
92 // get one free page and share between g_dma_block and g_dma_block2
93 printk("PAGE_SIZE = %ld\n", PAGE_SIZE);
94 g_dma_page_ptr = (u8 *)__get_free_page(GFP_KERNEL); // need 16-byte alignment memory block
95 g_dma_block = g_dma_page_ptr; // need 16-byte alignment memory block
96 g_dma_block2 = (u8 *)(g_dma_page_ptr + (PAGE_SIZE >> 1)); // need 16-byte alignment memory block
97
98
99 deu_dma_device_ptr = dma_device_reserve ("DEU");
100 if (!deu_dma_device_ptr) {
101 printk ("DEU: reserve DMA fail!\n");
102 return -1;
103 }
104 ifx_deu[0].dma_device = deu_dma_device_ptr;
105 dma_device = deu_dma_device_ptr;
106 //dma_device->priv = &deu_dma_priv;
107 dma_device->buffer_alloc = &deu_dma_buffer_alloc;
108 dma_device->buffer_free = &deu_dma_buffer_free;
109 dma_device->intr_handler = &deu_dma_intr_handler;
110 dma_device->tx_endianness_mode = IFX_DMA_ENDIAN_TYPE3;
111 dma_device->rx_endianness_mode = IFX_DMA_ENDIAN_TYPE3;
112 dma_device->port_num = 1;
113 dma_device->tx_burst_len = 4;
114 dma_device->max_rx_chan_num = 1;
115 dma_device->max_tx_chan_num = 1;
116 dma_device->port_packet_drop_enable = 0;
117
118 for (i = 0; i < dma_device->max_rx_chan_num; i++) {
119 dma_device->rx_chan[i]->packet_size = DEU_MAX_PACKET_SIZE;
120 dma_device->rx_chan[i]->desc_len = 1;
121 dma_device->rx_chan[i]->control = IFX_DMA_CH_ON;
122 dma_device->rx_chan[i]->byte_offset = 0;
123 dma_device->rx_chan[i]->chan_poll_enable = 1;
124
125 }
126
127 for (i = 0; i < dma_device->max_tx_chan_num; i++) {
128 dma_device->tx_chan[i]->control = IFX_DMA_CH_ON;
129 dma_device->tx_chan[i]->desc_len = 1;
130 dma_device->tx_chan[i]->chan_poll_enable = 1;
131 }
132
133 dma_device->current_tx_chan = 0;
134 dma_device->current_rx_chan = 0;
135
136 dma_device_register (dma_device);
137 for (i = 0; i < dma_device->max_rx_chan_num; i++) {
138 (dma_device->rx_chan[i])->open (dma_device->rx_chan[i]);
139 }
140
141 dma->controlr.BS = 0;
142 dma->controlr.RXCLS = 0;
143 dma->controlr.EN = 1;
144
145
146 *IFX_DMA_PS = 1;
147
148 /* DANUBE PRE 1.4 SOFTWARE FIX */
149 if (ifx_danube_pre_1_4)
150 *IFX_DMA_PCTRL = 0x14;
151 else
152 *IFX_DMA_PCTRL = 0xF14;
153
154 return 0;
155 }
156
157 /*! \fn u32 *memory_alignment(const u8 *arg, u32 *buffer_alloc, int in_buff, int nbytes)
158 * \ingroup BOARD_SPECIFIC_FUNCTIONS
159 * \brief A fix to align mis-aligned address for Danube version 1.3 chips which has
160 * memory alignment issues.
161 * \param arg Pointer to the input / output memory address
162 * \param buffer_alloc A pointer to the buffer
163 * \param in_buff Input (if == 1) or Output (if == 0) buffer
164 * \param nbytes Number of bytes of data
165 * \return returns arg: if address is aligned, buffer_alloc: if memory address is not aligned
166 */
167
168 u32 *memory_alignment(const u8 *arg, u32 *buffer_alloc, int in_buff, int nbytes)
169 {
170 if (ifx_danube_pre_1_4) {
171 /* for input buffer */
172 if(in_buff) {
173 if (((u32) arg) & 0xF) {
174 memcpy(buffer_alloc, arg, nbytes);
175 return (u32 *) buffer_alloc;
176 }
177 else
178 return (u32 *) arg;
179 }
180 else {
181 /* for output buffer */
182 if (((u32) arg) & 0x3)
183 return buffer_alloc;
184 else
185 return (u32 *) arg;
186 }
187 }
188
189 return (u32 *) arg;
190 }
191
192 /*! \fn void aes_dma_memory_copy(u32 *outcopy, u32 *out_dma, u8 *out_arg, int nbytes)
193 * \ingroup BOARD_SPECIFIC_FUNCTIONS
194 * \brief copy the DMA data to the memory address space for AES. The swaping of the 4 bytes
195 * is done only for Danube version 1.3 (FIX). Otherwise, it is a direct memory copy
196 * to out_arg pointer
197 * \param outcopy Pointer to the address to store swapped copy
198 * \param out_dma A pointer to the memory address that stores the DMA data
199 * \param out_arg The pointer to the memory address that needs to be copied to
200 * \param nbytes Number of bytes of data
201 */
202
203 void aes_dma_memory_copy(u32 *outcopy, u32 *out_dma, u8 *out_arg, int nbytes)
204 {
205 int i = 0;
206 int x = 0;
207
208 /* DANUBE PRE 1.4 SOFTWARE FIX */
209 if (ifx_danube_pre_1_4) {
210 for (i = 0; i < (nbytes / 4); i++) {
211 x = i ^ 0x3;
212 outcopy[i] = out_dma[x];
213
214 }
215 if (((u32) out_arg) & 0x3) {
216 memcpy((u8 *)out_arg, outcopy, nbytes);
217 }
218 }
219 else
220 memcpy (out_arg, out_dma, nbytes);
221 }
222
223 /*! \fn void des_dma_memory_copy(u32 *outcopy, u32 *out_dma, u8 *out_arg, int nbytes)
224 * \ingroup BOARD_SPECIFIC_FUNCTIONS
225 * \brief copy the DMA data to the memory address space for DES. The swaping of the 4 bytes
226 * is done only for Danube version 1.3 (FIX). Otherwise, it is a direct memory copy
227 * to out_arg pointer
228 *
229 * \param outcopy Pointer to the address to store swapped copy
230 * \param out_dma A pointer to the memory address that stores the DMA data
231 * \param out_arg The pointer to the memory address that needs to be copied to
232 * \param nbytes Number of bytes of data
233 */
234
235 void des_dma_memory_copy(u32 *outcopy, u32 *out_dma, u8 *out_arg, int nbytes)
236 {
237 int i = 0;
238 int x = 0;
239
240 /* DANUBE PRE 1.4 SOFTWARE FIX */
241 if (ifx_danube_pre_1_4) {
242 for (i = 0; i < (nbytes / 4); i++) {
243 x = i ^ 1;
244 outcopy[i] = out_dma[x];
245
246 }
247 if (((u32) out_arg) & 0x3) {
248 memcpy((u8 *)out_arg, outcopy, nbytes);
249 }
250 }
251 else
252 memcpy (out_arg, out_dma, nbytes);
253 }
254
255 /*! \fn int des_memory_allocate(int value)
256 * \ingroup BOARD_SPECIFIC_FUNCTIONS
257 * \brief allocates memory to the necessary memory input/output buffer location, used during
258 * the DES algorithm DMA transfer (memory alignment issues)
259 * \param value value determinds whether the calling of the function is for a input buffer
260 * or for an output buffer memory allocation
261 */
262
263 int des_memory_allocate(int value)
264 {
265 if (ifx_danube_pre_1_4) {
266 if (value == BUFFER_IN) {
267 des_buff_in = kmalloc(DEU_MAX_PACKET_SIZE, GFP_ATOMIC);
268 if (!des_buff_in)
269 return -1;
270 else
271 return 0;
272 }
273 else {
274 des_buff_out = kmalloc(DEU_MAX_PACKET_SIZE, GFP_ATOMIC);
275 if (!des_buff_out)
276 return -1;
277 else
278 return 0;
279 }
280 }
281
282 else
283 return 0;
284 }
285
286 /*! \fn int aes_memory_allocate(int value)
287 * \ingroup BOARD_SPECIFIC_FUNCTIONS
288 * \brief allocates memory to the necessary memory input/output buffer location, used during
289 * the AES algorithm DMA transfer (memory alignment issues)
290 * \param value value determinds whether the calling of the function is for a input buffer
291 * or for an output buffer memory allocation
292 */
293
294 int aes_memory_allocate(int value)
295 {
296 if (ifx_danube_pre_1_4) {
297 if (value == BUFFER_IN) {
298 aes_buff_in = kmalloc(DEU_MAX_PACKET_SIZE, GFP_ATOMIC);
299 if (!aes_buff_in)
300 return -1;
301 else
302 return 0;
303 }
304 else {
305 aes_buff_out = kmalloc(DEU_MAX_PACKET_SIZE, GFP_ATOMIC);
306 if (!aes_buff_out)
307 return -1;
308 else
309 return 0;
310 }
311 }
312
313 else
314 return 0;
315 }
316
317 /*! \fn void memory_release(u32 *addr)
318 * \ingroup BOARD_SPECIFIC_FUNCTIONS
319 * \brief frees previously allocated memory
320 * \param addr memory address of the buffer that needs to be freed
321 */
322
323 void memory_release(u32 *addr)
324 {
325 if (addr)
326 kfree(addr);
327 return;
328 }
329
330 /*! \fn __exit ifxdeu_fini_dma(void)
331 * \ingroup BOARD_SPECIFIC_FUNCTIONS
332 * \brief unregister dma devices after exit
333 */
334
335 void __exit ifxdeu_fini_dma(void)
336 {
337 if (g_dma_page_ptr)
338 free_page((u32) g_dma_page_ptr);
339 dma_device_release(ifx_deu[0].dma_device);
340 dma_device_unregister(ifx_deu[0].dma_device);
341
342 }
343
344 #endif /* CONFIG_CRYPTO_DEV_IFXMIPS_DMA */
345
346 /*! \fn u32 endian_swap(u32 input)
347 * \ingroup BOARD_SPECIFIC_FUNCTIONS
348 * \brief function is not used
349 * \param input Data input to be swapped
350 * \return input
351 */
352
353 u32 endian_swap(u32 input)
354 {
355 return input;
356 }
357
358 /*! \fn u32 input_swap(u32 input)
359 * \ingroup BOARD_SPECIFIC_FUNCTIONS
360 * \brief Swap the input data if the current chip is Danube version
361 * 1.4 and do nothing to the data if the current chip is
362 * Danube version 1.3
363 * \param input data that needs to be swapped
364 * \return input or swapped input
365 */
366
367 u32 input_swap(u32 input)
368 {
369 if (!ifx_danube_pre_1_4) {
370 u8 *ptr = (u8 *)&input;
371 return ((ptr[3] << 24) | (ptr[2] << 16) | (ptr[1] << 8) | ptr[0]);
372 }
373 else
374 return input;
375 }
376
377
378
379 /*! \fn void aes_chip_init (void)
380 * \ingroup BOARD_SPECIFIC_FUNCTIONS
381 * \brief initialize AES hardware
382 */
383
384 int aes_chip_init (void)
385 {
386 volatile struct aes_t *aes = (struct aes_t *) AES_START;
387
388 #ifndef CONFIG_CRYPTO_DEV_IFXMIPS_DMA
389 //start crypto engine with write to ILR
390 aes->controlr.SM = 1;
391 aes->controlr.ARS = 1;
392 #else
393 aes->controlr.SM = 1;
394 aes->controlr.ARS = 1; // 0 for dma
395 #endif
396 return 0;
397 }
398
399 /*! \fn void des_chip_init (void)
400 * \ingroup BOARD_SPECIFIC_FUNCTIONS
401 * \brief initialize DES hardware
402 */
403
404 void des_chip_init (void)
405 {
406 volatile struct des_t *des = (struct des_t *) DES_3DES_START;
407
408 #ifndef CONFIG_CRYPTO_DEV_IFXMIPS_DMA
409 // start crypto engine with write to ILR
410 des->controlr.SM = 1;
411 des->controlr.ARS = 1;
412 #else
413 des->controlr.SM = 1;
414 des->controlr.ARS = 1; // 0 for dma
415
416 #endif
417 }
418
419 /*! \fn void chip_version (void)
420 * \ingroup IFX_DES_FUNCTIONS
421 * \brief To find the version of the chip by looking at the chip ID
422 * \param ifx_danube_pre_1_4 (sets to 1 if Chip is Danube less than v1.4)
423 */
424
425 void chip_version(void)
426 {
427 /* DANUBE PRE 1.4 SOFTWARE FIX */
428 int chip_id = 0;
429 chip_id = *IFX_MPS_CHIPID;
430 chip_id >>= 28;
431
432 if (chip_id >= 4) {
433 ifx_danube_pre_1_4 = 0;
434 printk("Danube Chip ver. 1.4 detected. \n");
435 }
436 else {
437 ifx_danube_pre_1_4 = 1;
438 printk("Danube Chip ver. 1.3 or below detected. \n");
439 }
440
441 return;
442 }
443