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