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