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