Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/djbw/async_tx
[pandora-kernel.git] / drivers / staging / sep / sep_driver.c
1 /*
2  *
3  *  sep_driver.c - Security Processor Driver main group of functions
4  *
5  *  Copyright(c) 2009 Intel Corporation. All rights reserved.
6  *  Copyright(c) 2009 Discretix. All rights reserved.
7  *
8  *  This program is free software; you can redistribute it and/or modify it
9  *  under the terms of the GNU General Public License as published by the Free
10  *  Software Foundation; either version 2 of the License, or (at your option)
11  *  any later version.
12  *
13  *  This program is distributed in the hope that it will be useful, but WITHOUT
14  *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15  *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
16  *  more details.
17  *
18  *  You should have received a copy of the GNU General Public License along with
19  *  this program; if not, write to the Free Software Foundation, Inc., 59
20  *  Temple Place - Suite 330, Boston, MA  02111-1307, USA.
21  *
22  *  CONTACTS:
23  *
24  *  Mark Allyn          mark.a.allyn@intel.com
25  *
26  *  CHANGES:
27  *
28  *  2009.06.26  Initial publish
29  *
30  */
31
32 #include <linux/init.h>
33 #include <linux/module.h>
34 #include <linux/fs.h>
35 #include <linux/cdev.h>
36 #include <linux/kdev_t.h>
37 #include <linux/mutex.h>
38 #include <linux/sched.h>
39 #include <linux/mm.h>
40 #include <linux/poll.h>
41 #include <linux/wait.h>
42 #include <linux/pci.h>
43 #include <linux/firmware.h>
44 #include <linux/slab.h>
45 #include <asm/ioctl.h>
46 #include <linux/ioport.h>
47 #include <asm/io.h>
48 #include <linux/interrupt.h>
49 #include <linux/pagemap.h>
50 #include <asm/cacheflush.h>
51 #include "sep_driver_hw_defs.h"
52 #include "sep_driver_config.h"
53 #include "sep_driver_api.h"
54 #include "sep_dev.h"
55
56 #if SEP_DRIVER_ARM_DEBUG_MODE
57
58 #define  CRYS_SEP_ROM_length                  0x4000
59 #define  CRYS_SEP_ROM_start_address           0x8000C000UL
60 #define  CRYS_SEP_ROM_start_address_offset    0xC000UL
61 #define  SEP_ROM_BANK_register                0x80008420UL
62 #define  SEP_ROM_BANK_register_offset         0x8420UL
63 #define SEP_RAR_IO_MEM_REGION_START_ADDRESS   0x82000000
64
65 /*
66  * THESE 2 definitions are specific to the board - must be
67  * defined during integration
68  */
69 #define SEP_RAR_IO_MEM_REGION_START_ADDRESS   0xFF0D0000
70
71 /* 2M size */
72
73 static void sep_load_rom_code(struct sep_device *sep)
74 {
75         /* Index variables */
76         unsigned long i, k, j;
77         u32 reg;
78         u32 error;
79         u32 warning;
80
81         /* Loading ROM from SEP_ROM_image.h file */
82         k = sizeof(CRYS_SEP_ROM);
83
84         edbg("SEP Driver: DX_CC_TST_SepRomLoader start\n");
85
86         edbg("SEP Driver: k is %lu\n", k);
87         edbg("SEP Driver: sep->reg_addr is %p\n", sep->reg_addr);
88         edbg("SEP Driver: CRYS_SEP_ROM_start_address_offset is %p\n", CRYS_SEP_ROM_start_address_offset);
89
90         for (i = 0; i < 4; i++) {
91                 /* write bank */
92                 sep_write_reg(sep, SEP_ROM_BANK_register_offset, i);
93
94                 for (j = 0; j < CRYS_SEP_ROM_length / 4; j++) {
95                         sep_write_reg(sep, CRYS_SEP_ROM_start_address_offset + 4 * j, CRYS_SEP_ROM[i * 0x1000 + j]);
96
97                         k = k - 4;
98
99                         if (k == 0) {
100                                 j = CRYS_SEP_ROM_length;
101                                 i = 4;
102                         }
103                 }
104         }
105
106         /* reset the SEP */
107         sep_write_reg(sep, HW_HOST_SEP_SW_RST_REG_ADDR, 0x1);
108
109         /* poll for SEP ROM boot finish */
110         do
111                 reg = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR3_REG_ADDR);
112         while (!reg);
113
114         edbg("SEP Driver: ROM polling ended\n");
115
116         switch (reg) {
117         case 0x1:
118                 /* fatal error - read erro status from GPRO */
119                 error = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR0_REG_ADDR);
120                 edbg("SEP Driver: ROM polling case 1\n");
121                 break;
122         case 0x4:
123                 /* Cold boot ended successfully  */
124         case 0x8:
125                 /* Warmboot ended successfully */
126         case 0x10:
127                 /* ColdWarm boot ended successfully */
128                 error = 0;
129         case 0x2:
130                 /* Boot First Phase ended  */
131                 warning = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR0_REG_ADDR);
132         case 0x20:
133                 edbg("SEP Driver: ROM polling case %d\n", reg);
134                 break;
135         }
136
137 }
138
139 #else
140 static void sep_load_rom_code(struct sep_device *sep) { }
141 #endif                          /* SEP_DRIVER_ARM_DEBUG_MODE */
142
143
144
145 /*----------------------------------------
146         DEFINES
147 -----------------------------------------*/
148
149 #define BASE_ADDRESS_FOR_SYSTEM 0xfffc0000
150 #define SEP_RAR_IO_MEM_REGION_SIZE 0x40000
151
152 /*--------------------------------------------
153         GLOBAL variables
154 --------------------------------------------*/
155
156 /* debug messages level */
157 static int debug;
158 module_param(debug, int , 0);
159 MODULE_PARM_DESC(debug, "Flag to enable SEP debug messages");
160
161 /* Keep this a single static object for now to keep the conversion easy */
162
163 static struct sep_device sep_instance;
164 static struct sep_device *sep_dev = &sep_instance;
165
166 /*
167   mutex for the access to the internals of the sep driver
168 */
169 static DEFINE_MUTEX(sep_mutex);
170
171
172 /* wait queue head (event) of the driver */
173 static DECLARE_WAIT_QUEUE_HEAD(sep_event);
174
175 /**
176  *      sep_load_firmware       -       copy firmware cache/resident
177  *      @sep: device we are loading
178  *
179  *      This functions copies the cache and resident from their source
180  *      location into destination shared memory.
181  */
182
183 static int sep_load_firmware(struct sep_device *sep)
184 {
185         const struct firmware *fw;
186         char *cache_name = "sep/cache.image.bin";
187         char *res_name = "sep/resident.image.bin";
188         int error;
189
190         edbg("SEP Driver:rar_virtual is %p\n", sep->rar_addr);
191         edbg("SEP Driver:rar_bus is %08llx\n", (unsigned long long)sep->rar_bus);
192
193         /* load cache */
194         error = request_firmware(&fw, cache_name, &sep->pdev->dev);
195         if (error) {
196                 edbg("SEP Driver:cant request cache fw\n");
197                 return error;
198         }
199         edbg("SEP Driver:cache %08Zx@%p\n", fw->size, (void *) fw->data);
200
201         memcpy(sep->rar_addr, (void *)fw->data, fw->size);
202         sep->cache_size = fw->size;
203         release_firmware(fw);
204
205         sep->resident_bus = sep->rar_bus + sep->cache_size;
206         sep->resident_addr = sep->rar_addr + sep->cache_size;
207
208         /* load resident */
209         error = request_firmware(&fw, res_name, &sep->pdev->dev);
210         if (error) {
211                 edbg("SEP Driver:cant request res fw\n");
212                 return error;
213         }
214         edbg("sep: res %08Zx@%p\n", fw->size, (void *)fw->data);
215
216         memcpy(sep->resident_addr, (void *) fw->data, fw->size);
217         sep->resident_size = fw->size;
218         release_firmware(fw);
219
220         edbg("sep: resident v %p b %08llx cache v %p b %08llx\n",
221                 sep->resident_addr, (unsigned long long)sep->resident_bus,
222                 sep->rar_addr, (unsigned long long)sep->rar_bus);
223         return 0;
224 }
225
226 MODULE_FIRMWARE("sep/cache.image.bin");
227 MODULE_FIRMWARE("sep/resident.image.bin");
228
229 /**
230  *      sep_map_and_alloc_shared_area   -       allocate shared block
231  *      @sep: security processor
232  *      @size: size of shared area
233  *
234  *      Allocate a shared buffer in host memory that can be used by both the
235  *      kernel and also the hardware interface via DMA.
236  */
237
238 static int sep_map_and_alloc_shared_area(struct sep_device *sep,
239                                                         unsigned long size)
240 {
241         /* shared_addr = ioremap_nocache(0xda00000,shared_area_size); */
242         sep->shared_addr = dma_alloc_coherent(&sep->pdev->dev, size,
243                                         &sep->shared_bus, GFP_KERNEL);
244
245         if (!sep->shared_addr) {
246                 edbg("sep_driver :shared memory dma_alloc_coherent failed\n");
247                 return -ENOMEM;
248         }
249         /* set the bus address of the shared area */
250         edbg("sep: shared_addr %ld bytes @%p (bus %08llx)\n",
251                 size, sep->shared_addr, (unsigned long long)sep->shared_bus);
252         return 0;
253 }
254
255 /**
256  *      sep_unmap_and_free_shared_area  -       free shared block
257  *      @sep: security processor
258  *
259  *      Free the shared area allocated to the security processor. The
260  *      processor must have finished with this and any final posted
261  *      writes cleared before we do so.
262  */
263 static void sep_unmap_and_free_shared_area(struct sep_device *sep, int size)
264 {
265         dma_free_coherent(&sep->pdev->dev, size,
266                                 sep->shared_addr, sep->shared_bus);
267 }
268
269 /**
270  *      sep_shared_virt_to_bus  -       convert bus/virt addresses
271  *
272  *      Returns the bus address inside the shared area according
273  *      to the virtual address.
274  */
275
276 static dma_addr_t sep_shared_virt_to_bus(struct sep_device *sep,
277                                                 void *virt_address)
278 {
279         dma_addr_t pa = sep->shared_bus + (virt_address - sep->shared_addr);
280         edbg("sep: virt to bus b %08llx v %p\n", (unsigned long long) pa,
281                                                                 virt_address);
282         return pa;
283 }
284
285 /**
286  *      sep_shared_bus_to_virt  -       convert bus/virt addresses
287  *
288  *      Returns virtual address inside the shared area according
289  *      to the bus address.
290  */
291
292 static void *sep_shared_bus_to_virt(struct sep_device *sep,
293                                                 dma_addr_t bus_address)
294 {
295         return sep->shared_addr + (bus_address - sep->shared_bus);
296 }
297
298
299 /**
300  *      sep_try_open            -       attempt to open a SEP device
301  *      @sep: device to attempt to open
302  *
303  *      Atomically attempt to get ownership of a SEP device.
304  *      Returns 1 if the device was opened, 0 on failure.
305  */
306
307 static int sep_try_open(struct sep_device *sep)
308 {
309         if (!test_and_set_bit(0, &sep->in_use))
310                 return 1;
311         return 0;
312 }
313
314 /**
315  *      sep_open                -       device open method
316  *      @inode: inode of sep device
317  *      @filp: file handle to sep device
318  *
319  *      Open method for the SEP device. Called when userspace opens
320  *      the SEP device node. Must also release the memory data pool
321  *      allocations.
322  *
323  *      Returns zero on success otherwise an error code.
324  */
325
326 static int sep_open(struct inode *inode, struct file *filp)
327 {
328         if (sep_dev == NULL)
329                 return -ENODEV;
330
331         /* check the blocking mode */
332         if (filp->f_flags & O_NDELAY) {
333                 if (sep_try_open(sep_dev) == 0)
334                         return -EAGAIN;
335         } else
336                 if (wait_event_interruptible(sep_event, sep_try_open(sep_dev)) < 0)
337                         return -EINTR;
338
339         /* Bind to the device, we only have one which makes it easy */
340         filp->private_data = sep_dev;
341         /* release data pool allocations */
342         sep_dev->data_pool_bytes_allocated = 0;
343         return 0;
344 }
345
346
347 /**
348  *      sep_release             -       close a SEP device
349  *      @inode: inode of SEP device
350  *      @filp: file handle being closed
351  *
352  *      Called on the final close of a SEP device. As the open protects against
353  *      multiple simultaenous opens that means this method is called when the
354  *      final reference to the open handle is dropped.
355  */
356
357 static int sep_release(struct inode *inode, struct file *filp)
358 {
359         struct sep_device *sep =  filp->private_data;
360 #if 0                           /*!SEP_DRIVER_POLLING_MODE */
361         /* close IMR */
362         sep_write_reg(sep, HW_HOST_IMR_REG_ADDR, 0x7FFF);
363         /* release IRQ line */
364         free_irq(SEP_DIRVER_IRQ_NUM, sep);
365
366 #endif
367         /* Ensure any blocked open progresses */
368         clear_bit(0, &sep->in_use);
369         wake_up(&sep_event);
370         return 0;
371 }
372
373 /*---------------------------------------------------------------
374   map function - this functions maps the message shared area
375 -----------------------------------------------------------------*/
376 static int sep_mmap(struct file *filp, struct vm_area_struct *vma)
377 {
378         dma_addr_t bus_addr;
379         struct sep_device *sep = filp->private_data;
380
381         dbg("-------->SEP Driver: mmap start\n");
382
383         /* check that the size of the mapped range is as the size of the message
384            shared area */
385         if ((vma->vm_end - vma->vm_start) > SEP_DRIVER_MMMAP_AREA_SIZE) {
386                 edbg("SEP Driver mmap requested size is more than allowed\n");
387                 printk(KERN_WARNING "SEP Driver mmap requested size is more than allowed\n");
388                 printk(KERN_WARNING "SEP Driver vma->vm_end is %08lx\n", vma->vm_end);
389                 printk(KERN_WARNING "SEP Driver vma->vm_end is %08lx\n", vma->vm_start);
390                 return -EAGAIN;
391         }
392
393         edbg("SEP Driver:sep->shared_addr is %p\n", sep->shared_addr);
394
395         /* get bus address */
396         bus_addr = sep->shared_bus;
397
398         edbg("SEP Driver: phys_addr is %08llx\n", (unsigned long long)bus_addr);
399
400         if (remap_pfn_range(vma, vma->vm_start, bus_addr >> PAGE_SHIFT, vma->vm_end - vma->vm_start, vma->vm_page_prot)) {
401                 edbg("SEP Driver remap_page_range failed\n");
402                 printk(KERN_WARNING "SEP Driver remap_page_range failed\n");
403                 return -EAGAIN;
404         }
405
406         dbg("SEP Driver:<-------- mmap end\n");
407
408         return 0;
409 }
410
411
412 /*-----------------------------------------------
413   poll function
414 *----------------------------------------------*/
415 static unsigned int sep_poll(struct file *filp, poll_table * wait)
416 {
417         unsigned long count;
418         unsigned int mask = 0;
419         unsigned long retval = 0;       /* flow id */
420         struct sep_device *sep = filp->private_data;
421
422         dbg("---------->SEP Driver poll: start\n");
423
424
425 #if SEP_DRIVER_POLLING_MODE
426
427         while (sep->send_ct != (retval & 0x7FFFFFFF)) {
428                 retval = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR2_REG_ADDR);
429
430                 for (count = 0; count < 10 * 4; count += 4)
431                         edbg("Poll Debug Word %lu of the message is %lu\n", count, *((unsigned long *) (sep->shared_addr + SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES + count)));
432         }
433
434         sep->reply_ct++;
435 #else
436         /* add the event to the polling wait table */
437         poll_wait(filp, &sep_event, wait);
438
439 #endif
440
441         edbg("sep->send_ct is %lu\n", sep->send_ct);
442         edbg("sep->reply_ct is %lu\n", sep->reply_ct);
443
444         /* check if the data is ready */
445         if (sep->send_ct == sep->reply_ct) {
446                 for (count = 0; count < 12 * 4; count += 4)
447                         edbg("Sep Mesg Word %lu of the message is %lu\n", count, *((unsigned long *) (sep->shared_addr + count)));
448
449                 for (count = 0; count < 10 * 4; count += 4)
450                         edbg("Debug Data Word %lu of the message is %lu\n", count, *((unsigned long *) (sep->shared_addr + 0x1800 + count)));
451
452                 retval = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR2_REG_ADDR);
453                 edbg("retval is %lu\n", retval);
454                 /* check if the this is sep reply or request */
455                 if (retval >> 31) {
456                         edbg("SEP Driver: sep request in\n");
457                         /* request */
458                         mask |= POLLOUT | POLLWRNORM;
459                 } else {
460                         edbg("SEP Driver: sep reply in\n");
461                         mask |= POLLIN | POLLRDNORM;
462                 }
463         }
464         dbg("SEP Driver:<-------- poll exit\n");
465         return mask;
466 }
467
468 /**
469  *      sep_time_address        -       address in SEP memory of time
470  *      @sep: SEP device we want the address from
471  *
472  *      Return the address of the two dwords in memory used for time
473  *      setting.
474  */
475
476 static u32 *sep_time_address(struct sep_device *sep)
477 {
478         return sep->shared_addr + SEP_DRIVER_SYSTEM_TIME_MEMORY_OFFSET_IN_BYTES;
479 }
480
481 /**
482  *      sep_set_time            -       set the SEP time
483  *      @sep: the SEP we are setting the time for
484  *
485  *      Calculates time and sets it at the predefined address.
486  *      Called with the sep mutex held.
487  */
488 static unsigned long sep_set_time(struct sep_device *sep)
489 {
490         struct timeval time;
491         u32 *time_addr; /* address of time as seen by the kernel */
492
493
494         dbg("sep:sep_set_time start\n");
495
496         do_gettimeofday(&time);
497
498         /* set value in the SYSTEM MEMORY offset */
499         time_addr = sep_time_address(sep);
500
501         time_addr[0] = SEP_TIME_VAL_TOKEN;
502         time_addr[1] = time.tv_sec;
503
504         edbg("SEP Driver:time.tv_sec is %lu\n", time.tv_sec);
505         edbg("SEP Driver:time_addr is %p\n", time_addr);
506         edbg("SEP Driver:sep->shared_addr is %p\n", sep->shared_addr);
507
508         return time.tv_sec;
509 }
510
511 /**
512  *      sep_dump_message        - dump the message that is pending
513  *      @sep: sep device
514  *
515  *      Dump out the message pending in the shared message area
516  */
517
518 static void sep_dump_message(struct sep_device *sep)
519 {
520         int count;
521         for (count = 0; count < 12 * 4; count += 4)
522                 edbg("Word %d of the message is %u\n", count, *((u32 *) (sep->shared_addr + count)));
523 }
524
525 /**
526  *      sep_send_command_handler        -       kick off a command
527  *      @sep: sep being signalled
528  *
529  *      This function raises interrupt to SEP that signals that is has a new
530  *      command from the host
531  */
532
533 static void sep_send_command_handler(struct sep_device *sep)
534 {
535         dbg("sep:sep_send_command_handler start\n");
536
537         mutex_lock(&sep_mutex);
538         sep_set_time(sep);
539
540         /* FIXME: flush cache */
541         flush_cache_all();
542
543         sep_dump_message(sep);
544         /* update counter */
545         sep->send_ct++;
546         /* send interrupt to SEP */
547         sep_write_reg(sep, HW_HOST_HOST_SEP_GPR0_REG_ADDR, 0x2);
548         dbg("SEP Driver:<-------- sep_send_command_handler end\n");
549         mutex_unlock(&sep_mutex);
550         return;
551 }
552
553 /**
554  *      sep_send_reply_command_handler  -       kick off a command reply
555  *      @sep: sep being signalled
556  *
557  *      This function raises interrupt to SEP that signals that is has a new
558  *      command from the host
559  */
560
561 static void sep_send_reply_command_handler(struct sep_device *sep)
562 {
563         dbg("sep:sep_send_reply_command_handler start\n");
564
565         /* flash cache */
566         flush_cache_all();
567
568         sep_dump_message(sep);
569
570         mutex_lock(&sep_mutex);
571         sep->send_ct++;         /* update counter */
572         /* send the interrupt to SEP */
573         sep_write_reg(sep, HW_HOST_HOST_SEP_GPR2_REG_ADDR, sep->send_ct);
574         /* update both counters */
575         sep->send_ct++;
576         sep->reply_ct++;
577         mutex_unlock(&sep_mutex);
578         dbg("sep: sep_send_reply_command_handler end\n");
579 }
580
581 /*
582   This function handles the allocate data pool memory request
583   This function returns calculates the bus address of the
584   allocated memory, and the offset of this area from the mapped address.
585   Therefore, the FVOs in user space can calculate the exact virtual
586   address of this allocated memory
587 */
588 static int sep_allocate_data_pool_memory_handler(struct sep_device *sep,
589                                                         unsigned long arg)
590 {
591         int error;
592         struct sep_driver_alloc_t command_args;
593
594         dbg("SEP Driver:--------> sep_allocate_data_pool_memory_handler start\n");
595
596         error = copy_from_user(&command_args, (void *) arg, sizeof(struct sep_driver_alloc_t));
597         if (error)
598                 goto end_function;
599
600         /* allocate memory */
601         if ((sep->data_pool_bytes_allocated + command_args.num_bytes) > SEP_DRIVER_DATA_POOL_SHARED_AREA_SIZE_IN_BYTES) {
602                 error = -ENOMEM;
603                 goto end_function;
604         }
605
606         /* set the virtual and bus address */
607         command_args.offset = SEP_DRIVER_DATA_POOL_AREA_OFFSET_IN_BYTES + sep->data_pool_bytes_allocated;
608         command_args.phys_address = sep->shared_bus + SEP_DRIVER_DATA_POOL_AREA_OFFSET_IN_BYTES + sep->data_pool_bytes_allocated;
609
610         /* write the memory back to the user space */
611         error = copy_to_user((void *) arg, (void *) &command_args, sizeof(struct sep_driver_alloc_t));
612         if (error)
613                 goto end_function;
614
615         /* set the allocation */
616         sep->data_pool_bytes_allocated += command_args.num_bytes;
617
618 end_function:
619         dbg("SEP Driver:<-------- sep_allocate_data_pool_memory_handler end\n");
620         return error;
621 }
622
623 /*
624   This function  handles write into allocated data pool command
625 */
626 static int sep_write_into_data_pool_handler(struct sep_device *sep, unsigned long arg)
627 {
628         int error;
629         void *virt_address;
630         unsigned long va;
631         unsigned long app_in_address;
632         unsigned long num_bytes;
633         void *data_pool_area_addr;
634
635         dbg("SEP Driver:--------> sep_write_into_data_pool_handler start\n");
636
637         /* get the application address */
638         error = get_user(app_in_address, &(((struct sep_driver_write_t *) arg)->app_address));
639         if (error)
640                 goto end_function;
641
642         /* get the virtual kernel address address */
643         error = get_user(va, &(((struct sep_driver_write_t *) arg)->datapool_address));
644         if (error)
645                 goto end_function;
646         virt_address = (void *)va;
647
648         /* get the number of bytes */
649         error = get_user(num_bytes, &(((struct sep_driver_write_t *) arg)->num_bytes));
650         if (error)
651                 goto end_function;
652
653         /* calculate the start of the data pool */
654         data_pool_area_addr = sep->shared_addr + SEP_DRIVER_DATA_POOL_AREA_OFFSET_IN_BYTES;
655
656
657         /* check that the range of the virtual kernel address is correct */
658         if (virt_address < data_pool_area_addr || virt_address > (data_pool_area_addr + SEP_DRIVER_DATA_POOL_SHARED_AREA_SIZE_IN_BYTES)) {
659                 error = -EINVAL;
660                 goto end_function;
661         }
662         /* copy the application data */
663         error = copy_from_user(virt_address, (void *) app_in_address, num_bytes);
664 end_function:
665         dbg("SEP Driver:<-------- sep_write_into_data_pool_handler end\n");
666         return error;
667 }
668
669 /*
670   this function handles the read from data pool command
671 */
672 static int sep_read_from_data_pool_handler(struct sep_device *sep, unsigned long arg)
673 {
674         int error;
675         /* virtual address of dest application buffer */
676         unsigned long app_out_address;
677         /* virtual address of the data pool */
678         unsigned long va;
679         void *virt_address;
680         unsigned long num_bytes;
681         void *data_pool_area_addr;
682
683         dbg("SEP Driver:--------> sep_read_from_data_pool_handler start\n");
684
685         /* get the application address */
686         error = get_user(app_out_address, &(((struct sep_driver_write_t *) arg)->app_address));
687         if (error)
688                 goto end_function;
689
690         /* get the virtual kernel address address */
691         error = get_user(va, &(((struct sep_driver_write_t *) arg)->datapool_address));
692         if (error)
693                 goto end_function;
694         virt_address = (void *)va;
695
696         /* get the number of bytes */
697         error = get_user(num_bytes, &(((struct sep_driver_write_t *) arg)->num_bytes));
698         if (error)
699                 goto end_function;
700
701         /* calculate the start of the data pool */
702         data_pool_area_addr = sep->shared_addr + SEP_DRIVER_DATA_POOL_AREA_OFFSET_IN_BYTES;
703
704         /* FIXME: These are incomplete all over the driver: what about + len
705            and when doing that also overflows */
706         /* check that the range of the virtual kernel address is correct */
707         if (virt_address < data_pool_area_addr || virt_address > data_pool_area_addr + SEP_DRIVER_DATA_POOL_SHARED_AREA_SIZE_IN_BYTES) {
708                 error = -EINVAL;
709                 goto end_function;
710         }
711
712         /* copy the application data */
713         error = copy_to_user((void *) app_out_address, virt_address, num_bytes);
714 end_function:
715         dbg("SEP Driver:<-------- sep_read_from_data_pool_handler end\n");
716         return error;
717 }
718
719 /*
720   This function releases all the application virtual buffer physical pages,
721         that were previously locked
722 */
723 static int sep_free_dma_pages(struct page **page_array_ptr, unsigned long num_pages, unsigned long dirtyFlag)
724 {
725         unsigned long count;
726
727         if (dirtyFlag) {
728                 for (count = 0; count < num_pages; count++) {
729                         /* the out array was written, therefore the data was changed */
730                         if (!PageReserved(page_array_ptr[count]))
731                                 SetPageDirty(page_array_ptr[count]);
732                         page_cache_release(page_array_ptr[count]);
733                 }
734         } else {
735                 /* free in pages - the data was only read, therefore no update was done
736                    on those pages */
737                 for (count = 0; count < num_pages; count++)
738                         page_cache_release(page_array_ptr[count]);
739         }
740
741         if (page_array_ptr)
742                 /* free the array */
743                 kfree(page_array_ptr);
744
745         return 0;
746 }
747
748 /*
749   This function locks all the physical pages of the kernel virtual buffer
750   and construct a basic lli  array, where each entry holds the physical
751   page address and the size that application data holds in this physical pages
752 */
753 static int sep_lock_kernel_pages(struct sep_device *sep,
754                                  unsigned long kernel_virt_addr,
755                                  unsigned long data_size,
756                                  unsigned long *num_pages_ptr,
757                                  struct sep_lli_entry_t **lli_array_ptr,
758                                  struct page ***page_array_ptr)
759 {
760         int error = 0;
761         /* the the page of the end address of the user space buffer */
762         unsigned long end_page;
763         /* the page of the start address of the user space buffer */
764         unsigned long start_page;
765         /* the range in pages */
766         unsigned long num_pages;
767         struct sep_lli_entry_t *lli_array;
768         /* next kernel address to map */
769         unsigned long next_kernel_address;
770         unsigned long count;
771
772         dbg("SEP Driver:--------> sep_lock_kernel_pages start\n");
773
774         /* set start and end pages  and num pages */
775         end_page = (kernel_virt_addr + data_size - 1) >> PAGE_SHIFT;
776         start_page = kernel_virt_addr >> PAGE_SHIFT;
777         num_pages = end_page - start_page + 1;
778
779         edbg("SEP Driver: kernel_virt_addr is %08lx\n", kernel_virt_addr);
780         edbg("SEP Driver: data_size is %lu\n", data_size);
781         edbg("SEP Driver: start_page is %lx\n", start_page);
782         edbg("SEP Driver: end_page is %lx\n", end_page);
783         edbg("SEP Driver: num_pages is %lu\n", num_pages);
784
785         lli_array = kmalloc(sizeof(struct sep_lli_entry_t) * num_pages, GFP_ATOMIC);
786         if (!lli_array) {
787                 edbg("SEP Driver: kmalloc for lli_array failed\n");
788                 error = -ENOMEM;
789                 goto end_function;
790         }
791
792         /* set the start address of the first page - app data may start not at
793            the beginning of the page */
794         lli_array[0].physical_address = (unsigned long) virt_to_phys((unsigned long *) kernel_virt_addr);
795
796         /* check that not all the data is in the first page only */
797         if ((PAGE_SIZE - (kernel_virt_addr & (~PAGE_MASK))) >= data_size)
798                 lli_array[0].block_size = data_size;
799         else
800                 lli_array[0].block_size = PAGE_SIZE - (kernel_virt_addr & (~PAGE_MASK));
801
802         /* debug print */
803         dbg("lli_array[0].physical_address is %08lx, lli_array[0].block_size is %lu\n", lli_array[0].physical_address, lli_array[0].block_size);
804
805         /* advance the address to the start of the next page */
806         next_kernel_address = (kernel_virt_addr & PAGE_MASK) + PAGE_SIZE;
807
808         /* go from the second page to the prev before last */
809         for (count = 1; count < (num_pages - 1); count++) {
810                 lli_array[count].physical_address = (unsigned long) virt_to_phys((unsigned long *) next_kernel_address);
811                 lli_array[count].block_size = PAGE_SIZE;
812
813                 edbg("lli_array[%lu].physical_address is %08lx, lli_array[%lu].block_size is %lu\n", count, lli_array[count].physical_address, count, lli_array[count].block_size);
814                 next_kernel_address += PAGE_SIZE;
815         }
816
817         /* if more then 1 pages locked - then update for the last page size needed */
818         if (num_pages > 1) {
819                 /* update the address of the last page */
820                 lli_array[count].physical_address = (unsigned long) virt_to_phys((unsigned long *) next_kernel_address);
821
822                 /* set the size of the last page */
823                 lli_array[count].block_size = (kernel_virt_addr + data_size) & (~PAGE_MASK);
824
825                 if (lli_array[count].block_size == 0) {
826                         dbg("app_virt_addr is %08lx\n", kernel_virt_addr);
827                         dbg("data_size is %lu\n", data_size);
828                         while (1);
829                 }
830
831                 edbg("lli_array[%lu].physical_address is %08lx, lli_array[%lu].block_size is %lu\n", count, lli_array[count].physical_address, count, lli_array[count].block_size);
832         }
833         /* set output params */
834         *lli_array_ptr = lli_array;
835         *num_pages_ptr = num_pages;
836         *page_array_ptr = 0;
837 end_function:
838         dbg("SEP Driver:<-------- sep_lock_kernel_pages end\n");
839         return 0;
840 }
841
842 /*
843   This function locks all the physical pages of the application virtual buffer
844   and construct a basic lli  array, where each entry holds the physical page
845   address and the size that application data holds in this physical pages
846 */
847 static int sep_lock_user_pages(struct sep_device *sep,
848                         unsigned long app_virt_addr,
849                         unsigned long data_size,
850                         unsigned long *num_pages_ptr,
851                         struct sep_lli_entry_t **lli_array_ptr,
852                         struct page ***page_array_ptr)
853 {
854         int error = 0;
855         /* the the page of the end address of the user space buffer */
856         unsigned long end_page;
857         /* the page of the start address of the user space buffer */
858         unsigned long start_page;
859         /* the range in pages */
860         unsigned long num_pages;
861         struct page **page_array;
862         struct sep_lli_entry_t *lli_array;
863         unsigned long count;
864         int result;
865
866         dbg("SEP Driver:--------> sep_lock_user_pages start\n");
867
868         /* set start and end pages  and num pages */
869         end_page = (app_virt_addr + data_size - 1) >> PAGE_SHIFT;
870         start_page = app_virt_addr >> PAGE_SHIFT;
871         num_pages = end_page - start_page + 1;
872
873         edbg("SEP Driver: app_virt_addr is %08lx\n", app_virt_addr);
874         edbg("SEP Driver: data_size is %lu\n", data_size);
875         edbg("SEP Driver: start_page is %lu\n", start_page);
876         edbg("SEP Driver: end_page is %lu\n", end_page);
877         edbg("SEP Driver: num_pages is %lu\n", num_pages);
878
879         /* allocate array of pages structure pointers */
880         page_array = kmalloc(sizeof(struct page *) * num_pages, GFP_ATOMIC);
881         if (!page_array) {
882                 edbg("SEP Driver: kmalloc for page_array failed\n");
883
884                 error = -ENOMEM;
885                 goto end_function;
886         }
887
888         lli_array = kmalloc(sizeof(struct sep_lli_entry_t) * num_pages, GFP_ATOMIC);
889         if (!lli_array) {
890                 edbg("SEP Driver: kmalloc for lli_array failed\n");
891
892                 error = -ENOMEM;
893                 goto end_function_with_error1;
894         }
895
896         /* convert the application virtual address into a set of physical */
897         down_read(&current->mm->mmap_sem);
898         result = get_user_pages(current, current->mm, app_virt_addr, num_pages, 1, 0, page_array, 0);
899         up_read(&current->mm->mmap_sem);
900
901         /* check the number of pages locked - if not all then exit with error */
902         if (result != num_pages) {
903                 dbg("SEP Driver: not all pages locked by get_user_pages\n");
904
905                 error = -ENOMEM;
906                 goto end_function_with_error2;
907         }
908
909         /* flush the cache */
910         for (count = 0; count < num_pages; count++)
911                 flush_dcache_page(page_array[count]);
912
913         /* set the start address of the first page - app data may start not at
914            the beginning of the page */
915         lli_array[0].physical_address = ((unsigned long) page_to_phys(page_array[0])) + (app_virt_addr & (~PAGE_MASK));
916
917         /* check that not all the data is in the first page only */
918         if ((PAGE_SIZE - (app_virt_addr & (~PAGE_MASK))) >= data_size)
919                 lli_array[0].block_size = data_size;
920         else
921                 lli_array[0].block_size = PAGE_SIZE - (app_virt_addr & (~PAGE_MASK));
922
923         /* debug print */
924         dbg("lli_array[0].physical_address is %08lx, lli_array[0].block_size is %lu\n", lli_array[0].physical_address, lli_array[0].block_size);
925
926         /* go from the second page to the prev before last */
927         for (count = 1; count < (num_pages - 1); count++) {
928                 lli_array[count].physical_address = (unsigned long) page_to_phys(page_array[count]);
929                 lli_array[count].block_size = PAGE_SIZE;
930
931                 edbg("lli_array[%lu].physical_address is %08lx, lli_array[%lu].block_size is %lu\n", count, lli_array[count].physical_address, count, lli_array[count].block_size);
932         }
933
934         /* if more then 1 pages locked - then update for the last page size needed */
935         if (num_pages > 1) {
936                 /* update the address of the last page */
937                 lli_array[count].physical_address = (unsigned long) page_to_phys(page_array[count]);
938
939                 /* set the size of the last page */
940                 lli_array[count].block_size = (app_virt_addr + data_size) & (~PAGE_MASK);
941
942                 if (lli_array[count].block_size == 0) {
943                         dbg("app_virt_addr is %08lx\n", app_virt_addr);
944                         dbg("data_size is %lu\n", data_size);
945                         while (1);
946                 }
947                 edbg("lli_array[%lu].physical_address is %08lx, lli_array[%lu].block_size is %lu\n",
948                      count, lli_array[count].physical_address,
949                      count, lli_array[count].block_size);
950         }
951
952         /* set output params */
953         *lli_array_ptr = lli_array;
954         *num_pages_ptr = num_pages;
955         *page_array_ptr = page_array;
956         goto end_function;
957
958 end_function_with_error2:
959         /* release the cache */
960         for (count = 0; count < num_pages; count++)
961                 page_cache_release(page_array[count]);
962         kfree(lli_array);
963 end_function_with_error1:
964         kfree(page_array);
965 end_function:
966         dbg("SEP Driver:<-------- sep_lock_user_pages end\n");
967         return 0;
968 }
969
970
971 /*
972   this function calculates the size of data that can be inserted into the lli
973   table from this array the condition is that either the table is full
974   (all etnries are entered), or there are no more entries in the lli array
975 */
976 static unsigned long sep_calculate_lli_table_max_size(struct sep_lli_entry_t *lli_in_array_ptr, unsigned long num_array_entries)
977 {
978         unsigned long table_data_size = 0;
979         unsigned long counter;
980
981         /* calculate the data in the out lli table if till we fill the whole
982            table or till the data has ended */
983         for (counter = 0; (counter < (SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP - 1)) && (counter < num_array_entries); counter++)
984                 table_data_size += lli_in_array_ptr[counter].block_size;
985         return table_data_size;
986 }
987
988 /*
989   this functions builds ont lli table from the lli_array according to
990   the given size of data
991 */
992 static void sep_build_lli_table(struct sep_lli_entry_t *lli_array_ptr, struct sep_lli_entry_t *lli_table_ptr, unsigned long *num_processed_entries_ptr, unsigned long *num_table_entries_ptr, unsigned long table_data_size)
993 {
994         unsigned long curr_table_data_size;
995         /* counter of lli array entry */
996         unsigned long array_counter;
997
998         dbg("SEP Driver:--------> sep_build_lli_table start\n");
999
1000         /* init currrent table data size and lli array entry counter */
1001         curr_table_data_size = 0;
1002         array_counter = 0;
1003         *num_table_entries_ptr = 1;
1004
1005         edbg("SEP Driver:table_data_size is %lu\n", table_data_size);
1006
1007         /* fill the table till table size reaches the needed amount */
1008         while (curr_table_data_size < table_data_size) {
1009                 /* update the number of entries in table */
1010                 (*num_table_entries_ptr)++;
1011
1012                 lli_table_ptr->physical_address = lli_array_ptr[array_counter].physical_address;
1013                 lli_table_ptr->block_size = lli_array_ptr[array_counter].block_size;
1014                 curr_table_data_size += lli_table_ptr->block_size;
1015
1016                 edbg("SEP Driver:lli_table_ptr is %08lx\n", (unsigned long) lli_table_ptr);
1017                 edbg("SEP Driver:lli_table_ptr->physical_address is %08lx\n", lli_table_ptr->physical_address);
1018                 edbg("SEP Driver:lli_table_ptr->block_size is %lu\n", lli_table_ptr->block_size);
1019
1020                 /* check for overflow of the table data */
1021                 if (curr_table_data_size > table_data_size) {
1022                         edbg("SEP Driver:curr_table_data_size > table_data_size\n");
1023
1024                         /* update the size of block in the table */
1025                         lli_table_ptr->block_size -= (curr_table_data_size - table_data_size);
1026
1027                         /* update the physical address in the lli array */
1028                         lli_array_ptr[array_counter].physical_address += lli_table_ptr->block_size;
1029
1030                         /* update the block size left in the lli array */
1031                         lli_array_ptr[array_counter].block_size = (curr_table_data_size - table_data_size);
1032                 } else
1033                         /* advance to the next entry in the lli_array */
1034                         array_counter++;
1035
1036                 edbg("SEP Driver:lli_table_ptr->physical_address is %08lx\n", lli_table_ptr->physical_address);
1037                 edbg("SEP Driver:lli_table_ptr->block_size is %lu\n", lli_table_ptr->block_size);
1038
1039                 /* move to the next entry in table */
1040                 lli_table_ptr++;
1041         }
1042
1043         /* set the info entry to default */
1044         lli_table_ptr->physical_address = 0xffffffff;
1045         lli_table_ptr->block_size = 0;
1046
1047         edbg("SEP Driver:lli_table_ptr is %08lx\n", (unsigned long) lli_table_ptr);
1048         edbg("SEP Driver:lli_table_ptr->physical_address is %08lx\n", lli_table_ptr->physical_address);
1049         edbg("SEP Driver:lli_table_ptr->block_size is %lu\n", lli_table_ptr->block_size);
1050
1051         /* set the output parameter */
1052         *num_processed_entries_ptr += array_counter;
1053
1054         edbg("SEP Driver:*num_processed_entries_ptr is %lu\n", *num_processed_entries_ptr);
1055         dbg("SEP Driver:<-------- sep_build_lli_table end\n");
1056         return;
1057 }
1058
1059 /*
1060   this function goes over the list of the print created tables and
1061   prints all the data
1062 */
1063 static void sep_debug_print_lli_tables(struct sep_device *sep, struct sep_lli_entry_t *lli_table_ptr, unsigned long num_table_entries, unsigned long table_data_size)
1064 {
1065         unsigned long table_count;
1066         unsigned long entries_count;
1067
1068         dbg("SEP Driver:--------> sep_debug_print_lli_tables start\n");
1069
1070         table_count = 1;
1071         while ((unsigned long) lli_table_ptr != 0xffffffff) {
1072                 edbg("SEP Driver: lli table %08lx, table_data_size is %lu\n", table_count, table_data_size);
1073                 edbg("SEP Driver: num_table_entries is %lu\n", num_table_entries);
1074
1075                 /* print entries of the table (without info entry) */
1076                 for (entries_count = 0; entries_count < num_table_entries; entries_count++, lli_table_ptr++) {
1077                         edbg("SEP Driver:lli_table_ptr address is %08lx\n", (unsigned long) lli_table_ptr);
1078                         edbg("SEP Driver:phys address is %08lx block size is %lu\n", lli_table_ptr->physical_address, lli_table_ptr->block_size);
1079                 }
1080
1081                 /* point to the info entry */
1082                 lli_table_ptr--;
1083
1084                 edbg("SEP Driver:phys lli_table_ptr->block_size is %lu\n", lli_table_ptr->block_size);
1085                 edbg("SEP Driver:phys lli_table_ptr->physical_address is %08lx\n", lli_table_ptr->physical_address);
1086
1087
1088                 table_data_size = lli_table_ptr->block_size & 0xffffff;
1089                 num_table_entries = (lli_table_ptr->block_size >> 24) & 0xff;
1090                 lli_table_ptr = (struct sep_lli_entry_t *)
1091                     (lli_table_ptr->physical_address);
1092
1093                 edbg("SEP Driver:phys table_data_size is %lu num_table_entries is %lu lli_table_ptr is%lu\n", table_data_size, num_table_entries, (unsigned long) lli_table_ptr);
1094
1095                 if ((unsigned long) lli_table_ptr != 0xffffffff)
1096                         lli_table_ptr = (struct sep_lli_entry_t *) sep_shared_bus_to_virt(sep, (unsigned long) lli_table_ptr);
1097
1098                 table_count++;
1099         }
1100         dbg("SEP Driver:<-------- sep_debug_print_lli_tables end\n");
1101 }
1102
1103
1104 /*
1105   This function prepares only input DMA table for synhronic symmetric
1106   operations (HASH)
1107 */
1108 static int sep_prepare_input_dma_table(struct sep_device *sep,
1109                                 unsigned long app_virt_addr,
1110                                 unsigned long data_size,
1111                                 unsigned long block_size,
1112                                 unsigned long *lli_table_ptr,
1113                                 unsigned long *num_entries_ptr,
1114                                 unsigned long *table_data_size_ptr,
1115                                 bool isKernelVirtualAddress)
1116 {
1117         /* pointer to the info entry of the table - the last entry */
1118         struct sep_lli_entry_t *info_entry_ptr;
1119         /* array of pointers ot page */
1120         struct sep_lli_entry_t *lli_array_ptr;
1121         /* points to the first entry to be processed in the lli_in_array */
1122         unsigned long current_entry;
1123         /* num entries in the virtual buffer */
1124         unsigned long sep_lli_entries;
1125         /* lli table pointer */
1126         struct sep_lli_entry_t *in_lli_table_ptr;
1127         /* the total data in one table */
1128         unsigned long table_data_size;
1129         /* number of entries in lli table */
1130         unsigned long num_entries_in_table;
1131         /* next table address */
1132         void *lli_table_alloc_addr;
1133         unsigned long result;
1134
1135         dbg("SEP Driver:--------> sep_prepare_input_dma_table start\n");
1136
1137         edbg("SEP Driver:data_size is %lu\n", data_size);
1138         edbg("SEP Driver:block_size is %lu\n", block_size);
1139
1140         /* initialize the pages pointers */
1141         sep->in_page_array = 0;
1142         sep->in_num_pages = 0;
1143
1144         if (data_size == 0) {
1145                 /* special case  - created 2 entries table with zero data */
1146                 in_lli_table_ptr = (struct sep_lli_entry_t *) (sep->shared_addr + SEP_DRIVER_SYNCHRONIC_DMA_TABLES_AREA_OFFSET_IN_BYTES);
1147                 /* FIXME: Should the entry below not be for _bus */
1148                 in_lli_table_ptr->physical_address = (unsigned long)sep->shared_addr + SEP_DRIVER_SYNCHRONIC_DMA_TABLES_AREA_OFFSET_IN_BYTES;
1149                 in_lli_table_ptr->block_size = 0;
1150
1151                 in_lli_table_ptr++;
1152                 in_lli_table_ptr->physical_address = 0xFFFFFFFF;
1153                 in_lli_table_ptr->block_size = 0;
1154
1155                 *lli_table_ptr = sep->shared_bus + SEP_DRIVER_SYNCHRONIC_DMA_TABLES_AREA_OFFSET_IN_BYTES;
1156                 *num_entries_ptr = 2;
1157                 *table_data_size_ptr = 0;
1158
1159                 goto end_function;
1160         }
1161
1162         /* check if the pages are in Kernel Virtual Address layout */
1163         if (isKernelVirtualAddress == true)
1164                 /* lock the pages of the kernel buffer and translate them to pages */
1165                 result = sep_lock_kernel_pages(sep, app_virt_addr, data_size, &sep->in_num_pages, &lli_array_ptr, &sep->in_page_array);
1166         else
1167                 /* lock the pages of the user buffer and translate them to pages */
1168                 result = sep_lock_user_pages(sep, app_virt_addr, data_size, &sep->in_num_pages, &lli_array_ptr, &sep->in_page_array);
1169
1170         if (result)
1171                 return result;
1172
1173         edbg("SEP Driver:output sep->in_num_pages is %lu\n", sep->in_num_pages);
1174
1175         current_entry = 0;
1176         info_entry_ptr = 0;
1177         sep_lli_entries = sep->in_num_pages;
1178
1179         /* initiate to point after the message area */
1180         lli_table_alloc_addr = sep->shared_addr + SEP_DRIVER_SYNCHRONIC_DMA_TABLES_AREA_OFFSET_IN_BYTES;
1181
1182         /* loop till all the entries in in array are not processed */
1183         while (current_entry < sep_lli_entries) {
1184                 /* set the new input and output tables */
1185                 in_lli_table_ptr = (struct sep_lli_entry_t *) lli_table_alloc_addr;
1186
1187                 lli_table_alloc_addr += sizeof(struct sep_lli_entry_t) * SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP;
1188
1189                 /* calculate the maximum size of data for input table */
1190                 table_data_size = sep_calculate_lli_table_max_size(&lli_array_ptr[current_entry], (sep_lli_entries - current_entry));
1191
1192                 /* now calculate the table size so that it will be module block size */
1193                 table_data_size = (table_data_size / block_size) * block_size;
1194
1195                 edbg("SEP Driver:output table_data_size is %lu\n", table_data_size);
1196
1197                 /* construct input lli table */
1198                 sep_build_lli_table(&lli_array_ptr[current_entry], in_lli_table_ptr, &current_entry, &num_entries_in_table, table_data_size);
1199
1200                 if (info_entry_ptr == 0) {
1201                         /* set the output parameters to physical addresses */
1202                         *lli_table_ptr = sep_shared_virt_to_bus(sep, in_lli_table_ptr);
1203                         *num_entries_ptr = num_entries_in_table;
1204                         *table_data_size_ptr = table_data_size;
1205
1206                         edbg("SEP Driver:output lli_table_in_ptr is %08lx\n", *lli_table_ptr);
1207                 } else {
1208                         /* update the info entry of the previous in table */
1209                         info_entry_ptr->physical_address = sep_shared_virt_to_bus(sep, in_lli_table_ptr);
1210                         info_entry_ptr->block_size = ((num_entries_in_table) << 24) | (table_data_size);
1211                 }
1212
1213                 /* save the pointer to the info entry of the current tables */
1214                 info_entry_ptr = in_lli_table_ptr + num_entries_in_table - 1;
1215         }
1216
1217         /* print input tables */
1218         sep_debug_print_lli_tables(sep, (struct sep_lli_entry_t *)
1219                                    sep_shared_bus_to_virt(sep, *lli_table_ptr), *num_entries_ptr, *table_data_size_ptr);
1220
1221         /* the array of the pages */
1222         kfree(lli_array_ptr);
1223 end_function:
1224         dbg("SEP Driver:<-------- sep_prepare_input_dma_table end\n");
1225         return 0;
1226
1227 }
1228
1229 /*
1230  This function creates the input and output dma tables for
1231  symmetric operations (AES/DES) according to the block size from LLI arays
1232 */
1233 static int sep_construct_dma_tables_from_lli(struct sep_device *sep,
1234                                       struct sep_lli_entry_t *lli_in_array,
1235                                       unsigned long sep_in_lli_entries,
1236                                       struct sep_lli_entry_t *lli_out_array,
1237                                       unsigned long sep_out_lli_entries,
1238                                       unsigned long block_size, unsigned long *lli_table_in_ptr, unsigned long *lli_table_out_ptr, unsigned long *in_num_entries_ptr, unsigned long *out_num_entries_ptr, unsigned long *table_data_size_ptr)
1239 {
1240         /* points to the area where next lli table can be allocated: keep void *
1241            as there is pointer scaling to fix otherwise */
1242         void *lli_table_alloc_addr;
1243         /* input lli table */
1244         struct sep_lli_entry_t *in_lli_table_ptr;
1245         /* output lli table */
1246         struct sep_lli_entry_t *out_lli_table_ptr;
1247         /* pointer to the info entry of the table - the last entry */
1248         struct sep_lli_entry_t *info_in_entry_ptr;
1249         /* pointer to the info entry of the table - the last entry */
1250         struct sep_lli_entry_t *info_out_entry_ptr;
1251         /* points to the first entry to be processed in the lli_in_array */
1252         unsigned long current_in_entry;
1253         /* points to the first entry to be processed in the lli_out_array */
1254         unsigned long current_out_entry;
1255         /* max size of the input table */
1256         unsigned long in_table_data_size;
1257         /* max size of the output table */
1258         unsigned long out_table_data_size;
1259         /* flag te signifies if this is the first tables build from the arrays */
1260         unsigned long first_table_flag;
1261         /* the data size that should be in table */
1262         unsigned long table_data_size;
1263         /* number of etnries in the input table */
1264         unsigned long num_entries_in_table;
1265         /* number of etnries in the output table */
1266         unsigned long num_entries_out_table;
1267
1268         dbg("SEP Driver:--------> sep_construct_dma_tables_from_lli start\n");
1269
1270         /* initiate to pint after the message area */
1271         lli_table_alloc_addr = sep->shared_addr + SEP_DRIVER_SYNCHRONIC_DMA_TABLES_AREA_OFFSET_IN_BYTES;
1272
1273         current_in_entry = 0;
1274         current_out_entry = 0;
1275         first_table_flag = 1;
1276         info_in_entry_ptr = 0;
1277         info_out_entry_ptr = 0;
1278
1279         /* loop till all the entries in in array are not processed */
1280         while (current_in_entry < sep_in_lli_entries) {
1281                 /* set the new input and output tables */
1282                 in_lli_table_ptr = (struct sep_lli_entry_t *) lli_table_alloc_addr;
1283
1284                 lli_table_alloc_addr += sizeof(struct sep_lli_entry_t) * SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP;
1285
1286                 /* set the first output tables */
1287                 out_lli_table_ptr = (struct sep_lli_entry_t *) lli_table_alloc_addr;
1288
1289                 lli_table_alloc_addr += sizeof(struct sep_lli_entry_t) * SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP;
1290
1291                 /* calculate the maximum size of data for input table */
1292                 in_table_data_size = sep_calculate_lli_table_max_size(&lli_in_array[current_in_entry], (sep_in_lli_entries - current_in_entry));
1293
1294                 /* calculate the maximum size of data for output table */
1295                 out_table_data_size = sep_calculate_lli_table_max_size(&lli_out_array[current_out_entry], (sep_out_lli_entries - current_out_entry));
1296
1297                 edbg("SEP Driver:in_table_data_size is %lu\n", in_table_data_size);
1298                 edbg("SEP Driver:out_table_data_size is %lu\n", out_table_data_size);
1299
1300                 /* check where the data is smallest */
1301                 table_data_size = in_table_data_size;
1302                 if (table_data_size > out_table_data_size)
1303                         table_data_size = out_table_data_size;
1304
1305                 /* now calculate the table size so that it will be module block size */
1306                 table_data_size = (table_data_size / block_size) * block_size;
1307
1308                 dbg("SEP Driver:table_data_size is %lu\n", table_data_size);
1309
1310                 /* construct input lli table */
1311                 sep_build_lli_table(&lli_in_array[current_in_entry], in_lli_table_ptr, &current_in_entry, &num_entries_in_table, table_data_size);
1312
1313                 /* construct output lli table */
1314                 sep_build_lli_table(&lli_out_array[current_out_entry], out_lli_table_ptr, &current_out_entry, &num_entries_out_table, table_data_size);
1315
1316                 /* if info entry is null - this is the first table built */
1317                 if (info_in_entry_ptr == 0) {
1318                         /* set the output parameters to physical addresses */
1319                         *lli_table_in_ptr = sep_shared_virt_to_bus(sep, in_lli_table_ptr);
1320                         *in_num_entries_ptr = num_entries_in_table;
1321                         *lli_table_out_ptr = sep_shared_virt_to_bus(sep, out_lli_table_ptr);
1322                         *out_num_entries_ptr = num_entries_out_table;
1323                         *table_data_size_ptr = table_data_size;
1324
1325                         edbg("SEP Driver:output lli_table_in_ptr is %08lx\n", *lli_table_in_ptr);
1326                         edbg("SEP Driver:output lli_table_out_ptr is %08lx\n", *lli_table_out_ptr);
1327                 } else {
1328                         /* update the info entry of the previous in table */
1329                         info_in_entry_ptr->physical_address = sep_shared_virt_to_bus(sep, in_lli_table_ptr);
1330                         info_in_entry_ptr->block_size = ((num_entries_in_table) << 24) | (table_data_size);
1331
1332                         /* update the info entry of the previous in table */
1333                         info_out_entry_ptr->physical_address = sep_shared_virt_to_bus(sep, out_lli_table_ptr);
1334                         info_out_entry_ptr->block_size = ((num_entries_out_table) << 24) | (table_data_size);
1335                 }
1336
1337                 /* save the pointer to the info entry of the current tables */
1338                 info_in_entry_ptr = in_lli_table_ptr + num_entries_in_table - 1;
1339                 info_out_entry_ptr = out_lli_table_ptr + num_entries_out_table - 1;
1340
1341                 edbg("SEP Driver:output num_entries_out_table is %lu\n", (unsigned long) num_entries_out_table);
1342                 edbg("SEP Driver:output info_in_entry_ptr is %lu\n", (unsigned long) info_in_entry_ptr);
1343                 edbg("SEP Driver:output info_out_entry_ptr is %lu\n", (unsigned long) info_out_entry_ptr);
1344         }
1345
1346         /* print input tables */
1347         sep_debug_print_lli_tables(sep, (struct sep_lli_entry_t *)
1348                                    sep_shared_bus_to_virt(sep, *lli_table_in_ptr), *in_num_entries_ptr, *table_data_size_ptr);
1349         /* print output tables */
1350         sep_debug_print_lli_tables(sep, (struct sep_lli_entry_t *)
1351                                    sep_shared_bus_to_virt(sep, *lli_table_out_ptr), *out_num_entries_ptr, *table_data_size_ptr);
1352         dbg("SEP Driver:<-------- sep_construct_dma_tables_from_lli end\n");
1353         return 0;
1354 }
1355
1356
1357 /*
1358   This function builds input and output DMA tables for synhronic
1359   symmetric operations (AES, DES). It also checks that each table
1360   is of the modular block size
1361 */
1362 static int sep_prepare_input_output_dma_table(struct sep_device *sep,
1363                                        unsigned long app_virt_in_addr,
1364                                        unsigned long app_virt_out_addr,
1365                                        unsigned long data_size,
1366                                        unsigned long block_size,
1367                                        unsigned long *lli_table_in_ptr, unsigned long *lli_table_out_ptr, unsigned long *in_num_entries_ptr, unsigned long *out_num_entries_ptr, unsigned long *table_data_size_ptr, bool isKernelVirtualAddress)
1368 {
1369         /* array of pointers of page */
1370         struct sep_lli_entry_t *lli_in_array;
1371         /* array of pointers of page */
1372         struct sep_lli_entry_t *lli_out_array;
1373         int result = 0;
1374
1375         dbg("SEP Driver:--------> sep_prepare_input_output_dma_table start\n");
1376
1377         /* initialize the pages pointers */
1378         sep->in_page_array = 0;
1379         sep->out_page_array = 0;
1380
1381         /* check if the pages are in Kernel Virtual Address layout */
1382         if (isKernelVirtualAddress == true) {
1383                 /* lock the pages of the kernel buffer and translate them to pages */
1384                 result = sep_lock_kernel_pages(sep, app_virt_in_addr, data_size, &sep->in_num_pages, &lli_in_array, &sep->in_page_array);
1385                 if (result) {
1386                         edbg("SEP Driver: sep_lock_kernel_pages for input virtual buffer failed\n");
1387                         goto end_function;
1388                 }
1389         } else {
1390                 /* lock the pages of the user buffer and translate them to pages */
1391                 result = sep_lock_user_pages(sep, app_virt_in_addr, data_size, &sep->in_num_pages, &lli_in_array, &sep->in_page_array);
1392                 if (result) {
1393                         edbg("SEP Driver: sep_lock_user_pages for input virtual buffer failed\n");
1394                         goto end_function;
1395                 }
1396         }
1397
1398         if (isKernelVirtualAddress == true) {
1399                 result = sep_lock_kernel_pages(sep, app_virt_out_addr, data_size, &sep->out_num_pages, &lli_out_array, &sep->out_page_array);
1400                 if (result) {
1401                         edbg("SEP Driver: sep_lock_kernel_pages for output virtual buffer failed\n");
1402                         goto end_function_with_error1;
1403                 }
1404         } else {
1405                 result = sep_lock_user_pages(sep, app_virt_out_addr, data_size, &sep->out_num_pages, &lli_out_array, &sep->out_page_array);
1406                 if (result) {
1407                         edbg("SEP Driver: sep_lock_user_pages for output virtual buffer failed\n");
1408                         goto end_function_with_error1;
1409                 }
1410         }
1411         edbg("sep->in_num_pages is %lu\n", sep->in_num_pages);
1412         edbg("sep->out_num_pages is %lu\n", sep->out_num_pages);
1413         edbg("SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP is %x\n", SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP);
1414
1415
1416         /* call the fucntion that creates table from the lli arrays */
1417         result = sep_construct_dma_tables_from_lli(sep, lli_in_array, sep->in_num_pages, lli_out_array, sep->out_num_pages, block_size, lli_table_in_ptr, lli_table_out_ptr, in_num_entries_ptr, out_num_entries_ptr, table_data_size_ptr);
1418         if (result) {
1419                 edbg("SEP Driver: sep_construct_dma_tables_from_lli failed\n");
1420                 goto end_function_with_error2;
1421         }
1422
1423         /* fall through - free the lli entry arrays */
1424         dbg("in_num_entries_ptr is %08lx\n", *in_num_entries_ptr);
1425         dbg("out_num_entries_ptr is %08lx\n", *out_num_entries_ptr);
1426         dbg("table_data_size_ptr is %08lx\n", *table_data_size_ptr);
1427 end_function_with_error2:
1428         kfree(lli_out_array);
1429 end_function_with_error1:
1430         kfree(lli_in_array);
1431 end_function:
1432         dbg("SEP Driver:<-------- sep_prepare_input_output_dma_table end result = %d\n", (int) result);
1433         return result;
1434
1435 }
1436
1437 /*
1438   this function handles tha request for creation of the DMA table
1439   for the synchronic symmetric operations (AES,DES)
1440 */
1441 static int sep_create_sync_dma_tables_handler(struct sep_device *sep,
1442                                                 unsigned long arg)
1443 {
1444         int error;
1445         /* command arguments */
1446         struct sep_driver_build_sync_table_t command_args;
1447
1448         dbg("SEP Driver:--------> sep_create_sync_dma_tables_handler start\n");
1449
1450         error = copy_from_user(&command_args, (void *) arg, sizeof(struct sep_driver_build_sync_table_t));
1451         if (error)
1452                 goto end_function;
1453
1454         edbg("app_in_address is %08lx\n", command_args.app_in_address);
1455         edbg("app_out_address is %08lx\n", command_args.app_out_address);
1456         edbg("data_size is %lu\n", command_args.data_in_size);
1457         edbg("block_size is %lu\n", command_args.block_size);
1458
1459         /* check if we need to build only input table or input/output */
1460         if (command_args.app_out_address)
1461                 /* prepare input and output tables */
1462                 error = sep_prepare_input_output_dma_table(sep,
1463                                                            command_args.app_in_address,
1464                                                            command_args.app_out_address,
1465                                                            command_args.data_in_size,
1466                                                            command_args.block_size,
1467                                                            &command_args.in_table_address,
1468                                                            &command_args.out_table_address, &command_args.in_table_num_entries, &command_args.out_table_num_entries, &command_args.table_data_size, command_args.isKernelVirtualAddress);
1469         else
1470                 /* prepare input tables */
1471                 error = sep_prepare_input_dma_table(sep,
1472                                                     command_args.app_in_address,
1473                                                     command_args.data_in_size, command_args.block_size, &command_args.in_table_address, &command_args.in_table_num_entries, &command_args.table_data_size, command_args.isKernelVirtualAddress);
1474
1475         if (error)
1476                 goto end_function;
1477         /* copy to user */
1478         if (copy_to_user((void *) arg, (void *) &command_args, sizeof(struct sep_driver_build_sync_table_t)))
1479                 error = -EFAULT;
1480 end_function:
1481         dbg("SEP Driver:<-------- sep_create_sync_dma_tables_handler end\n");
1482         return error;
1483 }
1484
1485 /*
1486   this function handles the request for freeing dma table for synhronic actions
1487 */
1488 static int sep_free_dma_table_data_handler(struct sep_device *sep)
1489 {
1490         dbg("SEP Driver:--------> sep_free_dma_table_data_handler start\n");
1491
1492         /* free input pages array */
1493         sep_free_dma_pages(sep->in_page_array, sep->in_num_pages, 0);
1494
1495         /* free output pages array if needed */
1496         if (sep->out_page_array)
1497                 sep_free_dma_pages(sep->out_page_array, sep->out_num_pages, 1);
1498
1499         /* reset all the values */
1500         sep->in_page_array = 0;
1501         sep->out_page_array = 0;
1502         sep->in_num_pages = 0;
1503         sep->out_num_pages = 0;
1504         dbg("SEP Driver:<-------- sep_free_dma_table_data_handler end\n");
1505         return 0;
1506 }
1507
1508 /*
1509   this function find a space for the new flow dma table
1510 */
1511 static int sep_find_free_flow_dma_table_space(struct sep_device *sep,
1512                                         unsigned long **table_address_ptr)
1513 {
1514         int error = 0;
1515         /* pointer to the id field of the flow dma table */
1516         unsigned long *start_table_ptr;
1517         /* Do not make start_addr unsigned long * unless fixing the offset
1518            computations ! */
1519         void *flow_dma_area_start_addr;
1520         unsigned long *flow_dma_area_end_addr;
1521         /* maximum table size in words */
1522         unsigned long table_size_in_words;
1523
1524         /* find the start address of the flow DMA table area */
1525         flow_dma_area_start_addr = sep->shared_addr + SEP_DRIVER_FLOW_DMA_TABLES_AREA_OFFSET_IN_BYTES;
1526
1527         /* set end address of the flow table area */
1528         flow_dma_area_end_addr = flow_dma_area_start_addr + SEP_DRIVER_FLOW_DMA_TABLES_AREA_SIZE_IN_BYTES;
1529
1530         /* set table size in words */
1531         table_size_in_words = SEP_DRIVER_MAX_FLOW_NUM_ENTRIES_IN_TABLE * (sizeof(struct sep_lli_entry_t) / sizeof(long)) + 2;
1532
1533         /* set the pointer to the start address of DMA area */
1534         start_table_ptr = flow_dma_area_start_addr;
1535
1536         /* find the space for the next table */
1537         while (((*start_table_ptr & 0x7FFFFFFF) != 0) && start_table_ptr < flow_dma_area_end_addr)
1538                 start_table_ptr += table_size_in_words;
1539
1540         /* check if we reached the end of floa tables area */
1541         if (start_table_ptr >= flow_dma_area_end_addr)
1542                 error = -1;
1543         else
1544                 *table_address_ptr = start_table_ptr;
1545
1546         return error;
1547 }
1548
1549 /*
1550   This function creates one DMA table for flow and returns its data,
1551   and pointer to its info entry
1552 */
1553 static int sep_prepare_one_flow_dma_table(struct sep_device *sep,
1554                                         unsigned long virt_buff_addr,
1555                                         unsigned long virt_buff_size,
1556                                         struct sep_lli_entry_t *table_data,
1557                                         struct sep_lli_entry_t **info_entry_ptr,
1558                                         struct sep_flow_context_t *flow_data_ptr,
1559                                         bool isKernelVirtualAddress)
1560 {
1561         int error;
1562         /* the range in pages */
1563         unsigned long lli_array_size;
1564         struct sep_lli_entry_t *lli_array;
1565         struct sep_lli_entry_t *flow_dma_table_entry_ptr;
1566         unsigned long *start_dma_table_ptr;
1567         /* total table data counter */
1568         unsigned long dma_table_data_count;
1569         /* pointer that will keep the pointer to the pages of the virtual buffer */
1570         struct page **page_array_ptr;
1571         unsigned long entry_count;
1572
1573         /* find the space for the new table */
1574         error = sep_find_free_flow_dma_table_space(sep, &start_dma_table_ptr);
1575         if (error)
1576                 goto end_function;
1577
1578         /* check if the pages are in Kernel Virtual Address layout */
1579         if (isKernelVirtualAddress == true)
1580                 /* lock kernel buffer in the memory */
1581                 error = sep_lock_kernel_pages(sep, virt_buff_addr, virt_buff_size, &lli_array_size, &lli_array, &page_array_ptr);
1582         else
1583                 /* lock user buffer in the memory */
1584                 error = sep_lock_user_pages(sep, virt_buff_addr, virt_buff_size, &lli_array_size, &lli_array, &page_array_ptr);
1585
1586         if (error)
1587                 goto end_function;
1588
1589         /* set the pointer to page array at the beginning of table - this table is
1590            now considered taken */
1591         *start_dma_table_ptr = lli_array_size;
1592
1593         /* point to the place of the pages pointers of the table */
1594         start_dma_table_ptr++;
1595
1596         /* set the pages pointer */
1597         *start_dma_table_ptr = (unsigned long) page_array_ptr;
1598
1599         /* set the pointer to the first entry */
1600         flow_dma_table_entry_ptr = (struct sep_lli_entry_t *) (++start_dma_table_ptr);
1601
1602         /* now create the entries for table */
1603         for (dma_table_data_count = entry_count = 0; entry_count < lli_array_size; entry_count++) {
1604                 flow_dma_table_entry_ptr->physical_address = lli_array[entry_count].physical_address;
1605
1606                 flow_dma_table_entry_ptr->block_size = lli_array[entry_count].block_size;
1607
1608                 /* set the total data of a table */
1609                 dma_table_data_count += lli_array[entry_count].block_size;
1610
1611                 flow_dma_table_entry_ptr++;
1612         }
1613
1614         /* set the physical address */
1615         table_data->physical_address = virt_to_phys(start_dma_table_ptr);
1616
1617         /* set the num_entries and total data size */
1618         table_data->block_size = ((lli_array_size + 1) << SEP_NUM_ENTRIES_OFFSET_IN_BITS) | (dma_table_data_count);
1619
1620         /* set the info entry */
1621         flow_dma_table_entry_ptr->physical_address = 0xffffffff;
1622         flow_dma_table_entry_ptr->block_size = 0;
1623
1624         /* set the pointer to info entry */
1625         *info_entry_ptr = flow_dma_table_entry_ptr;
1626
1627         /* the array of the lli entries */
1628         kfree(lli_array);
1629 end_function:
1630         return error;
1631 }
1632
1633
1634
1635 /*
1636   This function creates a list of tables for flow and returns the data for
1637         the first and last tables of the list
1638 */
1639 static int sep_prepare_flow_dma_tables(struct sep_device *sep,
1640                                         unsigned long num_virtual_buffers,
1641                                         unsigned long first_buff_addr, struct sep_flow_context_t *flow_data_ptr, struct sep_lli_entry_t *first_table_data_ptr, struct sep_lli_entry_t *last_table_data_ptr, bool isKernelVirtualAddress)
1642 {
1643         int error;
1644         unsigned long virt_buff_addr;
1645         unsigned long virt_buff_size;
1646         struct sep_lli_entry_t table_data;
1647         struct sep_lli_entry_t *info_entry_ptr;
1648         struct sep_lli_entry_t *prev_info_entry_ptr;
1649         unsigned long i;
1650
1651         /* init vars */
1652         error = 0;
1653         prev_info_entry_ptr = 0;
1654
1655         /* init the first table to default */
1656         table_data.physical_address = 0xffffffff;
1657         first_table_data_ptr->physical_address = 0xffffffff;
1658         table_data.block_size = 0;
1659
1660         for (i = 0; i < num_virtual_buffers; i++) {
1661                 /* get the virtual buffer address */
1662                 error = get_user(virt_buff_addr, &first_buff_addr);
1663                 if (error)
1664                         goto end_function;
1665
1666                 /* get the virtual buffer size */
1667                 first_buff_addr++;
1668                 error = get_user(virt_buff_size, &first_buff_addr);
1669                 if (error)
1670                         goto end_function;
1671
1672                 /* advance the address to point to the next pair of address|size */
1673                 first_buff_addr++;
1674
1675                 /* now prepare the one flow LLI table from the data */
1676                 error = sep_prepare_one_flow_dma_table(sep, virt_buff_addr, virt_buff_size, &table_data, &info_entry_ptr, flow_data_ptr, isKernelVirtualAddress);
1677                 if (error)
1678                         goto end_function;
1679
1680                 if (i == 0) {
1681                         /* if this is the first table - save it to return to the user
1682                            application */
1683                         *first_table_data_ptr = table_data;
1684
1685                         /* set the pointer to info entry */
1686                         prev_info_entry_ptr = info_entry_ptr;
1687                 } else {
1688                         /* not first table - the previous table info entry should
1689                            be updated */
1690                         prev_info_entry_ptr->block_size = (0x1 << SEP_INT_FLAG_OFFSET_IN_BITS) | (table_data.block_size);
1691
1692                         /* set the pointer to info entry */
1693                         prev_info_entry_ptr = info_entry_ptr;
1694                 }
1695         }
1696
1697         /* set the last table data */
1698         *last_table_data_ptr = table_data;
1699 end_function:
1700         return error;
1701 }
1702
1703 /*
1704   this function goes over all the flow tables connected to the given
1705         table and deallocate them
1706 */
1707 static void sep_deallocated_flow_tables(struct sep_lli_entry_t *first_table_ptr)
1708 {
1709         /* id pointer */
1710         unsigned long *table_ptr;
1711         /* end address of the flow dma area */
1712         unsigned long num_entries;
1713         unsigned long num_pages;
1714         struct page **pages_ptr;
1715         /* maximum table size in words */
1716         struct sep_lli_entry_t *info_entry_ptr;
1717
1718         /* set the pointer to the first table */
1719         table_ptr = (unsigned long *) first_table_ptr->physical_address;
1720
1721         /* set the num of entries */
1722         num_entries = (first_table_ptr->block_size >> SEP_NUM_ENTRIES_OFFSET_IN_BITS)
1723             & SEP_NUM_ENTRIES_MASK;
1724
1725         /* go over all the connected tables */
1726         while (*table_ptr != 0xffffffff) {
1727                 /* get number of pages */
1728                 num_pages = *(table_ptr - 2);
1729
1730                 /* get the pointer to the pages */
1731                 pages_ptr = (struct page **) (*(table_ptr - 1));
1732
1733                 /* free the pages */
1734                 sep_free_dma_pages(pages_ptr, num_pages, 1);
1735
1736                 /* goto to the info entry */
1737                 info_entry_ptr = ((struct sep_lli_entry_t *) table_ptr) + (num_entries - 1);
1738
1739                 table_ptr = (unsigned long *) info_entry_ptr->physical_address;
1740                 num_entries = (info_entry_ptr->block_size >> SEP_NUM_ENTRIES_OFFSET_IN_BITS) & SEP_NUM_ENTRIES_MASK;
1741         }
1742
1743         return;
1744 }
1745
1746 /**
1747  *      sep_find_flow_context   -       find a flow
1748  *      @sep: the SEP we are working with
1749  *      @flow_id: flow identifier
1750  *
1751  *      Returns a pointer the matching flow, or NULL if the flow does not
1752  *      exist.
1753  */
1754
1755 static struct sep_flow_context_t *sep_find_flow_context(struct sep_device *sep,
1756                                 unsigned long flow_id)
1757 {
1758         int count;
1759         /*
1760          *  always search for flow with id default first - in case we
1761          *  already started working on the flow there can be no situation
1762          *  when 2 flows are with default flag
1763          */
1764         for (count = 0; count < SEP_DRIVER_NUM_FLOWS; count++) {
1765                 if (sep->flows[count].flow_id == flow_id)
1766                         return &sep->flows[count];
1767         }
1768         return NULL;
1769 }
1770
1771
1772 /*
1773   this function handles the request to create the DMA tables for flow
1774 */
1775 static int sep_create_flow_dma_tables_handler(struct sep_device *sep,
1776                                                         unsigned long arg)
1777 {
1778         int error = -ENOENT;
1779         struct sep_driver_build_flow_table_t command_args;
1780         /* first table - output */
1781         struct sep_lli_entry_t first_table_data;
1782         /* dma table data */
1783         struct sep_lli_entry_t last_table_data;
1784         /* pointer to the info entry of the previuos DMA table */
1785         struct sep_lli_entry_t *prev_info_entry_ptr;
1786         /* pointer to the flow data strucutre */
1787         struct sep_flow_context_t *flow_context_ptr;
1788
1789         dbg("SEP Driver:--------> sep_create_flow_dma_tables_handler start\n");
1790
1791         /* init variables */
1792         prev_info_entry_ptr = 0;
1793         first_table_data.physical_address = 0xffffffff;
1794
1795         /* find the free structure for flow data */
1796         error = -EINVAL;
1797         flow_context_ptr = sep_find_flow_context(sep, SEP_FREE_FLOW_ID);
1798         if (flow_context_ptr == NULL)
1799                 goto end_function;
1800
1801         error = copy_from_user(&command_args, (void *) arg, sizeof(struct sep_driver_build_flow_table_t));
1802         if (error)
1803                 goto end_function;
1804
1805         /* create flow tables */
1806         error = sep_prepare_flow_dma_tables(sep, command_args.num_virtual_buffers, command_args.virt_buff_data_addr, flow_context_ptr, &first_table_data, &last_table_data, command_args.isKernelVirtualAddress);
1807         if (error)
1808                 goto end_function_with_error;
1809
1810         /* check if flow is static */
1811         if (!command_args.flow_type)
1812                 /* point the info entry of the last to the info entry of the first */
1813                 last_table_data = first_table_data;
1814
1815         /* set output params */
1816         command_args.first_table_addr = first_table_data.physical_address;
1817         command_args.first_table_num_entries = ((first_table_data.block_size >> SEP_NUM_ENTRIES_OFFSET_IN_BITS) & SEP_NUM_ENTRIES_MASK);
1818         command_args.first_table_data_size = (first_table_data.block_size & SEP_TABLE_DATA_SIZE_MASK);
1819
1820         /* send the parameters to user application */
1821         error = copy_to_user((void *) arg, &command_args, sizeof(struct sep_driver_build_flow_table_t));
1822         if (error)
1823                 goto end_function_with_error;
1824
1825         /* all the flow created  - update the flow entry with temp id */
1826         flow_context_ptr->flow_id = SEP_TEMP_FLOW_ID;
1827
1828         /* set the processing tables data in the context */
1829         if (command_args.input_output_flag == SEP_DRIVER_IN_FLAG)
1830                 flow_context_ptr->input_tables_in_process = first_table_data;
1831         else
1832                 flow_context_ptr->output_tables_in_process = first_table_data;
1833
1834         goto end_function;
1835
1836 end_function_with_error:
1837         /* free the allocated tables */
1838         sep_deallocated_flow_tables(&first_table_data);
1839 end_function:
1840         dbg("SEP Driver:<-------- sep_create_flow_dma_tables_handler end\n");
1841         return error;
1842 }
1843
1844 /*
1845   this function handles add tables to flow
1846 */
1847 static int sep_add_flow_tables_handler(struct sep_device *sep, unsigned long arg)
1848 {
1849         int error;
1850         unsigned long num_entries;
1851         struct sep_driver_add_flow_table_t command_args;
1852         struct sep_flow_context_t *flow_context_ptr;
1853         /* first dma table data */
1854         struct sep_lli_entry_t first_table_data;
1855         /* last dma table data */
1856         struct sep_lli_entry_t last_table_data;
1857         /* pointer to the info entry of the current DMA table */
1858         struct sep_lli_entry_t *info_entry_ptr;
1859
1860         dbg("SEP Driver:--------> sep_add_flow_tables_handler start\n");
1861
1862         /* get input parameters */
1863         error = copy_from_user(&command_args, (void *) arg, sizeof(struct sep_driver_add_flow_table_t));
1864         if (error)
1865                 goto end_function;
1866
1867         /* find the flow structure for the flow id */
1868         flow_context_ptr = sep_find_flow_context(sep, command_args.flow_id);
1869         if (flow_context_ptr == NULL)
1870                 goto end_function;
1871
1872         /* prepare the flow dma tables */
1873         error = sep_prepare_flow_dma_tables(sep, command_args.num_virtual_buffers, command_args.virt_buff_data_addr, flow_context_ptr, &first_table_data, &last_table_data, command_args.isKernelVirtualAddress);
1874         if (error)
1875                 goto end_function_with_error;
1876
1877         /* now check if there is already an existing add table for this flow */
1878         if (command_args.inputOutputFlag == SEP_DRIVER_IN_FLAG) {
1879                 /* this buffer was for input buffers */
1880                 if (flow_context_ptr->input_tables_flag) {
1881                         /* add table already exists - add the new tables to the end
1882                            of the previous */
1883                         num_entries = (flow_context_ptr->last_input_table.block_size >> SEP_NUM_ENTRIES_OFFSET_IN_BITS) & SEP_NUM_ENTRIES_MASK;
1884
1885                         info_entry_ptr = (struct sep_lli_entry_t *)
1886                             (flow_context_ptr->last_input_table.physical_address + (sizeof(struct sep_lli_entry_t) * (num_entries - 1)));
1887
1888                         /* connect to list of tables */
1889                         *info_entry_ptr = first_table_data;
1890
1891                         /* set the first table data */
1892                         first_table_data = flow_context_ptr->first_input_table;
1893                 } else {
1894                         /* set the input flag */
1895                         flow_context_ptr->input_tables_flag = 1;
1896
1897                         /* set the first table data */
1898                         flow_context_ptr->first_input_table = first_table_data;
1899                 }
1900                 /* set the last table data */
1901                 flow_context_ptr->last_input_table = last_table_data;
1902         } else {                /* this is output tables */
1903
1904                 /* this buffer was for input buffers */
1905                 if (flow_context_ptr->output_tables_flag) {
1906                         /* add table already exists - add the new tables to
1907                            the end of the previous */
1908                         num_entries = (flow_context_ptr->last_output_table.block_size >> SEP_NUM_ENTRIES_OFFSET_IN_BITS) & SEP_NUM_ENTRIES_MASK;
1909
1910                         info_entry_ptr = (struct sep_lli_entry_t *)
1911                             (flow_context_ptr->last_output_table.physical_address + (sizeof(struct sep_lli_entry_t) * (num_entries - 1)));
1912
1913                         /* connect to list of tables */
1914                         *info_entry_ptr = first_table_data;
1915
1916                         /* set the first table data */
1917                         first_table_data = flow_context_ptr->first_output_table;
1918                 } else {
1919                         /* set the input flag */
1920                         flow_context_ptr->output_tables_flag = 1;
1921
1922                         /* set the first table data */
1923                         flow_context_ptr->first_output_table = first_table_data;
1924                 }
1925                 /* set the last table data */
1926                 flow_context_ptr->last_output_table = last_table_data;
1927         }
1928
1929         /* set output params */
1930         command_args.first_table_addr = first_table_data.physical_address;
1931         command_args.first_table_num_entries = ((first_table_data.block_size >> SEP_NUM_ENTRIES_OFFSET_IN_BITS) & SEP_NUM_ENTRIES_MASK);
1932         command_args.first_table_data_size = (first_table_data.block_size & SEP_TABLE_DATA_SIZE_MASK);
1933
1934         /* send the parameters to user application */
1935         error = copy_to_user((void *) arg, &command_args, sizeof(struct sep_driver_add_flow_table_t));
1936 end_function_with_error:
1937         /* free the allocated tables */
1938         sep_deallocated_flow_tables(&first_table_data);
1939 end_function:
1940         dbg("SEP Driver:<-------- sep_add_flow_tables_handler end\n");
1941         return error;
1942 }
1943
1944 /*
1945   this function add the flow add message to the specific flow
1946 */
1947 static int sep_add_flow_tables_message_handler(struct sep_device *sep, unsigned long arg)
1948 {
1949         int error;
1950         struct sep_driver_add_message_t command_args;
1951         struct sep_flow_context_t *flow_context_ptr;
1952
1953         dbg("SEP Driver:--------> sep_add_flow_tables_message_handler start\n");
1954
1955         error = copy_from_user(&command_args, (void *) arg, sizeof(struct sep_driver_add_message_t));
1956         if (error)
1957                 goto end_function;
1958
1959         /* check input */
1960         if (command_args.message_size_in_bytes > SEP_MAX_ADD_MESSAGE_LENGTH_IN_BYTES) {
1961                 error = -ENOMEM;
1962                 goto end_function;
1963         }
1964
1965         /* find the flow context */
1966         flow_context_ptr = sep_find_flow_context(sep, command_args.flow_id);
1967         if (flow_context_ptr == NULL)
1968                 goto end_function;
1969
1970         /* copy the message into context */
1971         flow_context_ptr->message_size_in_bytes = command_args.message_size_in_bytes;
1972         error = copy_from_user(flow_context_ptr->message, (void *) command_args.message_address, command_args.message_size_in_bytes);
1973 end_function:
1974         dbg("SEP Driver:<-------- sep_add_flow_tables_message_handler end\n");
1975         return error;
1976 }
1977
1978
1979 /*
1980   this function returns the bus and virtual addresses of the static pool
1981 */
1982 static int sep_get_static_pool_addr_handler(struct sep_device *sep, unsigned long arg)
1983 {
1984         int error;
1985         struct sep_driver_static_pool_addr_t command_args;
1986
1987         dbg("SEP Driver:--------> sep_get_static_pool_addr_handler start\n");
1988
1989         /*prepare the output parameters in the struct */
1990         command_args.physical_static_address = sep->shared_bus + SEP_DRIVER_STATIC_AREA_OFFSET_IN_BYTES;
1991         command_args.virtual_static_address = (unsigned long)sep->shared_addr + SEP_DRIVER_STATIC_AREA_OFFSET_IN_BYTES;
1992
1993         edbg("SEP Driver:bus_static_address is %08lx, virtual_static_address %08lx\n", command_args.physical_static_address, command_args.virtual_static_address);
1994
1995         /* send the parameters to user application */
1996         error = copy_to_user((void *) arg, &command_args, sizeof(struct sep_driver_static_pool_addr_t));
1997         dbg("SEP Driver:<-------- sep_get_static_pool_addr_handler end\n");
1998         return error;
1999 }
2000
2001 /*
2002   this address gets the offset of the physical address from the start
2003   of the mapped area
2004 */
2005 static int sep_get_physical_mapped_offset_handler(struct sep_device *sep, unsigned long arg)
2006 {
2007         int error;
2008         struct sep_driver_get_mapped_offset_t command_args;
2009
2010         dbg("SEP Driver:--------> sep_get_physical_mapped_offset_handler start\n");
2011
2012         error = copy_from_user(&command_args, (void *) arg, sizeof(struct sep_driver_get_mapped_offset_t));
2013         if (error)
2014                 goto end_function;
2015
2016         if (command_args.physical_address < sep->shared_bus) {
2017                 error = -EINVAL;
2018                 goto end_function;
2019         }
2020
2021         /*prepare the output parameters in the struct */
2022         command_args.offset = command_args.physical_address - sep->shared_bus;
2023
2024         edbg("SEP Driver:bus_address is %08lx, offset is %lu\n", command_args.physical_address, command_args.offset);
2025
2026         /* send the parameters to user application */
2027         error = copy_to_user((void *) arg, &command_args, sizeof(struct sep_driver_get_mapped_offset_t));
2028 end_function:
2029         dbg("SEP Driver:<-------- sep_get_physical_mapped_offset_handler end\n");
2030         return error;
2031 }
2032
2033
2034 /*
2035   ?
2036 */
2037 static int sep_start_handler(struct sep_device *sep)
2038 {
2039         unsigned long reg_val;
2040         unsigned long error = 0;
2041
2042         dbg("SEP Driver:--------> sep_start_handler start\n");
2043
2044         /* wait in polling for message from SEP */
2045         do
2046                 reg_val = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR3_REG_ADDR);
2047         while (!reg_val);
2048
2049         /* check the value */
2050         if (reg_val == 0x1)
2051                 /* fatal error - read error status from GPRO */
2052                 error = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR0_REG_ADDR);
2053         dbg("SEP Driver:<-------- sep_start_handler end\n");
2054         return error;
2055 }
2056
2057 /*
2058   this function handles the request for SEP initialization
2059 */
2060 static int sep_init_handler(struct sep_device *sep, unsigned long arg)
2061 {
2062         unsigned long message_word;
2063         unsigned long *message_ptr;
2064         struct sep_driver_init_t command_args;
2065         unsigned long counter;
2066         unsigned long error;
2067         unsigned long reg_val;
2068
2069         dbg("SEP Driver:--------> sep_init_handler start\n");
2070         error = 0;
2071
2072         error = copy_from_user(&command_args, (void *) arg, sizeof(struct sep_driver_init_t));
2073
2074         dbg("SEP Driver:--------> sep_init_handler - finished copy_from_user \n");
2075
2076         if (error)
2077                 goto end_function;
2078
2079         /* PATCH - configure the DMA to single -burst instead of multi-burst */
2080         /*sep_configure_dma_burst(); */
2081
2082         dbg("SEP Driver:--------> sep_init_handler - finished sep_configure_dma_burst \n");
2083
2084         message_ptr = (unsigned long *) command_args.message_addr;
2085
2086         /* set the base address of the SRAM  */
2087         sep_write_reg(sep, HW_SRAM_ADDR_REG_ADDR, HW_CC_SRAM_BASE_ADDRESS);
2088
2089         for (counter = 0; counter < command_args.message_size_in_words; counter++, message_ptr++) {
2090                 get_user(message_word, message_ptr);
2091                 /* write data to SRAM */
2092                 sep_write_reg(sep, HW_SRAM_DATA_REG_ADDR, message_word);
2093                 edbg("SEP Driver:message_word is %lu\n", message_word);
2094                 /* wait for write complete */
2095                 sep_wait_sram_write(sep);
2096         }
2097         dbg("SEP Driver:--------> sep_init_handler - finished getting messages from user space\n");
2098         /* signal SEP */
2099         sep_write_reg(sep, HW_HOST_HOST_SEP_GPR0_REG_ADDR, 0x1);
2100
2101         do
2102                 reg_val = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR3_REG_ADDR);
2103         while (!(reg_val & 0xFFFFFFFD));
2104
2105         dbg("SEP Driver:--------> sep_init_handler - finished waiting for reg_val & 0xFFFFFFFD \n");
2106
2107         /* check the value */
2108         if (reg_val == 0x1) {
2109                 edbg("SEP Driver:init failed\n");
2110
2111                 error = sep_read_reg(sep, 0x8060);
2112                 edbg("SEP Driver:sw monitor is %lu\n", error);
2113
2114                 /* fatal error - read erro status from GPRO */
2115                 error = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR0_REG_ADDR);
2116                 edbg("SEP Driver:error is %lu\n", error);
2117         }
2118 end_function:
2119         dbg("SEP Driver:<-------- sep_init_handler end\n");
2120         return error;
2121
2122 }
2123
2124 /*
2125   this function handles the request cache and resident reallocation
2126 */
2127 static int sep_realloc_cache_resident_handler(struct sep_device *sep,
2128                                                 unsigned long arg)
2129 {
2130         struct sep_driver_realloc_cache_resident_t command_args;
2131         int error;
2132
2133         /* copy cache and resident to the their intended locations */
2134         error = sep_load_firmware(sep);
2135         if (error)
2136                 return error;
2137
2138         command_args.new_base_addr = sep->shared_bus;
2139
2140         /* find the new base address according to the lowest address between
2141            cache, resident and shared area */
2142         if (sep->resident_bus < command_args.new_base_addr)
2143                 command_args.new_base_addr = sep->resident_bus;
2144         if (sep->rar_bus < command_args.new_base_addr)
2145                 command_args.new_base_addr = sep->rar_bus;
2146
2147         /* set the return parameters */
2148         command_args.new_cache_addr = sep->rar_bus;
2149         command_args.new_resident_addr = sep->resident_bus;
2150
2151         /* set the new shared area */
2152         command_args.new_shared_area_addr = sep->shared_bus;
2153
2154         edbg("SEP Driver:command_args.new_shared_addr is %08llx\n", command_args.new_shared_area_addr);
2155         edbg("SEP Driver:command_args.new_base_addr is %08llx\n", command_args.new_base_addr);
2156         edbg("SEP Driver:command_args.new_resident_addr is %08llx\n", command_args.new_resident_addr);
2157         edbg("SEP Driver:command_args.new_rar_addr is %08llx\n", command_args.new_cache_addr);
2158
2159         /* return to user */
2160         if (copy_to_user((void *) arg, &command_args, sizeof(struct sep_driver_realloc_cache_resident_t)))
2161                 return -EFAULT;
2162         return 0;
2163 }
2164
2165 /**
2166  *      sep_get_time_handler    -       time request from user space
2167  *      @sep: sep we are to set the time for
2168  *      @arg: pointer to user space arg buffer
2169  *
2170  *      This function reports back the time and the address in the SEP
2171  *      shared buffer at which it has been placed. (Do we really need this!!!)
2172  */
2173
2174 static int sep_get_time_handler(struct sep_device *sep, unsigned long arg)
2175 {
2176         struct sep_driver_get_time_t command_args;
2177
2178         mutex_lock(&sep_mutex);
2179         command_args.time_value = sep_set_time(sep);
2180         command_args.time_physical_address = (unsigned long)sep_time_address(sep);
2181         mutex_unlock(&sep_mutex);
2182         if (copy_to_user((void __user *)arg,
2183                         &command_args, sizeof(struct sep_driver_get_time_t)))
2184                         return -EFAULT;
2185         return 0;
2186
2187 }
2188
2189 /*
2190   This API handles the end transaction request
2191 */
2192 static int sep_end_transaction_handler(struct sep_device *sep, unsigned long arg)
2193 {
2194         dbg("SEP Driver:--------> sep_end_transaction_handler start\n");
2195
2196 #if 0                           /*!SEP_DRIVER_POLLING_MODE */
2197         /* close IMR */
2198         sep_write_reg(sep, HW_HOST_IMR_REG_ADDR, 0x7FFF);
2199
2200         /* release IRQ line */
2201         free_irq(SEP_DIRVER_IRQ_NUM, sep);
2202
2203         /* lock the sep mutex */
2204         mutex_unlock(&sep_mutex);
2205 #endif
2206
2207         dbg("SEP Driver:<-------- sep_end_transaction_handler end\n");
2208
2209         return 0;
2210 }
2211
2212
2213 /**
2214  *      sep_set_flow_id_handler -       handle flow setting
2215  *      @sep: the SEP we are configuring
2216  *      @flow_id: the flow we are setting
2217  *
2218  * This function handler the set flow id command
2219  */
2220 static int sep_set_flow_id_handler(struct sep_device *sep,
2221                                                 unsigned long flow_id)
2222 {
2223         int error = 0;
2224         struct sep_flow_context_t *flow_data_ptr;
2225
2226         /* find the flow data structure that was just used for creating new flow
2227            - its id should be default */
2228
2229         mutex_lock(&sep_mutex);
2230         flow_data_ptr = sep_find_flow_context(sep, SEP_TEMP_FLOW_ID);
2231         if (flow_data_ptr)
2232                 flow_data_ptr->flow_id = flow_id;       /* set flow id */
2233         else
2234                 error = -EINVAL;
2235         mutex_unlock(&sep_mutex);
2236         return error;
2237 }
2238
2239 static long sep_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
2240 {
2241         int error = 0;
2242         struct sep_device *sep = filp->private_data;
2243
2244         dbg("------------>SEP Driver: ioctl start\n");
2245
2246         edbg("SEP Driver: cmd is %x\n", cmd);
2247
2248         switch (cmd) {
2249         case SEP_IOCSENDSEPCOMMAND:
2250                 /* send command to SEP */
2251                 sep_send_command_handler(sep);
2252                 edbg("SEP Driver: after sep_send_command_handler\n");
2253                 break;
2254         case SEP_IOCSENDSEPRPLYCOMMAND:
2255                 /* send reply command to SEP */
2256                 sep_send_reply_command_handler(sep);
2257                 break;
2258         case SEP_IOCALLOCDATAPOLL:
2259                 /* allocate data pool */
2260                 error = sep_allocate_data_pool_memory_handler(sep, arg);
2261                 break;
2262         case SEP_IOCWRITEDATAPOLL:
2263                 /* write data into memory pool */
2264                 error = sep_write_into_data_pool_handler(sep, arg);
2265                 break;
2266         case SEP_IOCREADDATAPOLL:
2267                 /* read data from data pool into application memory */
2268                 error = sep_read_from_data_pool_handler(sep, arg);
2269                 break;
2270         case SEP_IOCCREATESYMDMATABLE:
2271                 /* create dma table for synhronic operation */
2272                 error = sep_create_sync_dma_tables_handler(sep, arg);
2273                 break;
2274         case SEP_IOCCREATEFLOWDMATABLE:
2275                 /* create flow dma tables */
2276                 error = sep_create_flow_dma_tables_handler(sep, arg);
2277                 break;
2278         case SEP_IOCFREEDMATABLEDATA:
2279                 /* free the pages */
2280                 error = sep_free_dma_table_data_handler(sep);
2281                 break;
2282         case SEP_IOCSETFLOWID:
2283                 /* set flow id */
2284                 error = sep_set_flow_id_handler(sep, (unsigned long)arg);
2285                 break;
2286         case SEP_IOCADDFLOWTABLE:
2287                 /* add tables to the dynamic flow */
2288                 error = sep_add_flow_tables_handler(sep, arg);
2289                 break;
2290         case SEP_IOCADDFLOWMESSAGE:
2291                 /* add message of add tables to flow */
2292                 error = sep_add_flow_tables_message_handler(sep, arg);
2293                 break;
2294         case SEP_IOCSEPSTART:
2295                 /* start command to sep */
2296                 error = sep_start_handler(sep);
2297                 break;
2298         case SEP_IOCSEPINIT:
2299                 /* init command to sep */
2300                 error = sep_init_handler(sep, arg);
2301                 break;
2302         case SEP_IOCGETSTATICPOOLADDR:
2303                 /* get the physical and virtual addresses of the static pool */
2304                 error = sep_get_static_pool_addr_handler(sep, arg);
2305                 break;
2306         case SEP_IOCENDTRANSACTION:
2307                 error = sep_end_transaction_handler(sep, arg);
2308                 break;
2309         case SEP_IOCREALLOCCACHERES:
2310                 error = sep_realloc_cache_resident_handler(sep, arg);
2311                 break;
2312         case SEP_IOCGETMAPPEDADDROFFSET:
2313                 error = sep_get_physical_mapped_offset_handler(sep, arg);
2314                 break;
2315         case SEP_IOCGETIME:
2316                 error = sep_get_time_handler(sep, arg);
2317                 break;
2318         default:
2319                 error = -ENOTTY;
2320                 break;
2321         }
2322         dbg("SEP Driver:<-------- ioctl end\n");
2323         return error;
2324 }
2325
2326
2327
2328 #if !SEP_DRIVER_POLLING_MODE
2329
2330 /* handler for flow done interrupt */
2331
2332 static void sep_flow_done_handler(struct work_struct *work)
2333 {
2334         struct sep_flow_context_t *flow_data_ptr;
2335
2336         /* obtain the mutex */
2337         mutex_lock(&sep_mutex);
2338
2339         /* get the pointer to context */
2340         flow_data_ptr = (struct sep_flow_context_t *) work;
2341
2342         /* free all the current input tables in sep */
2343         sep_deallocated_flow_tables(&flow_data_ptr->input_tables_in_process);
2344
2345         /* free all the current tables output tables in SEP (if needed) */
2346         if (flow_data_ptr->output_tables_in_process.physical_address != 0xffffffff)
2347                 sep_deallocated_flow_tables(&flow_data_ptr->output_tables_in_process);
2348
2349         /* check if we have additional tables to be sent to SEP only input
2350            flag may be checked */
2351         if (flow_data_ptr->input_tables_flag) {
2352                 /* copy the message to the shared RAM and signal SEP */
2353                 memcpy((void *) flow_data_ptr->message, (void *) sep->shared_addr, flow_data_ptr->message_size_in_bytes);
2354
2355                 sep_write_reg(sep, HW_HOST_HOST_SEP_GPR2_REG_ADDR, 0x2);
2356         }
2357         mutex_unlock(&sep_mutex);
2358 }
2359 /*
2360   interrupt handler function
2361 */
2362 static irqreturn_t sep_inthandler(int irq, void *dev_id)
2363 {
2364         irqreturn_t int_error;
2365         unsigned long reg_val;
2366         unsigned long flow_id;
2367         struct sep_flow_context_t *flow_context_ptr;
2368         struct sep_device *sep = dev_id;
2369
2370         int_error = IRQ_HANDLED;
2371
2372         /* read the IRR register to check if this is SEP interrupt */
2373         reg_val = sep_read_reg(sep, HW_HOST_IRR_REG_ADDR);
2374         edbg("SEP Interrupt - reg is %08lx\n", reg_val);
2375
2376         /* check if this is the flow interrupt */
2377         if (0 /*reg_val & (0x1 << 11) */ ) {
2378                 /* read GPRO to find out the which flow is done */
2379                 flow_id = sep_read_reg(sep, HW_HOST_IRR_REG_ADDR);
2380
2381                 /* find the contex of the flow */
2382                 flow_context_ptr = sep_find_flow_context(sep, flow_id >> 28);
2383                 if (flow_context_ptr == NULL)
2384                         goto end_function_with_error;
2385
2386                 /* queue the work */
2387                 INIT_WORK(&flow_context_ptr->flow_wq, sep_flow_done_handler);
2388                 queue_work(sep->flow_wq, &flow_context_ptr->flow_wq);
2389
2390         } else {
2391                 /* check if this is reply interrupt from SEP */
2392                 if (reg_val & (0x1 << 13)) {
2393                         /* update the counter of reply messages */
2394                         sep->reply_ct++;
2395                         /* wake up the waiting process */
2396                         wake_up(&sep_event);
2397                 } else {
2398                         int_error = IRQ_NONE;
2399                         goto end_function;
2400                 }
2401         }
2402 end_function_with_error:
2403         /* clear the interrupt */
2404         sep_write_reg(sep, HW_HOST_ICR_REG_ADDR, reg_val);
2405 end_function:
2406         return int_error;
2407 }
2408
2409 #endif
2410
2411
2412
2413 #if 0
2414
2415 static void sep_wait_busy(struct sep_device *sep)
2416 {
2417         u32 reg;
2418
2419         do {
2420                 reg = sep_read_reg(sep, HW_HOST_SEP_BUSY_REG_ADDR);
2421         } while (reg);
2422 }
2423
2424 /*
2425   PATCH for configuring the DMA to single burst instead of multi-burst
2426 */
2427 static void sep_configure_dma_burst(struct sep_device *sep)
2428 {
2429 #define          HW_AHB_RD_WR_BURSTS_REG_ADDR            0x0E10UL
2430
2431         dbg("SEP Driver:<-------- sep_configure_dma_burst start \n");
2432
2433         /* request access to registers from SEP */
2434         sep_write_reg(sep, HW_HOST_HOST_SEP_GPR0_REG_ADDR, 0x2);
2435
2436         dbg("SEP Driver:<-------- sep_configure_dma_burst finished request access to registers from SEP (write reg)  \n");
2437
2438         sep_wait_busy(sep);
2439
2440         dbg("SEP Driver:<-------- sep_configure_dma_burst finished request access to registers from SEP (while(revVal) wait loop)  \n");
2441
2442         /* set the DMA burst register to single burst */
2443         sep_write_reg(sep, HW_AHB_RD_WR_BURSTS_REG_ADDR, 0x0UL);
2444
2445         /* release the sep busy */
2446         sep_write_reg(sep, HW_HOST_HOST_SEP_GPR0_REG_ADDR, 0x0UL);
2447         sep_wait_busy(sep);
2448
2449         dbg("SEP Driver:<-------- sep_configure_dma_burst done  \n");
2450
2451 }
2452
2453 #endif
2454
2455 /*
2456   Function that is activated on the successful probe of the SEP device
2457 */
2458 static int __devinit sep_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
2459 {
2460         int error = 0;
2461         struct sep_device *sep;
2462         int counter;
2463         int size;               /* size of memory for allocation */
2464
2465         edbg("Sep pci probe starting\n");
2466         if (sep_dev != NULL) {
2467                 dev_warn(&pdev->dev, "only one SEP supported.\n");
2468                 return -EBUSY;
2469         }
2470
2471         /* enable the device */
2472         error = pci_enable_device(pdev);
2473         if (error) {
2474                 edbg("error enabling pci device\n");
2475                 goto end_function;
2476         }
2477
2478         /* set the pci dev pointer */
2479         sep_dev = &sep_instance;
2480         sep = &sep_instance;
2481
2482         edbg("sep->shared_addr = %p\n", sep->shared_addr);
2483         /* transaction counter that coordinates the transactions between SEP
2484         and HOST */
2485         sep->send_ct = 0;
2486         /* counter for the messages from sep */
2487         sep->reply_ct = 0;
2488         /* counter for the number of bytes allocated in the pool
2489         for the current transaction */
2490         sep->data_pool_bytes_allocated = 0;
2491
2492         /* calculate the total size for allocation */
2493         size = SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES +
2494             SEP_DRIVER_SYNCHRONIC_DMA_TABLES_AREA_SIZE_IN_BYTES + SEP_DRIVER_DATA_POOL_SHARED_AREA_SIZE_IN_BYTES + SEP_DRIVER_FLOW_DMA_TABLES_AREA_SIZE_IN_BYTES + SEP_DRIVER_STATIC_AREA_SIZE_IN_BYTES + SEP_DRIVER_SYSTEM_DATA_MEMORY_SIZE_IN_BYTES;
2495
2496         /* allocate the shared area */
2497         if (sep_map_and_alloc_shared_area(sep, size)) {
2498                 error = -ENOMEM;
2499                 /* allocation failed */
2500                 goto end_function_error;
2501         }
2502         /* now set the memory regions */
2503 #if (SEP_DRIVER_RECONFIG_MESSAGE_AREA == 1)
2504         /* Note: this test section will need moving before it could ever
2505            work as the registers are not yet mapped ! */
2506         /* send the new SHARED MESSAGE AREA to the SEP */
2507         sep_write_reg(sep, HW_HOST_HOST_SEP_GPR1_REG_ADDR, sep->shared_bus);
2508
2509         /* poll for SEP response */
2510         retval = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR1_REG_ADDR);
2511         while (retval != 0xffffffff && retval != sep->shared_bus)
2512                 retval = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR1_REG_ADDR);
2513
2514         /* check the return value (register) */
2515         if (retval != sep->shared_bus) {
2516                 error = -ENOMEM;
2517                 goto end_function_deallocate_sep_shared_area;
2518         }
2519 #endif
2520         /* init the flow contextes */
2521         for (counter = 0; counter < SEP_DRIVER_NUM_FLOWS; counter++)
2522                 sep->flows[counter].flow_id = SEP_FREE_FLOW_ID;
2523
2524         sep->flow_wq = create_singlethread_workqueue("sepflowwq");
2525         if (sep->flow_wq == NULL) {
2526                 error = -ENOMEM;
2527                 edbg("sep_driver:flow queue creation failed\n");
2528                 goto end_function_deallocate_sep_shared_area;
2529         }
2530         edbg("SEP Driver: create flow workqueue \n");
2531         sep->pdev = pci_dev_get(pdev);
2532
2533         sep->reg_addr = pci_ioremap_bar(pdev, 0);
2534         if (!sep->reg_addr) {
2535                 edbg("sep: ioremap of registers failed.\n");
2536                 goto end_function_deallocate_sep_shared_area;
2537         }
2538         edbg("SEP Driver:reg_addr is %p\n", sep->reg_addr);
2539
2540         /* load the rom code */
2541         sep_load_rom_code(sep);
2542
2543         /* set up system base address and shared memory location */
2544         sep->rar_addr = dma_alloc_coherent(&sep->pdev->dev,
2545                         2 * SEP_RAR_IO_MEM_REGION_SIZE,
2546                         &sep->rar_bus, GFP_KERNEL);
2547
2548         if (!sep->rar_addr) {
2549                 edbg("SEP Driver:can't allocate rar\n");
2550                 goto end_function_uniomap;
2551         }
2552
2553
2554         edbg("SEP Driver:rar_bus is %08llx\n", (unsigned long long)sep->rar_bus);
2555         edbg("SEP Driver:rar_virtual is %p\n", sep->rar_addr);
2556
2557 #if !SEP_DRIVER_POLLING_MODE
2558
2559         edbg("SEP Driver: about to write IMR and ICR REG_ADDR\n");
2560
2561         /* clear ICR register */
2562         sep_write_reg(sep, HW_HOST_ICR_REG_ADDR, 0xFFFFFFFF);
2563
2564         /* set the IMR register - open only GPR 2 */
2565         sep_write_reg(sep, HW_HOST_IMR_REG_ADDR, (~(0x1 << 13)));
2566
2567         edbg("SEP Driver: about to call request_irq\n");
2568         /* get the interrupt line */
2569         error = request_irq(pdev->irq, sep_inthandler, IRQF_SHARED, "sep_driver", sep);
2570         if (error)
2571                 goto end_function_free_res;
2572         return 0;
2573         edbg("SEP Driver: about to write IMR REG_ADDR");
2574
2575         /* set the IMR register - open only GPR 2 */
2576         sep_write_reg(sep, HW_HOST_IMR_REG_ADDR, (~(0x1 << 13)));
2577
2578 end_function_free_res:
2579         dma_free_coherent(&sep->pdev->dev, 2 * SEP_RAR_IO_MEM_REGION_SIZE,
2580                         sep->rar_addr, sep->rar_bus);
2581 #endif                          /* SEP_DRIVER_POLLING_MODE */
2582 end_function_uniomap:
2583         iounmap(sep->reg_addr);
2584 end_function_deallocate_sep_shared_area:
2585         /* de-allocate shared area */
2586         sep_unmap_and_free_shared_area(sep, size);
2587 end_function_error:
2588         sep_dev = NULL;
2589 end_function:
2590         return error;
2591 }
2592
2593 static const struct pci_device_id sep_pci_id_tbl[] = {
2594         {PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x080c)},
2595         {0}
2596 };
2597
2598 MODULE_DEVICE_TABLE(pci, sep_pci_id_tbl);
2599
2600 /* field for registering driver to PCI device */
2601 static struct pci_driver sep_pci_driver = {
2602         .name = "sep_sec_driver",
2603         .id_table = sep_pci_id_tbl,
2604         .probe = sep_probe
2605         /* FIXME: remove handler */
2606 };
2607
2608 /* major and minor device numbers */
2609 static dev_t sep_devno;
2610
2611 /* the files operations structure of the driver */
2612 static struct file_operations sep_file_operations = {
2613         .owner = THIS_MODULE,
2614         .unlocked_ioctl = sep_ioctl,
2615         .poll = sep_poll,
2616         .open = sep_open,
2617         .release = sep_release,
2618         .mmap = sep_mmap,
2619 };
2620
2621
2622 /* cdev struct of the driver */
2623 static struct cdev sep_cdev;
2624
2625 /*
2626   this function registers the driver to the file system
2627 */
2628 static int sep_register_driver_to_fs(void)
2629 {
2630         int ret_val = alloc_chrdev_region(&sep_devno, 0, 1, "sep_sec_driver");
2631         if (ret_val) {
2632                 edbg("sep: major number allocation failed, retval is %d\n",
2633                                                                 ret_val);
2634                 return ret_val;
2635         }
2636         /* init cdev */
2637         cdev_init(&sep_cdev, &sep_file_operations);
2638         sep_cdev.owner = THIS_MODULE;
2639
2640         /* register the driver with the kernel */
2641         ret_val = cdev_add(&sep_cdev, sep_devno, 1);
2642         if (ret_val) {
2643                 edbg("sep_driver:cdev_add failed, retval is %d\n", ret_val);
2644                 /* unregister dev numbers */
2645                 unregister_chrdev_region(sep_devno, 1);
2646         }
2647         return ret_val;
2648 }
2649
2650
2651 /*--------------------------------------------------------------
2652   init function
2653 ----------------------------------------------------------------*/
2654 static int __init sep_init(void)
2655 {
2656         int ret_val = 0;
2657         dbg("SEP Driver:-------->Init start\n");
2658         /* FIXME: Probe can occur before we are ready to survive a probe */
2659         ret_val = pci_register_driver(&sep_pci_driver);
2660         if (ret_val) {
2661                 edbg("sep_driver:sep_driver_to_device failed, ret_val is %d\n", ret_val);
2662                 goto end_function_unregister_from_fs;
2663         }
2664         /* register driver to fs */
2665         ret_val = sep_register_driver_to_fs();
2666         if (ret_val)
2667                 goto end_function_unregister_pci;
2668         goto end_function;
2669 end_function_unregister_pci:
2670         pci_unregister_driver(&sep_pci_driver);
2671 end_function_unregister_from_fs:
2672         /* unregister from fs */
2673         cdev_del(&sep_cdev);
2674         /* unregister dev numbers */
2675         unregister_chrdev_region(sep_devno, 1);
2676 end_function:
2677         dbg("SEP Driver:<-------- Init end\n");
2678         return ret_val;
2679 }
2680
2681
2682 /*-------------------------------------------------------------
2683   exit function
2684 --------------------------------------------------------------*/
2685 static void __exit sep_exit(void)
2686 {
2687         int size;
2688
2689         dbg("SEP Driver:--------> Exit start\n");
2690
2691         /* unregister from fs */
2692         cdev_del(&sep_cdev);
2693         /* unregister dev numbers */
2694         unregister_chrdev_region(sep_devno, 1);
2695         /* calculate the total size for de-allocation */
2696         size = SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES +
2697             SEP_DRIVER_SYNCHRONIC_DMA_TABLES_AREA_SIZE_IN_BYTES + SEP_DRIVER_DATA_POOL_SHARED_AREA_SIZE_IN_BYTES + SEP_DRIVER_FLOW_DMA_TABLES_AREA_SIZE_IN_BYTES + SEP_DRIVER_STATIC_AREA_SIZE_IN_BYTES + SEP_DRIVER_SYSTEM_DATA_MEMORY_SIZE_IN_BYTES;
2698         /* FIXME: We need to do this in the unload for the device */
2699         /* free shared area  */
2700         if (sep_dev) {
2701                 sep_unmap_and_free_shared_area(sep_dev, size);
2702                 edbg("SEP Driver: free pages SEP SHARED AREA \n");
2703                 iounmap((void *) sep_dev->reg_addr);
2704                 edbg("SEP Driver: iounmap \n");
2705         }
2706         edbg("SEP Driver: release_mem_region \n");
2707         dbg("SEP Driver:<-------- Exit end\n");
2708 }
2709
2710
2711 module_init(sep_init);
2712 module_exit(sep_exit);
2713
2714 MODULE_LICENSE("GPL");