3 * sep_main_mod.c - Security Processor Driver main group of functions
5 * Copyright(c) 2009 Intel Corporation. All rights reserved.
6 * Copyright(c) 2009 Discretix. All rights reserved.
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)
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
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.
24 * Mark Allyn mark.a.allyn@intel.com
28 * 2009.06.26 Initial publish
32 #include <linux/init.h>
33 #include <linux/module.h>
35 #include <linux/cdev.h>
36 #include <linux/kdev_t.h>
37 #include <linux/mutex.h>
39 #include <linux/poll.h>
40 #include <linux/wait.h>
41 #include <linux/pci.h>
42 #include <linux/firmware.h>
43 #include <asm/ioctl.h>
44 #include <linux/ioport.h>
46 #include <linux/interrupt.h>
47 #include <linux/pagemap.h>
48 #include <asm/cacheflush.h>
49 #include "sep_driver_hw_defs.h"
50 #include "sep_driver_config.h"
51 #include "sep_driver_api.h"
52 #include "sep_driver_ext_api.h"
55 #if SEP_DRIVER_ARM_DEBUG_MODE
57 #define CRYS_SEP_ROM_length 0x4000
58 #define CRYS_SEP_ROM_start_address 0x8000C000UL
59 #define CRYS_SEP_ROM_start_address_offset 0xC000UL
60 #define SEP_ROM_BANK_register 0x80008420UL
61 #define SEP_ROM_BANK_register_offset 0x8420UL
62 #define SEP_RAR_IO_MEM_REGION_START_ADDRESS 0x82000000
65 * THESE 2 definitions are specific to the board - must be
66 * defined during integration
68 #define SEP_RAR_IO_MEM_REGION_START_ADDRESS 0xFF0D0000
72 void sep_load_rom_code(void)
75 unsigned long i, k, j;
78 unsigned long warning;
80 /* Loading ROM from SEP_ROM_image.h file */
81 k = sizeof(CRYS_SEP_ROM);
83 edbg("SEP Driver: DX_CC_TST_SepRomLoader start\n");
85 edbg("SEP Driver: k is %lu\n", k);
86 edbg("SEP Driver: sep_dev->reg_base_address is %p\n", sep_dev->reg_base_address);
87 edbg("SEP Driver: CRYS_SEP_ROM_start_address_offset is %p\n", CRYS_SEP_ROM_start_address_offset);
89 for (i = 0; i < 4; i++) {
91 sep_write_reg(sep_dev, SEP_ROM_BANK_register_offset, i);
93 for (j = 0; j < CRYS_SEP_ROM_length / 4; j++) {
94 sep_write_reg(sep_dev, CRYS_SEP_ROM_start_address_offset + 4 * j, CRYS_SEP_ROM[i * 0x1000 + j]);
99 j = CRYS_SEP_ROM_length;
106 sep_write_reg(sep_dev, HW_HOST_SEP_SW_RST_REG_ADDR, 0x1);
108 /* poll for SEP ROM boot finish */
110 retVal = sep_read_reg(sep_dev, HW_HOST_SEP_HOST_GPR3_REG_ADDR);
113 edbg("SEP Driver: ROM polling ended\n");
117 /* fatal error - read erro status from GPRO */
118 Error = sep_read_reg(sep_dev, HW_HOST_SEP_HOST_GPR0_REG_ADDR);
119 edbg("SEP Driver: ROM polling case 1\n");
122 /* Boot First Phase ended */
123 warning = sep_read_reg(sep_dev, HW_HOST_SEP_HOST_GPR0_REG_ADDR);
124 edbg("SEP Driver: ROM polling case 2\n");
127 /* Cold boot ended successfully */
128 warning = sep_read_reg(sep_dev, HW_HOST_SEP_HOST_GPR0_REG_ADDR);
129 edbg("SEP Driver: ROM polling case 4\n");
133 /* Warmboot ended successfully */
134 warning = sep_read_reg(sep_dev, HW_HOST_SEP_HOST_GPR0_REG_ADDR);
135 edbg("SEP Driver: ROM polling case 8\n");
139 /* ColdWarm boot ended successfully */
140 warning = sep_read_reg(sep_dev, HW_HOST_SEP_HOST_GPR0_REG_ADDR);
141 edbg("SEP Driver: ROM polling case 16\n");
145 edbg("SEP Driver: ROM polling case 32\n");
152 void sep_load_rom_code(void) { }
153 #endif /* SEP_DRIVER_ARM_DEBUG_MODE */
157 /*----------------------------------------
159 -----------------------------------------*/
161 #define INT_MODULE_PARM(n, v) int n = v; module_param(n, int, 0)
162 #define BASE_ADDRESS_FOR_SYSTEM 0xfffc0000
163 #define SEP_RAR_IO_MEM_REGION_SIZE 0x40000
165 /*--------------------------------------------
167 --------------------------------------------*/
169 /* debug messages level */
170 INT_MODULE_PARM(sepDebug, 0x0);
171 MODULE_PARM_DESC(sepDebug, "Flag to enable SEP debug messages");
173 /* Keep this a single static object for now to keep the conversion easy */
175 static struct sep_device sep_instance;
176 struct sep_device *sep_dev = &sep_instance;
179 unsigned long jiffies_future;
183 mutex for the access to the internals of the sep driver
185 static DEFINE_MUTEX(sep_mutex);
188 /* wait queue head (event) of the driver */
189 static DECLARE_WAIT_QUEUE_HEAD(g_sep_event);
193 /*------------------------------------------------
195 ---------------------------------------------------*/
198 interrupt handler function
200 irqreturn_t sep_inthandler(int irq, void *dev_id);
203 this function registers the driver to the file system
205 static int sep_register_driver_to_fs(void);
208 this function unregisters driver from fs
210 static void sep_unregister_driver_from_fs(void);
213 this function calculates the size of data that can be inserted into the lli
214 table from this array the condition is that either the table is full
215 (all etnries are entered), or there are no more entries in the lli array
217 static unsigned long sep_calculate_lli_table_max_size(struct sep_lli_entry_t *lli_in_array_ptr, unsigned long num_array_entries);
219 this functions builds ont lli table from the lli_array according to the
222 static void sep_build_lli_table(struct sep_lli_entry_t *lli_array_ptr, struct sep_lli_entry_t *lli_table_ptr, unsigned long *num_processed_entries_ptr, unsigned long *num_table_entries_ptr, unsigned long table_data_size);
225 this function goes over the list of the print created tables and prints
228 static void sep_debug_print_lli_tables(struct sep_lli_entry_t *lli_table_ptr, unsigned long num_table_entries, unsigned long table_data_size);
233 This function raises interrupt to SEPm that signals that is has a new
236 static void sep_send_command_handler(void);
240 This function raises interrupt to SEP that signals that is has a
243 static void sep_send_reply_command_handler(void);
246 This function handles the allocate data pool memory request
247 This function returns calculates the physical address of the allocated memory
248 and the offset of this area from the mapped address. Therefore, the FVOs in
249 user space can calculate the exact virtual address of this allocated memory
251 static int sep_allocate_data_pool_memory_handler(unsigned long arg);
255 This function handles write into allocated data pool command
257 static int sep_write_into_data_pool_handler(unsigned long arg);
260 this function handles the read from data pool command
262 static int sep_read_from_data_pool_handler(unsigned long arg);
265 this function handles tha request for creation of the DMA table
266 for the synchronic symmetric operations (AES,DES)
268 static int sep_create_sync_dma_tables_handler(unsigned long arg);
271 this function handles the request to create the DMA tables for flow
273 static int sep_create_flow_dma_tables_handler(unsigned long arg);
276 This API handles the end transaction request
278 static int sep_end_transaction_handler(unsigned long arg);
282 this function handles add tables to flow
284 static int sep_add_flow_tables_handler(unsigned long arg);
287 this function add the flow add message to the specific flow
289 static int sep_add_flow_tables_message_handler(unsigned long arg);
292 this function handles the request for SEP start
294 static int sep_start_handler(void);
297 this function handles the request for SEP initialization
299 static int sep_init_handler(unsigned long arg);
302 this function handles the request cache and resident reallocation
304 static int sep_realloc_cache_resident_handler(unsigned long arg);
308 This api handles the setting of API mode to blocking or non-blocking
310 static int sep_set_api_mode_handler(unsigned long arg);
312 /* handler for flow done interrupt */
313 static void sep_flow_done_handler(struct work_struct *work);
316 This function locks all the physical pages of the kernel virtual buffer
317 and construct a basic lli array, where each entry holds the physical
318 page address and the size that application data holds in this physical pages
320 static int sep_lock_kernel_pages(unsigned long kernel_virt_addr, unsigned long data_size, unsigned long *num_pages_ptr, struct sep_lli_entry_t **lli_array_ptr, struct page ***page_array_ptr);
323 This function creates one DMA table for flow and returns its data,
324 and pointer to its info entry
326 static int sep_prepare_one_flow_dma_table(unsigned long virt_buff_addr, unsigned long virt_buff_size, struct sep_lli_entry_t *table_data, struct sep_lli_entry_t **info_entry_ptr, struct sep_flow_context_t *flow_data_ptr, bool isKernelVirtualAddress);
329 This function creates a list of tables for flow and returns the data for the
330 first and last tables of the list
332 static int sep_prepare_flow_dma_tables(unsigned long num_virtual_buffers,
333 unsigned long first_buff_addr, struct sep_flow_context_t *flow_data_ptr, struct sep_lli_entry_t *first_table_data_ptr, struct sep_lli_entry_t *last_table_data_ptr, bool isKernelVirtualAddress);
336 this function find a space for the new flow dma table
338 static int sep_find_free_flow_dma_table_space(unsigned long **table_address_ptr);
341 this function goes over all the flow tables connected to the given table and
344 static void sep_deallocated_flow_tables(struct sep_lli_entry_t *first_table_ptr);
347 This function handler the set flow id command
349 static int sep_set_flow_id_handler(unsigned long arg);
352 This function returns pointer to the flow data structure
353 that conatins the given id
355 static int sep_find_flow_context(unsigned long flow_id, struct sep_flow_context_t **flow_data_ptr);
359 this function returns the physical and virtual addresses of the static pool
361 static int sep_get_static_pool_addr_handler(unsigned long arg);
364 this address gets the offset of the physical address from the start of
367 static int sep_get_physical_mapped_offset_handler(unsigned long arg);
371 this function handles the request for get time
373 static int sep_get_time_handler(unsigned long arg);
376 calculates time and sets it at the predefined address
378 static int sep_set_time(unsigned long *address_ptr, unsigned long *time_in_sec_ptr);
381 PATCH for configuring the DMA to single burst instead of multi-burst
383 static void sep_configure_dma_burst(void);
386 This function locks all the physical pages of the
387 application virtual buffer and construct a basic lli
388 array, where each entry holds the physical page address
389 and the size that application data holds in this physical pages
391 static int sep_lock_user_pages(unsigned long app_virt_addr, unsigned long data_size, unsigned long *num_pages_ptr, struct sep_lli_entry_t **lli_array_ptr, struct page ***page_array_ptr);
393 /*---------------------------------------------
395 -----------------------------------------------*/
398 This functions locks the area of the resisnd and cache sep code
400 void sep_lock_cache_resident_area(void)
406 This functions copies the cache and resident from their source location into
407 destination memory, which is external to Linux VM and is given as
410 int sep_copy_cache_resident_to_area(unsigned long src_cache_addr, unsigned long cache_size_in_bytes, unsigned long src_resident_addr, unsigned long resident_size_in_bytes, unsigned long *dst_new_cache_addr_ptr, unsigned long *dst_new_resident_addr_ptr)
412 unsigned long resident_addr;
413 unsigned long cache_addr;
414 const struct firmware *fw;
416 char *cache_name = "cache.image.bin";
417 char *res_name = "resident.image.bin";
422 /*--------------------------------
424 -------------------------------------*/
427 edbg("SEP Driver:rar_virtual is %p\n", sep_dev->rar_virtual_address);
428 edbg("SEP Driver:rar_physical is %08lx\n", sep_dev->rar_physical_address);
430 sep_dev->rar_region_addr = (unsigned long) sep_dev->rar_virtual_address;
432 sep_dev->cache_physical_address = sep_dev->rar_physical_address;
433 sep_dev->cache_virtual_address = sep_dev->rar_virtual_address;
436 error = request_firmware(&fw, cache_name, &sep_dev->sep_pci_dev_ptr->dev);
438 edbg("SEP Driver:cant request cache fw\n");
442 edbg("SEP Driver:cache data loc is %p\n", (void *) fw->data);
443 edbg("SEP Driver:cache data size is %08Zx\n", fw->size);
445 memcpy((void *) sep_dev->cache_virtual_address, (void *) fw->data, fw->size);
447 sep_dev->cache_size = fw->size;
449 cache_addr = (unsigned long) sep_dev->cache_virtual_address;
451 release_firmware(fw);
453 sep_dev->resident_physical_address = sep_dev->cache_physical_address + sep_dev->cache_size;
454 sep_dev->resident_virtual_address = sep_dev->cache_virtual_address + sep_dev->cache_size;
457 error = request_firmware(&fw, res_name, &sep_dev->sep_pci_dev_ptr->dev);
459 edbg("SEP Driver:cant request res fw\n");
463 edbg("SEP Driver:res data loc is %p\n", (void *) fw->data);
464 edbg("SEP Driver:res data size is %08Zx\n", fw->size);
466 memcpy((void *) sep_dev->resident_virtual_address, (void *) fw->data, fw->size);
468 sep_dev->resident_size = fw->size;
470 release_firmware(fw);
472 resident_addr = (unsigned long) sep_dev->resident_virtual_address;
474 edbg("SEP Driver:resident_addr (physical )is %08lx\n", sep_dev->resident_physical_address);
475 edbg("SEP Driver:cache_addr (physical) is %08lx\n", sep_dev->cache_physical_address);
477 edbg("SEP Driver:resident_addr (logical )is %08lx\n", resident_addr);
478 edbg("SEP Driver:cache_addr (logical) is %08lx\n", cache_addr);
480 edbg("SEP Driver:resident_size is %08lx\n", sep_dev->resident_size);
481 edbg("SEP Driver:cache_size is %08lx\n", sep_dev->cache_size);
485 /* physical addresses */
486 *dst_new_cache_addr_ptr = sep_dev->cache_physical_address;
487 *dst_new_resident_addr_ptr = sep_dev->resident_physical_address;
493 This functions maps and allocates the
494 shared area on the external RAM (device)
495 The input is shared_area_size - the size of the memory to
496 allocate. The outputs
497 are kernel_shared_area_addr_ptr - the kerenl
498 address of the mapped and allocated
499 shared area, and phys_shared_area_addr_ptr
500 - the physical address of the shared area
502 int sep_map_and_alloc_shared_area(unsigned long shared_area_size, unsigned long *kernel_shared_area_addr_ptr, unsigned long *phys_shared_area_addr_ptr)
504 // shared_virtual_address = ioremap_nocache(0xda00000,shared_area_size);
505 sep_dev->shared_virtual_address = kmalloc(shared_area_size, GFP_KERNEL);
506 if (!sep_dev->shared_virtual_address) {
507 edbg("sep_driver:shared memory kmalloc failed\n");
511 sep_dev->shared_physical_address = __pa(sep_dev->shared_virtual_address);
512 /* shared_physical_address = 0xda00000; */
513 *kernel_shared_area_addr_ptr = (unsigned long) sep_dev->shared_virtual_address;
514 /* set the physical address of the shared area */
515 *phys_shared_area_addr_ptr = sep_dev->shared_physical_address;
516 edbg("SEP Driver:shared_virtual_address is %p\n", sep_dev->shared_virtual_address);
517 edbg("SEP Driver:shared_region_size is %08lx\n", shared_area_size);
518 edbg("SEP Driver:shared_physical_addr is %08lx\n", *phys_shared_area_addr_ptr);
524 This functions unmaps and deallocates the shared area
525 on the external RAM (device)
526 The input is shared_area_size - the size of the memory to deallocate,kernel_
527 shared_area_addr_ptr - the kernel address of the mapped and allocated
528 shared area,phys_shared_area_addr_ptr - the physical address of
531 void sep_unmap_and_free_shared_area(unsigned long shared_area_size, unsigned long kernel_shared_area_addr, unsigned long phys_shared_area_addr)
533 kfree((void *) kernel_shared_area_addr);
537 This functions returns the physical address inside shared area according
538 to the virtual address. It can be either on the externa RAM device
539 (ioremapped), or on the system RAM
540 This implementation is for the external RAM
542 unsigned long sep_shared_area_virt_to_phys(unsigned long virt_address)
544 edbg("SEP Driver:sh virt to phys v %08lx\n", virt_address);
545 edbg("SEP Driver:sh virt to phys p %08lx\n", sep_dev->shared_physical_address + (virt_address - (unsigned long) sep_dev->shared_virtual_address));
547 return (unsigned long) sep_dev->shared_physical_address + (virt_address - (unsigned long) sep_dev->shared_virtual_address);
551 This functions returns the virtual address inside shared area
552 according to the physical address. It can be either on the
553 externa RAM device (ioremapped), or on the system RAM This implementation
554 is for the external RAM
556 unsigned long sep_shared_area_phys_to_virt(unsigned long phys_address)
558 return (unsigned long) sep_dev->shared_virtual_address + (phys_address - sep_dev->shared_physical_address);
563 this function returns the address of the message shared area
565 void sep_map_shared_area(unsigned long *mappedAddr_ptr)
567 *mappedAddr_ptr = sep_dev->shared_area_addr;
571 this function returns the address of the message shared area
573 void sep_send_msg_rdy_cmd()
575 sep_send_command_handler();
578 /* this functions frees all the resources that were allocated for the building
579 of the LLI DMA tables */
580 void sep_free_dma_resources()
582 sep_free_dma_table_data_handler();
585 /* poll(suspend), until reply from sep */
586 void sep_driver_poll()
588 unsigned long retVal = 0;
590 #ifdef SEP_DRIVER_POLLING_MODE
592 while (sep_dev->host_to_sep_send_counter != (retVal & 0x7FFFFFFF))
593 retVal = sep_read_reg(sep_dev, HW_HOST_SEP_HOST_GPR2_REG_ADDR);
595 sep_dev->sep_to_host_reply_counter++;
597 /* poll, until reply from sep */
598 wait_event(g_sep_event, (sep_dev->host_to_sep_send_counter == sep_dev->sep_to_host_reply_counter));
603 /*----------------------------------------------------------------------
604 open function of the character driver - must only lock the mutex
605 must also release the memory data pool allocations
606 ------------------------------------------------------------------------*/
607 static int sep_open(struct inode *inode_ptr, struct file *file_ptr)
611 dbg("SEP Driver:--------> open start\n");
615 /* check the blocking mode */
616 if (sep_dev->block_mode_flag)
618 mutex_lock(&sep_mutex);
620 error = mutex_trylock(&sep_mutex);
622 /* check the error */
624 edbg("SEP Driver: down_interruptible failed\n");
629 /* release data pool allocations */
630 sep_dev->data_pool_bytes_allocated = 0;
633 dbg("SEP Driver:<-------- open end\n");
640 /*------------------------------------------------------------
642 -------------------------------------------------------------*/
643 static int sep_release(struct inode *inode_ptr, struct file *file_ptr)
645 dbg("----------->SEP Driver: sep_release start\n");
647 #if 0 /*!SEP_DRIVER_POLLING_MODE */
649 sep_write_reg(sep_dev, HW_HOST_IMR_REG_ADDR, 0x7FFF);
651 /* release IRQ line */
652 free_irq(SEP_DIRVER_IRQ_NUM, &sep_dev->reg_base_address);
656 /* unlock the sep mutex */
657 mutex_unlock(&sep_mutex);
659 dbg("SEP Driver:<-------- sep_release end\n");
667 /*---------------------------------------------------------------
668 map function - this functions maps the message shared area
669 -----------------------------------------------------------------*/
670 static int sep_mmap(struct file *filp, struct vm_area_struct *vma)
672 unsigned long phys_addr;
674 dbg("-------->SEP Driver: mmap start\n");
676 /* check that the size of the mapped range is as the size of the message
678 if ((vma->vm_end - vma->vm_start) > SEP_DRIVER_MMMAP_AREA_SIZE) {
679 edbg("SEP Driver mmap requested size is more than allowed\n");
680 printk(KERN_WARNING "SEP Driver mmap requested size is more \
682 printk(KERN_WARNING "SEP Driver vma->vm_end is %08lx\n", vma->vm_end);
683 printk(KERN_WARNING "SEP Driver vma->vm_end is %08lx\n", vma->vm_start);
687 edbg("SEP Driver:g_message_shared_area_addr is %08lx\n", sep_dev->message_shared_area_addr);
689 /* get physical address */
690 phys_addr = sep_dev->phys_shared_area_addr;
692 edbg("SEP Driver: phys_addr is %08lx\n", phys_addr);
694 if (remap_pfn_range(vma, vma->vm_start, phys_addr >> PAGE_SHIFT, vma->vm_end - vma->vm_start, vma->vm_page_prot)) {
695 edbg("SEP Driver remap_page_range failed\n");
696 printk(KERN_WARNING "SEP Driver remap_page_range failed\n");
700 dbg("SEP Driver:<-------- mmap end\n");
706 /*-----------------------------------------------
708 *----------------------------------------------*/
709 static unsigned int sep_poll(struct file *filp, poll_table * wait)
712 unsigned int mask = 0;
713 unsigned long retVal = 0; /* flow id */
715 dbg("---------->SEP Driver poll: start\n");
718 #if SEP_DRIVER_POLLING_MODE
720 while (sep_dev->host_to_sep_send_counter != (retVal & 0x7FFFFFFF)) {
721 retVal = sep_read_reg(sep_dev, HW_HOST_SEP_HOST_GPR2_REG_ADDR);
723 for (count = 0; count < 10 * 4; count += 4)
724 edbg("Poll Debug Word %lu of the message is %lu\n", count, *((unsigned long *) (sep_dev->shared_area_addr + SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES + count)));
727 sep_dev->sep_to_host_reply_counter++;
729 /* add the event to the polling wait table */
730 poll_wait(filp, &g_sep_event, wait);
734 edbg("sep_dev->host_to_sep_send_counter is %lu\n", sep_dev->host_to_sep_send_counter);
735 edbg("sep_dev->sep_to_host_reply_counter is %lu\n", sep_dev->sep_to_host_reply_counter);
737 /* check if the data is ready */
738 if (sep_dev->host_to_sep_send_counter == sep_dev->sep_to_host_reply_counter) {
739 for (count = 0; count < 12 * 4; count += 4)
740 edbg("Sep Mesg Word %lu of the message is %lu\n", count, *((unsigned long *) (sep_dev->shared_area_addr + count)));
742 for (count = 0; count < 10 * 4; count += 4)
743 edbg("Debug Data Word %lu of the message is %lu\n", count, *((unsigned long *) (sep_dev->shared_area_addr + 0x1800 + count)));
745 retVal = sep_read_reg(sep_dev, HW_HOST_SEP_HOST_GPR2_REG_ADDR);
746 edbg("retVal is %lu\n", retVal);
747 /* check if the this is sep reply or request */
749 edbg("SEP Driver: sep request in\n");
751 mask |= POLLOUT | POLLWRNORM;
753 edbg("SEP Driver: sep reply in\n");
754 mask |= POLLIN | POLLRDNORM;
757 dbg("SEP Driver:<-------- poll exit\n");
762 static int sep_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)
766 dbg("------------>SEP Driver: ioctl start\n");
768 edbg("SEP Driver: cmd is %x\n", cmd);
770 /* check that the command is for sep device */
771 if (_IOC_TYPE(cmd) != SEP_IOC_MAGIC_NUMBER)
775 case SEP_IOCSENDSEPCOMMAND:
776 /* send command to SEP */
777 sep_send_command_handler();
778 edbg("SEP Driver: after sep_send_command_handler\n");
780 case SEP_IOCSENDSEPRPLYCOMMAND:
781 /* send reply command to SEP */
782 sep_send_reply_command_handler();
784 case SEP_IOCALLOCDATAPOLL:
785 /* allocate data pool */
786 error = sep_allocate_data_pool_memory_handler(arg);
788 case SEP_IOCWRITEDATAPOLL:
789 /* write data into memory pool */
790 error = sep_write_into_data_pool_handler(arg);
792 case SEP_IOCREADDATAPOLL:
793 /* read data from data pool into application memory */
794 error = sep_read_from_data_pool_handler(arg);
796 case SEP_IOCCREATESYMDMATABLE:
797 /* create dma table for synhronic operation */
798 error = sep_create_sync_dma_tables_handler(arg);
800 case SEP_IOCCREATEFLOWDMATABLE:
801 /* create flow dma tables */
802 error = sep_create_flow_dma_tables_handler(arg);
804 case SEP_IOCFREEDMATABLEDATA:
806 error = sep_free_dma_table_data_handler();
808 case SEP_IOCSETFLOWID:
810 error = sep_set_flow_id_handler(arg);
812 case SEP_IOCADDFLOWTABLE:
813 /* add tables to the dynamic flow */
814 error = sep_add_flow_tables_handler(arg);
816 case SEP_IOCADDFLOWMESSAGE:
817 /* add message of add tables to flow */
818 error = sep_add_flow_tables_message_handler(arg);
820 case SEP_IOCSEPSTART:
821 /* start command to sep */
822 error = sep_start_handler();
825 /* init command to sep */
826 error = sep_init_handler(arg);
828 case SEP_IOCSETAPIMODE:
829 /* set non- blocking mode */
830 error = sep_set_api_mode_handler(arg);
832 case SEP_IOCGETSTATICPOOLADDR:
833 /* get the physical and virtual addresses of the static pool */
834 error = sep_get_static_pool_addr_handler(arg);
836 case SEP_IOCENDTRANSACTION:
837 error = sep_end_transaction_handler(arg);
839 case SEP_IOCREALLOCCACHERES:
840 error = sep_realloc_cache_resident_handler(arg);
842 case SEP_IOCGETMAPPEDADDROFFSET:
843 error = sep_get_physical_mapped_offset_handler(arg);
846 error = sep_get_time_handler(arg);
852 dbg("SEP Driver:<-------- ioctl end\n");
859 interrupt handler function
861 irqreturn_t sep_inthandler(int irq, void *dev_id)
863 irqreturn_t int_error;
865 unsigned long reg_val;
866 unsigned long flow_id;
867 struct sep_flow_context_t *flow_context_ptr;
869 int_error = IRQ_HANDLED;
871 /* read the IRR register to check if this is SEP interrupt */
872 reg_val = sep_read_reg(sep_dev, HW_HOST_IRR_REG_ADDR);
873 edbg("SEP Interrupt - reg is %08lx\n", reg_val);
875 /* check if this is the flow interrupt */
876 if (0 /*reg_val & (0x1 << 11) */ ) {
877 /* read GPRO to find out the which flow is done */
878 flow_id = sep_read_reg(sep_dev, HW_HOST_IRR_REG_ADDR);
880 /* find the contex of the flow */
881 error = sep_find_flow_context(flow_id >> 28, &flow_context_ptr);
883 goto end_function_with_error;
885 INIT_WORK(&flow_context_ptr->flow_wq, sep_flow_done_handler);
888 queue_work(sep_dev->flow_wq_ptr, &flow_context_ptr->flow_wq);
891 /* check if this is reply interrupt from SEP */
892 if (reg_val & (0x1 << 13)) {
893 /* update the counter of reply messages */
894 sep_dev->sep_to_host_reply_counter++;
896 /* wake up the waiting process */
897 wake_up(&g_sep_event);
899 int_error = IRQ_NONE;
903 end_function_with_error:
904 /* clear the interrupt */
905 sep_write_reg(sep_dev, HW_HOST_ICR_REG_ADDR, reg_val);
912 This function prepares only input DMA table for synhronic symmetric
915 int sep_prepare_input_dma_table(unsigned long app_virt_addr, unsigned long data_size, unsigned long block_size, unsigned long *lli_table_ptr, unsigned long *num_entries_ptr, unsigned long *table_data_size_ptr, bool isKernelVirtualAddress)
917 /* pointer to the info entry of the table - the last entry */
918 struct sep_lli_entry_t *info_entry_ptr;
919 /* array of pointers ot page */
920 struct sep_lli_entry_t *lli_array_ptr;
921 /* points to the first entry to be processed in the lli_in_array */
922 unsigned long current_entry;
923 /* num entries in the virtual buffer */
924 unsigned long sep_lli_entries;
925 /* lli table pointer */
926 struct sep_lli_entry_t *in_lli_table_ptr;
927 /* the total data in one table */
928 unsigned long table_data_size;
929 /* number of entries in lli table */
930 unsigned long num_entries_in_table;
931 /* next table address */
932 unsigned long lli_table_alloc_addr;
933 unsigned long result;
935 dbg("SEP Driver:--------> sep_prepare_input_dma_table start\n");
937 edbg("SEP Driver:data_size is %lu\n", data_size);
938 edbg("SEP Driver:block_size is %lu\n", block_size);
940 /* initialize the pages pointers */
941 sep_dev->in_page_array = 0;
942 sep_dev->in_num_pages = 0;
944 if (data_size == 0) {
945 /* special case - created 2 entries table with zero data */
946 in_lli_table_ptr = (struct sep_lli_entry_t *) (sep_dev->shared_area_addr + SEP_DRIVER_SYNCHRONIC_DMA_TABLES_AREA_OFFSET_IN_BYTES);
947 in_lli_table_ptr->physical_address = sep_dev->shared_area_addr + SEP_DRIVER_SYNCHRONIC_DMA_TABLES_AREA_OFFSET_IN_BYTES;
948 in_lli_table_ptr->block_size = 0;
951 in_lli_table_ptr->physical_address = 0xFFFFFFFF;
952 in_lli_table_ptr->block_size = 0;
954 *lli_table_ptr = sep_dev->phys_shared_area_addr + SEP_DRIVER_SYNCHRONIC_DMA_TABLES_AREA_OFFSET_IN_BYTES;
955 *num_entries_ptr = 2;
956 *table_data_size_ptr = 0;
961 /* check if the pages are in Kernel Virtual Address layout */
962 if (isKernelVirtualAddress == true)
963 /* lock the pages of the kernel buffer and translate them to pages */
964 result = sep_lock_kernel_pages(app_virt_addr, data_size, &sep_dev->in_num_pages, &lli_array_ptr, &sep_dev->in_page_array);
966 /* lock the pages of the user buffer and translate them to pages */
967 result = sep_lock_user_pages(app_virt_addr, data_size, &sep_dev->in_num_pages, &lli_array_ptr, &sep_dev->in_page_array);
972 edbg("SEP Driver:output sep_dev->in_num_pages is %lu\n", sep_dev->in_num_pages);
976 sep_lli_entries = sep_dev->in_num_pages;
978 /* initiate to point after the message area */
979 lli_table_alloc_addr = sep_dev->shared_area_addr + SEP_DRIVER_SYNCHRONIC_DMA_TABLES_AREA_OFFSET_IN_BYTES;
981 /* loop till all the entries in in array are not processed */
982 while (current_entry < sep_lli_entries) {
983 /* set the new input and output tables */
984 in_lli_table_ptr = (struct sep_lli_entry_t *) lli_table_alloc_addr;
986 lli_table_alloc_addr += sizeof(struct sep_lli_entry_t) * SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP;
988 /* calculate the maximum size of data for input table */
989 table_data_size = sep_calculate_lli_table_max_size(&lli_array_ptr[current_entry], (sep_lli_entries - current_entry));
991 /* now calculate the table size so that it will be module block size */
992 table_data_size = (table_data_size / block_size) * block_size;
994 edbg("SEP Driver:output table_data_size is %lu\n", table_data_size);
996 /* construct input lli table */
997 sep_build_lli_table(&lli_array_ptr[current_entry], in_lli_table_ptr, ¤t_entry, &num_entries_in_table, table_data_size);
999 if (info_entry_ptr == 0) {
1000 /* set the output parameters to physical addresses */
1001 *lli_table_ptr = sep_shared_area_virt_to_phys((unsigned long) in_lli_table_ptr);
1002 *num_entries_ptr = num_entries_in_table;
1003 *table_data_size_ptr = table_data_size;
1005 edbg("SEP Driver:output lli_table_in_ptr is %08lx\n", *lli_table_ptr);
1007 /* update the info entry of the previous in table */
1008 info_entry_ptr->physical_address = sep_shared_area_virt_to_phys((unsigned long) in_lli_table_ptr);
1009 info_entry_ptr->block_size = ((num_entries_in_table) << 24) | (table_data_size);
1012 /* save the pointer to the info entry of the current tables */
1013 info_entry_ptr = in_lli_table_ptr + num_entries_in_table - 1;
1016 /* print input tables */
1017 sep_debug_print_lli_tables((struct sep_lli_entry_t *)
1018 sep_shared_area_phys_to_virt(*lli_table_ptr), *num_entries_ptr, *table_data_size_ptr);
1020 /* the array of the pages */
1021 kfree(lli_array_ptr);
1023 dbg("SEP Driver:<-------- sep_prepare_input_dma_table end\n");
1029 This function builds input and output DMA tables for synhronic
1030 symmetric operations (AES, DES). It also checks that each table
1031 is of the modular block size
1033 int sep_prepare_input_output_dma_table(unsigned long app_virt_in_addr,
1034 unsigned long app_virt_out_addr,
1035 unsigned long data_size,
1036 unsigned long block_size,
1037 unsigned long *lli_table_in_ptr, unsigned long *lli_table_out_ptr, unsigned long *in_num_entries_ptr, unsigned long *out_num_entries_ptr, unsigned long *table_data_size_ptr, bool isKernelVirtualAddress)
1039 /* array of pointers of page */
1040 struct sep_lli_entry_t *lli_in_array;
1041 /* array of pointers of page */
1042 struct sep_lli_entry_t *lli_out_array;
1045 dbg("SEP Driver:--------> sep_prepare_input_output_dma_table start\n");
1047 /* initialize the pages pointers */
1048 sep_dev->in_page_array = 0;
1049 sep_dev->out_page_array = 0;
1051 /* check if the pages are in Kernel Virtual Address layout */
1052 if (isKernelVirtualAddress == true) {
1053 /* lock the pages of the kernel buffer and translate them to pages */
1054 result = sep_lock_kernel_pages(app_virt_in_addr, data_size, &sep_dev->in_num_pages, &lli_in_array, &sep_dev->in_page_array);
1056 edbg("SEP Driver: sep_lock_kernel_pages for input virtual buffer failed\n");
1060 /* lock the pages of the user buffer and translate them to pages */
1061 result = sep_lock_user_pages(app_virt_in_addr, data_size, &sep_dev->in_num_pages, &lli_in_array, &sep_dev->in_page_array);
1063 edbg("SEP Driver: sep_lock_user_pages for input virtual buffer failed\n");
1068 if (isKernelVirtualAddress == true) {
1069 result = sep_lock_kernel_pages(app_virt_out_addr, data_size, &sep_dev->out_num_pages, &lli_out_array, &sep_dev->out_page_array);
1071 edbg("SEP Driver: sep_lock_kernel_pages for output virtual buffer failed\n");
1072 goto end_function_with_error1;
1075 result = sep_lock_user_pages(app_virt_out_addr, data_size, &sep_dev->out_num_pages, &lli_out_array, &sep_dev->out_page_array);
1077 edbg("SEP Driver: sep_lock_user_pages for output virtual buffer failed\n");
1078 goto end_function_with_error1;
1081 edbg("sep_dev->in_num_pages is %lu\n", sep_dev->in_num_pages);
1082 edbg("sep_dev->out_num_pages is %lu\n", sep_dev->out_num_pages);
1083 edbg("SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP is %x\n", SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP);
1086 /* call the fucntion that creates table from the lli arrays */
1087 result = sep_construct_dma_tables_from_lli(lli_in_array, sep_dev->in_num_pages, lli_out_array, sep_dev->out_num_pages, block_size, lli_table_in_ptr, lli_table_out_ptr, in_num_entries_ptr, out_num_entries_ptr, table_data_size_ptr);
1089 edbg("SEP Driver: sep_construct_dma_tables_from_lli failed\n");
1090 goto end_function_with_error2;
1093 /* fall through - free the lli entry arrays */
1094 dbg("in_num_entries_ptr is %08lx\n", *in_num_entries_ptr);
1095 dbg("out_num_entries_ptr is %08lx\n", *out_num_entries_ptr);
1096 dbg("table_data_size_ptr is %08lx\n", *table_data_size_ptr);
1097 end_function_with_error2:
1098 kfree(lli_out_array);
1099 end_function_with_error1:
1100 kfree(lli_in_array);
1102 dbg("SEP Driver:<-------- sep_prepare_input_output_dma_table end result = %d\n", (int) result);
1109 This function creates the input and output dma tables for
1110 symmetric operations (AES/DES) according to the block size from LLI arays
1112 int sep_construct_dma_tables_from_lli(struct sep_lli_entry_t *lli_in_array,
1113 unsigned long sep_in_lli_entries,
1114 struct sep_lli_entry_t *lli_out_array,
1115 unsigned long sep_out_lli_entries,
1116 unsigned long block_size, unsigned long *lli_table_in_ptr, unsigned long *lli_table_out_ptr, unsigned long *in_num_entries_ptr, unsigned long *out_num_entries_ptr, unsigned long *table_data_size_ptr)
1118 /* points to the area where next lli table can be allocated */
1119 unsigned long lli_table_alloc_addr;
1120 /* input lli table */
1121 struct sep_lli_entry_t *in_lli_table_ptr;
1122 /* output lli table */
1123 struct sep_lli_entry_t *out_lli_table_ptr;
1124 /* pointer to the info entry of the table - the last entry */
1125 struct sep_lli_entry_t *info_in_entry_ptr;
1126 /* pointer to the info entry of the table - the last entry */
1127 struct sep_lli_entry_t *info_out_entry_ptr;
1128 /* points to the first entry to be processed in the lli_in_array */
1129 unsigned long current_in_entry;
1130 /* points to the first entry to be processed in the lli_out_array */
1131 unsigned long current_out_entry;
1132 /* max size of the input table */
1133 unsigned long in_table_data_size;
1134 /* max size of the output table */
1135 unsigned long out_table_data_size;
1136 /* flag te signifies if this is the first tables build from the arrays */
1137 unsigned long first_table_flag;
1138 /* the data size that should be in table */
1139 unsigned long table_data_size;
1140 /* number of etnries in the input table */
1141 unsigned long num_entries_in_table;
1142 /* number of etnries in the output table */
1143 unsigned long num_entries_out_table;
1145 dbg("SEP Driver:--------> sep_construct_dma_tables_from_lli start\n");
1147 /* initiate to pint after the message area */
1148 lli_table_alloc_addr = sep_dev->shared_area_addr + SEP_DRIVER_SYNCHRONIC_DMA_TABLES_AREA_OFFSET_IN_BYTES;
1150 current_in_entry = 0;
1151 current_out_entry = 0;
1152 first_table_flag = 1;
1153 info_in_entry_ptr = 0;
1154 info_out_entry_ptr = 0;
1156 /* loop till all the entries in in array are not processed */
1157 while (current_in_entry < sep_in_lli_entries) {
1158 /* set the new input and output tables */
1159 in_lli_table_ptr = (struct sep_lli_entry_t *) lli_table_alloc_addr;
1161 lli_table_alloc_addr += sizeof(struct sep_lli_entry_t) * SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP;
1163 /* set the first output tables */
1164 out_lli_table_ptr = (struct sep_lli_entry_t *) lli_table_alloc_addr;
1166 lli_table_alloc_addr += sizeof(struct sep_lli_entry_t) * SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP;
1168 /* calculate the maximum size of data for input table */
1169 in_table_data_size = sep_calculate_lli_table_max_size(&lli_in_array[current_in_entry], (sep_in_lli_entries - current_in_entry));
1171 /* calculate the maximum size of data for output table */
1172 out_table_data_size = sep_calculate_lli_table_max_size(&lli_out_array[current_out_entry], (sep_out_lli_entries - current_out_entry));
1174 edbg("SEP Driver:in_table_data_size is %lu\n", in_table_data_size);
1175 edbg("SEP Driver:out_table_data_size is %lu\n", out_table_data_size);
1177 /* check where the data is smallest */
1178 table_data_size = in_table_data_size;
1179 if (table_data_size > out_table_data_size)
1180 table_data_size = out_table_data_size;
1182 /* now calculate the table size so that it will be module block size */
1183 table_data_size = (table_data_size / block_size) * block_size;
1185 dbg("SEP Driver:table_data_size is %lu\n", table_data_size);
1187 /* construct input lli table */
1188 sep_build_lli_table(&lli_in_array[current_in_entry], in_lli_table_ptr, ¤t_in_entry, &num_entries_in_table, table_data_size);
1190 /* construct output lli table */
1191 sep_build_lli_table(&lli_out_array[current_out_entry], out_lli_table_ptr, ¤t_out_entry, &num_entries_out_table, table_data_size);
1193 /* if info entry is null - this is the first table built */
1194 if (info_in_entry_ptr == 0) {
1195 /* set the output parameters to physical addresses */
1196 *lli_table_in_ptr = sep_shared_area_virt_to_phys((unsigned long) in_lli_table_ptr);
1197 *in_num_entries_ptr = num_entries_in_table;
1198 *lli_table_out_ptr = sep_shared_area_virt_to_phys((unsigned long) out_lli_table_ptr);
1199 *out_num_entries_ptr = num_entries_out_table;
1200 *table_data_size_ptr = table_data_size;
1202 edbg("SEP Driver:output lli_table_in_ptr is %08lx\n", *lli_table_in_ptr);
1203 edbg("SEP Driver:output lli_table_out_ptr is %08lx\n", *lli_table_out_ptr);
1205 /* update the info entry of the previous in table */
1206 info_in_entry_ptr->physical_address = sep_shared_area_virt_to_phys((unsigned long) in_lli_table_ptr);
1207 info_in_entry_ptr->block_size = ((num_entries_in_table) << 24) | (table_data_size);
1209 /* update the info entry of the previous in table */
1210 info_out_entry_ptr->physical_address = sep_shared_area_virt_to_phys((unsigned long) out_lli_table_ptr);
1211 info_out_entry_ptr->block_size = ((num_entries_out_table) << 24) | (table_data_size);
1214 /* save the pointer to the info entry of the current tables */
1215 info_in_entry_ptr = in_lli_table_ptr + num_entries_in_table - 1;
1216 info_out_entry_ptr = out_lli_table_ptr + num_entries_out_table - 1;
1218 edbg("SEP Driver:output num_entries_out_table is %lu\n", (unsigned long) num_entries_out_table);
1219 edbg("SEP Driver:output info_in_entry_ptr is %lu\n", (unsigned long) info_in_entry_ptr);
1220 edbg("SEP Driver:output info_out_entry_ptr is %lu\n", (unsigned long) info_out_entry_ptr);
1223 /* print input tables */
1224 sep_debug_print_lli_tables((struct sep_lli_entry_t *)
1225 sep_shared_area_phys_to_virt(*lli_table_in_ptr), *in_num_entries_ptr, *table_data_size_ptr);
1226 /* print output tables */
1227 sep_debug_print_lli_tables((struct sep_lli_entry_t *)
1228 sep_shared_area_phys_to_virt(*lli_table_out_ptr), *out_num_entries_ptr, *table_data_size_ptr);
1229 dbg("SEP Driver:<-------- sep_construct_dma_tables_from_lli end\n");
1234 this function calculates the size of data that can be inserted into the lli
1235 table from this array the condition is that either the table is full
1236 (all etnries are entered), or there are no more entries in the lli array
1238 unsigned long sep_calculate_lli_table_max_size(struct sep_lli_entry_t *lli_in_array_ptr, unsigned long num_array_entries)
1240 unsigned long table_data_size = 0;
1241 unsigned long counter;
1243 /* calculate the data in the out lli table if till we fill the whole
1244 table or till the data has ended */
1245 for (counter = 0; (counter < (SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP - 1)) && (counter < num_array_entries); counter++)
1246 table_data_size += lli_in_array_ptr[counter].block_size;
1247 return table_data_size;
1251 this functions builds ont lli table from the lli_array according to
1252 the given size of data
1254 static void sep_build_lli_table(struct sep_lli_entry_t *lli_array_ptr, struct sep_lli_entry_t *lli_table_ptr, unsigned long *num_processed_entries_ptr, unsigned long *num_table_entries_ptr, unsigned long table_data_size)
1256 unsigned long curr_table_data_size;
1257 /* counter of lli array entry */
1258 unsigned long array_counter;
1260 dbg("SEP Driver:--------> sep_build_lli_table start\n");
1262 /* init currrent table data size and lli array entry counter */
1263 curr_table_data_size = 0;
1265 *num_table_entries_ptr = 1;
1267 edbg("SEP Driver:table_data_size is %lu\n", table_data_size);
1269 /* fill the table till table size reaches the needed amount */
1270 while (curr_table_data_size < table_data_size) {
1271 /* update the number of entries in table */
1272 (*num_table_entries_ptr)++;
1274 lli_table_ptr->physical_address = lli_array_ptr[array_counter].physical_address;
1275 lli_table_ptr->block_size = lli_array_ptr[array_counter].block_size;
1276 curr_table_data_size += lli_table_ptr->block_size;
1278 edbg("SEP Driver:lli_table_ptr is %08lx\n", (unsigned long) lli_table_ptr);
1279 edbg("SEP Driver:lli_table_ptr->physical_address is %08lx\n", lli_table_ptr->physical_address);
1280 edbg("SEP Driver:lli_table_ptr->block_size is %lu\n", lli_table_ptr->block_size);
1282 /* check for overflow of the table data */
1283 if (curr_table_data_size > table_data_size) {
1284 edbg("SEP Driver:curr_table_data_size > table_data_size\n");
1286 /* update the size of block in the table */
1287 lli_table_ptr->block_size -= (curr_table_data_size - table_data_size);
1289 /* update the physical address in the lli array */
1290 lli_array_ptr[array_counter].physical_address += lli_table_ptr->block_size;
1292 /* update the block size left in the lli array */
1293 lli_array_ptr[array_counter].block_size = (curr_table_data_size - table_data_size);
1295 /* advance to the next entry in the lli_array */
1298 edbg("SEP Driver:lli_table_ptr->physical_address is %08lx\n", lli_table_ptr->physical_address);
1299 edbg("SEP Driver:lli_table_ptr->block_size is %lu\n", lli_table_ptr->block_size);
1301 /* move to the next entry in table */
1305 /* set the info entry to default */
1306 lli_table_ptr->physical_address = 0xffffffff;
1307 lli_table_ptr->block_size = 0;
1309 edbg("SEP Driver:lli_table_ptr is %08lx\n", (unsigned long) lli_table_ptr);
1310 edbg("SEP Driver:lli_table_ptr->physical_address is %08lx\n", lli_table_ptr->physical_address);
1311 edbg("SEP Driver:lli_table_ptr->block_size is %lu\n", lli_table_ptr->block_size);
1313 /* set the output parameter */
1314 *num_processed_entries_ptr += array_counter;
1316 edbg("SEP Driver:*num_processed_entries_ptr is %lu\n", *num_processed_entries_ptr);
1317 dbg("SEP Driver:<-------- sep_build_lli_table end\n");
1322 this function goes over the list of the print created tables and
1325 static void sep_debug_print_lli_tables(struct sep_lli_entry_t *lli_table_ptr, unsigned long num_table_entries, unsigned long table_data_size)
1327 unsigned long table_count;
1328 unsigned long entries_count;
1330 dbg("SEP Driver:--------> sep_debug_print_lli_tables start\n");
1333 while ((unsigned long) lli_table_ptr != 0xffffffff) {
1334 edbg("SEP Driver: lli table %08lx, table_data_size is %lu\n", table_count, table_data_size);
1335 edbg("SEP Driver: num_table_entries is %lu\n", num_table_entries);
1337 /* print entries of the table (without info entry) */
1338 for (entries_count = 0; entries_count < num_table_entries; entries_count++, lli_table_ptr++) {
1339 edbg("SEP Driver:lli_table_ptr address is %08lx\n", (unsigned long) lli_table_ptr);
1340 edbg("SEP Driver:phys address is %08lx block size is %lu\n", lli_table_ptr->physical_address, lli_table_ptr->block_size);
1343 /* point to the info entry */
1346 edbg("SEP Driver:phys lli_table_ptr->block_size is %lu\n", lli_table_ptr->block_size);
1347 edbg("SEP Driver:phys lli_table_ptr->physical_address is %08lx\n", lli_table_ptr->physical_address);
1350 table_data_size = lli_table_ptr->block_size & 0xffffff;
1351 num_table_entries = (lli_table_ptr->block_size >> 24) & 0xff;
1352 lli_table_ptr = (struct sep_lli_entry_t *)
1353 (lli_table_ptr->physical_address);
1355 edbg("SEP Driver:phys table_data_size is %lu num_table_entries is %lu lli_table_ptr is%lu\n", table_data_size, num_table_entries, (unsigned long) lli_table_ptr);
1357 if ((unsigned long) lli_table_ptr != 0xffffffff)
1358 lli_table_ptr = (struct sep_lli_entry_t *) sep_shared_area_phys_to_virt((unsigned long) lli_table_ptr);
1362 dbg("SEP Driver:<-------- sep_debug_print_lli_tables end\n");
1367 This function locks all the physical pages of the application virtual buffer
1368 and construct a basic lli array, where each entry holds the physical page
1369 address and the size that application data holds in this physical pages
1371 int sep_lock_user_pages(unsigned long app_virt_addr, unsigned long data_size, unsigned long *num_pages_ptr, struct sep_lli_entry_t **lli_array_ptr, struct page ***page_array_ptr)
1374 /* the the page of the end address of the user space buffer */
1375 unsigned long end_page;
1376 /* the page of the start address of the user space buffer */
1377 unsigned long start_page;
1378 /* the range in pages */
1379 unsigned long num_pages;
1380 struct page **page_array;
1381 struct sep_lli_entry_t *lli_array;
1382 unsigned long count;
1385 dbg("SEP Driver:--------> sep_lock_user_pages start\n");
1387 /* set start and end pages and num pages */
1388 end_page = (app_virt_addr + data_size - 1) >> PAGE_SHIFT;
1389 start_page = app_virt_addr >> PAGE_SHIFT;
1390 num_pages = end_page - start_page + 1;
1392 edbg("SEP Driver: app_virt_addr is %08lx\n", app_virt_addr);
1393 edbg("SEP Driver: data_size is %lu\n", data_size);
1394 edbg("SEP Driver: start_page is %lu\n", start_page);
1395 edbg("SEP Driver: end_page is %lu\n", end_page);
1396 edbg("SEP Driver: num_pages is %lu\n", num_pages);
1398 /* allocate array of pages structure pointers */
1399 page_array = kmalloc(sizeof(struct page *) * num_pages, GFP_ATOMIC);
1401 edbg("SEP Driver: kmalloc for page_array failed\n");
1407 lli_array = kmalloc(sizeof(struct sep_lli_entry_t) * num_pages, GFP_ATOMIC);
1409 edbg("SEP Driver: kmalloc for lli_array failed\n");
1412 goto end_function_with_error1;
1415 /* convert the application virtual address into a set of physical */
1416 down_read(¤t->mm->mmap_sem);
1417 result = get_user_pages(current, current->mm, app_virt_addr, num_pages, 1, 0, page_array, 0);
1418 up_read(¤t->mm->mmap_sem);
1420 /* check the number of pages locked - if not all then exit with error */
1421 if (result != num_pages) {
1422 dbg("SEP Driver: not all pages locked by get_user_pages\n");
1425 goto end_function_with_error2;
1428 /* flush the cache */
1429 for (count = 0; count < num_pages; count++)
1430 flush_dcache_page(page_array[count]);
1432 /* set the start address of the first page - app data may start not at
1433 the beginning of the page */
1434 lli_array[0].physical_address = ((unsigned long) page_to_phys(page_array[0])) + (app_virt_addr & (~PAGE_MASK));
1436 /* check that not all the data is in the first page only */
1437 if ((PAGE_SIZE - (app_virt_addr & (~PAGE_MASK))) >= data_size)
1438 lli_array[0].block_size = data_size;
1440 lli_array[0].block_size = PAGE_SIZE - (app_virt_addr & (~PAGE_MASK));
1443 dbg("lli_array[0].physical_address is %08lx, lli_array[0].block_size is %lu\n", lli_array[0].physical_address, lli_array[0].block_size);
1445 /* go from the second page to the prev before last */
1446 for (count = 1; count < (num_pages - 1); count++) {
1447 lli_array[count].physical_address = (unsigned long) page_to_phys(page_array[count]);
1448 lli_array[count].block_size = PAGE_SIZE;
1450 edbg("lli_array[%lu].physical_address is %08lx, lli_array[%lu].block_size is %lu\n", count, lli_array[count].physical_address, count, lli_array[count].block_size);
1453 /* if more then 1 pages locked - then update for the last page size needed */
1454 if (num_pages > 1) {
1455 /* update the address of the last page */
1456 lli_array[count].physical_address = (unsigned long) page_to_phys(page_array[count]);
1458 /* set the size of the last page */
1459 lli_array[count].block_size = (app_virt_addr + data_size) & (~PAGE_MASK);
1461 if (lli_array[count].block_size == 0) {
1462 dbg("app_virt_addr is %08lx\n", app_virt_addr);
1463 dbg("data_size is %lu\n", data_size);
1466 edbg("lli_array[%lu].physical_address is %08lx, \
1467 lli_array[%lu].block_size is %lu\n", count, lli_array[count].physical_address, count, lli_array[count].block_size);
1470 /* set output params */
1471 *lli_array_ptr = lli_array;
1472 *num_pages_ptr = num_pages;
1473 *page_array_ptr = page_array;
1476 end_function_with_error2:
1477 /* release the cache */
1478 for (count = 0; count < num_pages; count++)
1479 page_cache_release(page_array[count]);
1481 end_function_with_error1:
1484 dbg("SEP Driver:<-------- sep_lock_user_pages end\n");
1489 This function locks all the physical pages of the kernel virtual buffer
1490 and construct a basic lli array, where each entry holds the physical
1491 page address and the size that application data holds in this physical pages
1493 int sep_lock_kernel_pages(unsigned long kernel_virt_addr, unsigned long data_size, unsigned long *num_pages_ptr, struct sep_lli_entry_t **lli_array_ptr, struct page ***page_array_ptr)
1496 /* the the page of the end address of the user space buffer */
1497 unsigned long end_page;
1498 /* the page of the start address of the user space buffer */
1499 unsigned long start_page;
1500 /* the range in pages */
1501 unsigned long num_pages;
1502 struct sep_lli_entry_t *lli_array;
1503 /* next kernel address to map */
1504 unsigned long next_kernel_address;
1505 unsigned long count;
1507 dbg("SEP Driver:--------> sep_lock_kernel_pages start\n");
1509 /* set start and end pages and num pages */
1510 end_page = (kernel_virt_addr + data_size - 1) >> PAGE_SHIFT;
1511 start_page = kernel_virt_addr >> PAGE_SHIFT;
1512 num_pages = end_page - start_page + 1;
1514 edbg("SEP Driver: kernel_virt_addr is %08lx\n", kernel_virt_addr);
1515 edbg("SEP Driver: data_size is %lu\n", data_size);
1516 edbg("SEP Driver: start_page is %lx\n", start_page);
1517 edbg("SEP Driver: end_page is %lx\n", end_page);
1518 edbg("SEP Driver: num_pages is %lu\n", num_pages);
1520 lli_array = kmalloc(sizeof(struct sep_lli_entry_t) * num_pages, GFP_ATOMIC);
1522 edbg("SEP Driver: kmalloc for lli_array failed\n");
1527 /* set the start address of the first page - app data may start not at
1528 the beginning of the page */
1529 lli_array[0].physical_address = (unsigned long) virt_to_phys((unsigned long *) kernel_virt_addr);
1531 /* check that not all the data is in the first page only */
1532 if ((PAGE_SIZE - (kernel_virt_addr & (~PAGE_MASK))) >= data_size)
1533 lli_array[0].block_size = data_size;
1535 lli_array[0].block_size = PAGE_SIZE - (kernel_virt_addr & (~PAGE_MASK));
1538 dbg("lli_array[0].physical_address is %08lx, lli_array[0].block_size is %lu\n", lli_array[0].physical_address, lli_array[0].block_size);
1540 /* advance the address to the start of the next page */
1541 next_kernel_address = (kernel_virt_addr & PAGE_MASK) + PAGE_SIZE;
1543 /* go from the second page to the prev before last */
1544 for (count = 1; count < (num_pages - 1); count++) {
1545 lli_array[count].physical_address = (unsigned long) virt_to_phys((unsigned long *) next_kernel_address);
1546 lli_array[count].block_size = PAGE_SIZE;
1548 edbg("lli_array[%lu].physical_address is %08lx, lli_array[%lu].block_size is %lu\n", count, lli_array[count].physical_address, count, lli_array[count].block_size);
1549 next_kernel_address += PAGE_SIZE;
1552 /* if more then 1 pages locked - then update for the last page size needed */
1553 if (num_pages > 1) {
1554 /* update the address of the last page */
1555 lli_array[count].physical_address = (unsigned long) virt_to_phys((unsigned long *) next_kernel_address);
1557 /* set the size of the last page */
1558 lli_array[count].block_size = (kernel_virt_addr + data_size) & (~PAGE_MASK);
1560 if (lli_array[count].block_size == 0) {
1561 dbg("app_virt_addr is %08lx\n", kernel_virt_addr);
1562 dbg("data_size is %lu\n", data_size);
1566 edbg("lli_array[%lu].physical_address is %08lx, lli_array[%lu].block_size is %lu\n", count, lli_array[count].physical_address, count, lli_array[count].block_size);
1568 /* set output params */
1569 *lli_array_ptr = lli_array;
1570 *num_pages_ptr = num_pages;
1571 *page_array_ptr = 0;
1573 dbg("SEP Driver:<-------- sep_lock_kernel_pages end\n");
1578 This function releases all the application virtual buffer physical pages,
1579 that were previously locked
1581 int sep_free_dma_pages(struct page **page_array_ptr, unsigned long num_pages, unsigned long dirtyFlag)
1583 unsigned long count;
1586 for (count = 0; count < num_pages; count++) {
1587 /* the out array was written, therefore the data was changed */
1588 if (!PageReserved(page_array_ptr[count]))
1589 SetPageDirty(page_array_ptr[count]);
1590 page_cache_release(page_array_ptr[count]);
1593 /* free in pages - the data was only read, therefore no update was done
1595 for (count = 0; count < num_pages; count++)
1596 page_cache_release(page_array_ptr[count]);
1600 /* free the array */
1601 kfree(page_array_ptr);
1607 This function raises interrupt to SEP that signals that is has a new
1610 static void sep_send_command_handler()
1612 unsigned long count;
1614 dbg("SEP Driver:--------> sep_send_command_handler start\n");
1620 for (count = 0; count < 12 * 4; count += 4)
1621 edbg("Word %lu of the message is %lu\n", count, *((unsigned long *) (sep_dev->shared_area_addr + count)));
1623 /* update counter */
1624 sep_dev->host_to_sep_send_counter++;
1625 /* send interrupt to SEP */
1626 sep_write_reg(sep_dev, HW_HOST_HOST_SEP_GPR0_REG_ADDR, 0x2);
1627 dbg("SEP Driver:<-------- sep_send_command_handler end\n");
1632 This function raises interrupt to SEPm that signals that is has a
1633 new command from HOST
1635 static void sep_send_reply_command_handler()
1637 unsigned long count;
1639 dbg("SEP Driver:--------> sep_send_reply_command_handler start\n");
1643 for (count = 0; count < 12 * 4; count += 4)
1644 edbg("Word %lu of the message is %lu\n", count, *((unsigned long *) (sep_dev->shared_area_addr + count)));
1645 /* update counter */
1646 sep_dev->host_to_sep_send_counter++;
1647 /* send the interrupt to SEP */
1648 sep_write_reg(sep_dev, HW_HOST_HOST_SEP_GPR2_REG_ADDR, sep_dev->host_to_sep_send_counter);
1649 /* update both counters */
1650 sep_dev->host_to_sep_send_counter++;
1651 sep_dev->sep_to_host_reply_counter++;
1652 dbg("SEP Driver:<-------- sep_send_reply_command_handler end\n");
1658 This function handles the allocate data pool memory request
1659 This function returns calculates the physical address of the
1660 allocated memory, and the offset of this area from the mapped address.
1661 Therefore, the FVOs in user space can calculate the exact virtual
1662 address of this allocated memory
1664 static int sep_allocate_data_pool_memory_handler(unsigned long arg)
1667 struct sep_driver_alloc_t command_args;
1669 dbg("SEP Driver:--------> sep_allocate_data_pool_memory_handler start\n");
1671 error = copy_from_user(&command_args, (void *) arg, sizeof(struct sep_driver_alloc_t));
1675 /* allocate memory */
1676 if ((sep_dev->data_pool_bytes_allocated + command_args.num_bytes) > SEP_DRIVER_DATA_POOL_SHARED_AREA_SIZE_IN_BYTES) {
1681 /* set the virtual and physical address */
1682 command_args.offset = SEP_DRIVER_DATA_POOL_AREA_OFFSET_IN_BYTES + sep_dev->data_pool_bytes_allocated;
1683 command_args.phys_address = sep_dev->phys_shared_area_addr + SEP_DRIVER_DATA_POOL_AREA_OFFSET_IN_BYTES + sep_dev->data_pool_bytes_allocated;
1685 /* write the memory back to the user space */
1686 error = copy_to_user((void *) arg, (void *) &command_args, sizeof(struct sep_driver_alloc_t));
1690 /* set the allocation */
1691 sep_dev->data_pool_bytes_allocated += command_args.num_bytes;
1694 dbg("SEP Driver:<-------- sep_allocate_data_pool_memory_handler end\n");
1699 This function handles write into allocated data pool command
1701 static int sep_write_into_data_pool_handler(unsigned long arg)
1704 unsigned long virt_address;
1705 unsigned long app_in_address;
1706 unsigned long num_bytes;
1707 unsigned long data_pool_area_addr;
1709 dbg("SEP Driver:--------> sep_write_into_data_pool_handler start\n");
1711 /* get the application address */
1712 error = get_user(app_in_address, &(((struct sep_driver_write_t *) arg)->app_address));
1716 /* get the virtual kernel address address */
1717 error = get_user(virt_address, &(((struct sep_driver_write_t *) arg)->datapool_address));
1721 /* get the number of bytes */
1722 error = get_user(num_bytes, &(((struct sep_driver_write_t *) arg)->num_bytes));
1726 /* calculate the start of the data pool */
1727 data_pool_area_addr = sep_dev->shared_area_addr + SEP_DRIVER_DATA_POOL_AREA_OFFSET_IN_BYTES;
1730 /* check that the range of the virtual kernel address is correct */
1731 if ((virt_address < data_pool_area_addr) || (virt_address > (data_pool_area_addr + SEP_DRIVER_DATA_POOL_SHARED_AREA_SIZE_IN_BYTES))) {
1735 /* copy the application data */
1736 error = copy_from_user((void *) virt_address, (void *) app_in_address, num_bytes);
1738 dbg("SEP Driver:<-------- sep_write_into_data_pool_handler end\n");
1743 this function handles the read from data pool command
1745 static int sep_read_from_data_pool_handler(unsigned long arg)
1748 /* virtual address of dest application buffer */
1749 unsigned long app_out_address;
1750 /* virtual address of the data pool */
1751 unsigned long virt_address;
1752 unsigned long num_bytes;
1753 unsigned long data_pool_area_addr;
1755 dbg("SEP Driver:--------> sep_read_from_data_pool_handler start\n");
1757 /* get the application address */
1758 error = get_user(app_out_address, &(((struct sep_driver_write_t *) arg)->app_address));
1762 /* get the virtual kernel address address */
1763 error = get_user(virt_address, &(((struct sep_driver_write_t *) arg)->datapool_address));
1767 /* get the number of bytes */
1768 error = get_user(num_bytes, &(((struct sep_driver_write_t *) arg)->num_bytes));
1772 /* calculate the start of the data pool */
1773 data_pool_area_addr = sep_dev->shared_area_addr + SEP_DRIVER_DATA_POOL_AREA_OFFSET_IN_BYTES;
1775 /* check that the range of the virtual kernel address is correct */
1776 if ((virt_address < data_pool_area_addr) || (virt_address > (data_pool_area_addr + SEP_DRIVER_DATA_POOL_SHARED_AREA_SIZE_IN_BYTES))) {
1781 /* copy the application data */
1782 error = copy_to_user((void *) app_out_address, (void *) virt_address, num_bytes);
1784 dbg("SEP Driver:<-------- sep_read_from_data_pool_handler end\n");
1790 this function handles tha request for creation of the DMA table
1791 for the synchronic symmetric operations (AES,DES)
1793 static int sep_create_sync_dma_tables_handler(unsigned long arg)
1796 /* command arguments */
1797 struct sep_driver_build_sync_table_t command_args;
1799 dbg("SEP Driver:--------> sep_create_sync_dma_tables_handler start\n");
1801 error = copy_from_user(&command_args, (void *) arg, sizeof(struct sep_driver_build_sync_table_t));
1805 edbg("app_in_address is %08lx\n", command_args.app_in_address);
1806 edbg("app_out_address is %08lx\n", command_args.app_out_address);
1807 edbg("data_size is %lu\n", command_args.data_in_size);
1808 edbg("block_size is %lu\n", command_args.block_size);
1810 /* check if we need to build only input table or input/output */
1811 if (command_args.app_out_address)
1812 /* prepare input and output tables */
1813 error = sep_prepare_input_output_dma_table(command_args.app_in_address,
1814 command_args.app_out_address,
1815 command_args.data_in_size,
1816 command_args.block_size,
1817 &command_args.in_table_address,
1818 &command_args.out_table_address, &command_args.in_table_num_entries, &command_args.out_table_num_entries, &command_args.table_data_size, command_args.isKernelVirtualAddress);
1820 /* prepare input tables */
1821 error = sep_prepare_input_dma_table(command_args.app_in_address,
1822 command_args.data_in_size, command_args.block_size, &command_args.in_table_address, &command_args.in_table_num_entries, &command_args.table_data_size, command_args.isKernelVirtualAddress);
1827 error = copy_to_user((void *) arg, (void *) &command_args, sizeof(struct sep_driver_build_sync_table_t));
1829 dbg("SEP Driver:<-------- sep_create_sync_dma_tables_handler end\n");
1834 this function handles the request for freeing dma table for synhronic actions
1836 int sep_free_dma_table_data_handler()
1838 dbg("SEP Driver:--------> sep_free_dma_table_data_handler start\n");
1840 /* free input pages array */
1841 sep_free_dma_pages(sep_dev->in_page_array, sep_dev->in_num_pages, 0);
1843 /* free output pages array if needed */
1844 if (sep_dev->out_page_array)
1845 sep_free_dma_pages(sep_dev->out_page_array, sep_dev->out_num_pages, 1);
1847 /* reset all the values */
1848 sep_dev->in_page_array = 0;
1849 sep_dev->out_page_array = 0;
1850 sep_dev->in_num_pages = 0;
1851 sep_dev->out_num_pages = 0;
1852 dbg("SEP Driver:<-------- sep_free_dma_table_data_handler end\n");
1857 this function handles the request to create the DMA tables for flow
1859 static int sep_create_flow_dma_tables_handler(unsigned long arg)
1862 struct sep_driver_build_flow_table_t command_args;
1863 /* first table - output */
1864 struct sep_lli_entry_t first_table_data;
1865 /* dma table data */
1866 struct sep_lli_entry_t last_table_data;
1867 /* pointer to the info entry of the previuos DMA table */
1868 struct sep_lli_entry_t *prev_info_entry_ptr;
1869 /* pointer to the flow data strucutre */
1870 struct sep_flow_context_t *flow_context_ptr;
1872 dbg("SEP Driver:--------> sep_create_flow_dma_tables_handler start\n");
1874 /* init variables */
1875 prev_info_entry_ptr = 0;
1876 first_table_data.physical_address = 0xffffffff;
1878 /* find the free structure for flow data */
1879 error = sep_find_flow_context(SEP_FREE_FLOW_ID, &flow_context_ptr);
1883 error = copy_from_user(&command_args, (void *) arg, sizeof(struct sep_driver_build_flow_table_t));
1887 /* create flow tables */
1888 error = sep_prepare_flow_dma_tables(command_args.num_virtual_buffers, command_args.virt_buff_data_addr, flow_context_ptr, &first_table_data, &last_table_data, command_args.isKernelVirtualAddress);
1890 goto end_function_with_error;
1892 /* check if flow is static */
1893 if (!command_args.flow_type)
1894 /* point the info entry of the last to the info entry of the first */
1895 last_table_data = first_table_data;
1897 /* set output params */
1898 command_args.first_table_addr = first_table_data.physical_address;
1899 command_args.first_table_num_entries = ((first_table_data.block_size >> SEP_NUM_ENTRIES_OFFSET_IN_BITS) & SEP_NUM_ENTRIES_MASK);
1900 command_args.first_table_data_size = (first_table_data.block_size & SEP_TABLE_DATA_SIZE_MASK);
1902 /* send the parameters to user application */
1903 error = copy_to_user((void *) arg, &command_args, sizeof(struct sep_driver_build_flow_table_t));
1905 goto end_function_with_error;
1907 /* all the flow created - update the flow entry with temp id */
1908 flow_context_ptr->flow_id = SEP_TEMP_FLOW_ID;
1910 /* set the processing tables data in the context */
1911 if (command_args.input_output_flag == SEP_DRIVER_IN_FLAG)
1912 flow_context_ptr->input_tables_in_process = first_table_data;
1914 flow_context_ptr->output_tables_in_process = first_table_data;
1918 end_function_with_error:
1919 /* free the allocated tables */
1920 sep_deallocated_flow_tables(&first_table_data);
1922 dbg("SEP Driver:<-------- sep_create_flow_dma_tables_handler end\n");
1927 this functio n handles add tables to flow
1929 static int sep_add_flow_tables_handler(unsigned long arg)
1932 unsigned long num_entries;
1933 struct sep_driver_add_flow_table_t command_args;
1934 struct sep_flow_context_t *flow_context_ptr;
1935 /* first dma table data */
1936 struct sep_lli_entry_t first_table_data;
1937 /* last dma table data */
1938 struct sep_lli_entry_t last_table_data;
1939 /* pointer to the info entry of the current DMA table */
1940 struct sep_lli_entry_t *info_entry_ptr;
1942 dbg("SEP Driver:--------> sep_add_flow_tables_handler start\n");
1944 /* get input parameters */
1945 error = copy_from_user(&command_args, (void *) arg, sizeof(struct sep_driver_add_flow_table_t));
1949 /* find the flow structure for the flow id */
1950 error = sep_find_flow_context(command_args.flow_id, &flow_context_ptr);
1954 /* prepare the flow dma tables */
1955 error = sep_prepare_flow_dma_tables(command_args.num_virtual_buffers, command_args.virt_buff_data_addr, flow_context_ptr, &first_table_data, &last_table_data, command_args.isKernelVirtualAddress);
1957 goto end_function_with_error;
1959 /* now check if there is already an existing add table for this flow */
1960 if (command_args.inputOutputFlag == SEP_DRIVER_IN_FLAG) {
1961 /* this buffer was for input buffers */
1962 if (flow_context_ptr->input_tables_flag) {
1963 /* add table already exists - add the new tables to the end
1965 num_entries = (flow_context_ptr->last_input_table.block_size >> SEP_NUM_ENTRIES_OFFSET_IN_BITS) & SEP_NUM_ENTRIES_MASK;
1967 info_entry_ptr = (struct sep_lli_entry_t *)
1968 (flow_context_ptr->last_input_table.physical_address + (sizeof(struct sep_lli_entry_t) * (num_entries - 1)));
1970 /* connect to list of tables */
1971 *info_entry_ptr = first_table_data;
1973 /* set the first table data */
1974 first_table_data = flow_context_ptr->first_input_table;
1976 /* set the input flag */
1977 flow_context_ptr->input_tables_flag = 1;
1979 /* set the first table data */
1980 flow_context_ptr->first_input_table = first_table_data;
1982 /* set the last table data */
1983 flow_context_ptr->last_input_table = last_table_data;
1984 } else { /* this is output tables */
1986 /* this buffer was for input buffers */
1987 if (flow_context_ptr->output_tables_flag) {
1988 /* add table already exists - add the new tables to
1989 the end of the previous */
1990 num_entries = (flow_context_ptr->last_output_table.block_size >> SEP_NUM_ENTRIES_OFFSET_IN_BITS) & SEP_NUM_ENTRIES_MASK;
1992 info_entry_ptr = (struct sep_lli_entry_t *)
1993 (flow_context_ptr->last_output_table.physical_address + (sizeof(struct sep_lli_entry_t) * (num_entries - 1)));
1995 /* connect to list of tables */
1996 *info_entry_ptr = first_table_data;
1998 /* set the first table data */
1999 first_table_data = flow_context_ptr->first_output_table;
2001 /* set the input flag */
2002 flow_context_ptr->output_tables_flag = 1;
2004 /* set the first table data */
2005 flow_context_ptr->first_output_table = first_table_data;
2007 /* set the last table data */
2008 flow_context_ptr->last_output_table = last_table_data;
2011 /* set output params */
2012 command_args.first_table_addr = first_table_data.physical_address;
2013 command_args.first_table_num_entries = ((first_table_data.block_size >> SEP_NUM_ENTRIES_OFFSET_IN_BITS) & SEP_NUM_ENTRIES_MASK);
2014 command_args.first_table_data_size = (first_table_data.block_size & SEP_TABLE_DATA_SIZE_MASK);
2016 /* send the parameters to user application */
2017 error = copy_to_user((void *) arg, &command_args, sizeof(struct sep_driver_add_flow_table_t));
2018 end_function_with_error:
2019 /* free the allocated tables */
2020 sep_deallocated_flow_tables(&first_table_data);
2022 dbg("SEP Driver:<-------- sep_add_flow_tables_handler end\n");
2027 this function add the flow add message to the specific flow
2029 static int sep_add_flow_tables_message_handler(unsigned long arg)
2032 struct sep_driver_add_message_t command_args;
2033 struct sep_flow_context_t *flow_context_ptr;
2035 dbg("SEP Driver:--------> sep_add_flow_tables_message_handler start\n");
2037 error = copy_from_user(&command_args, (void *) arg, sizeof(struct sep_driver_add_message_t));
2042 if (command_args.message_size_in_bytes > SEP_MAX_ADD_MESSAGE_LENGTH_IN_BYTES) {
2047 /* find the flow context */
2048 error = sep_find_flow_context(command_args.flow_id, &flow_context_ptr);
2052 /* copy the message into context */
2053 flow_context_ptr->message_size_in_bytes = command_args.message_size_in_bytes;
2054 error = copy_from_user(flow_context_ptr->message, (void *) command_args.message_address, command_args.message_size_in_bytes);
2056 dbg("SEP Driver:<-------- sep_add_flow_tables_message_handler end\n");
2062 this function returns the physical and virtual addresses of the static pool
2064 static int sep_get_static_pool_addr_handler(unsigned long arg)
2067 struct sep_driver_static_pool_addr_t command_args;
2069 dbg("SEP Driver:--------> sep_get_static_pool_addr_handler start\n");
2071 /*prepare the output parameters in the struct */
2072 command_args.physical_static_address = sep_dev->phys_shared_area_addr + SEP_DRIVER_STATIC_AREA_OFFSET_IN_BYTES;
2073 command_args.virtual_static_address = sep_dev->shared_area_addr + SEP_DRIVER_STATIC_AREA_OFFSET_IN_BYTES;
2075 edbg("SEP Driver:physical_static_address is %08lx, virtual_static_address %08lx\n", command_args.physical_static_address, command_args.virtual_static_address);
2077 /* send the parameters to user application */
2078 error = copy_to_user((void *) arg, &command_args, sizeof(struct sep_driver_static_pool_addr_t));
2079 dbg("SEP Driver:<-------- sep_get_static_pool_addr_handler end\n");
2084 this address gets the offset of the physical address from the start
2087 static int sep_get_physical_mapped_offset_handler(unsigned long arg)
2090 struct sep_driver_get_mapped_offset_t command_args;
2092 dbg("SEP Driver:--------> sep_get_physical_mapped_offset_handler start\n");
2094 error = copy_from_user(&command_args, (void *) arg, sizeof(struct sep_driver_get_mapped_offset_t));
2098 if (command_args.physical_address < sep_dev->phys_shared_area_addr) {
2103 /*prepare the output parameters in the struct */
2104 command_args.offset = command_args.physical_address - sep_dev->phys_shared_area_addr;
2106 edbg("SEP Driver:physical_address is %08lx, offset is %lu\n", command_args.physical_address, command_args.offset);
2108 /* send the parameters to user application */
2109 error = copy_to_user((void *) arg, &command_args, sizeof(struct sep_driver_get_mapped_offset_t));
2111 dbg("SEP Driver:<-------- sep_get_physical_mapped_offset_handler end\n");
2119 static int sep_start_handler(void)
2121 unsigned long reg_val;
2122 unsigned long error = 0;
2124 dbg("SEP Driver:--------> sep_start_handler start\n");
2126 /* wait in polling for message from SEP */
2128 reg_val = sep_read_reg(sep_dev, HW_HOST_SEP_HOST_GPR3_REG_ADDR);
2131 /* check the value */
2133 /* fatal error - read erro status from GPRO */
2134 error = sep_read_reg(sep_dev, HW_HOST_SEP_HOST_GPR0_REG_ADDR);
2135 dbg("SEP Driver:<-------- sep_start_handler end\n");
2140 this function handles the request for SEP initialization
2142 static int sep_init_handler(unsigned long arg)
2144 unsigned long message_word;
2145 unsigned long *message_ptr;
2146 struct sep_driver_init_t command_args;
2147 unsigned long counter;
2148 unsigned long error;
2149 unsigned long reg_val;
2151 dbg("SEP Driver:--------> sep_init_handler start\n");
2154 error = copy_from_user(&command_args, (void *) arg, sizeof(struct sep_driver_init_t));
2156 dbg("SEP Driver:--------> sep_init_handler - finished copy_from_user \n");
2161 /* PATCH - configure the DMA to single -burst instead of multi-burst */
2162 /*sep_configure_dma_burst(); */
2164 dbg("SEP Driver:--------> sep_init_handler - finished sep_configure_dma_burst \n");
2166 message_ptr = (unsigned long *) command_args.message_addr;
2168 /* set the base address of the SRAM */
2169 sep_write_reg(sep_dev, HW_SRAM_ADDR_REG_ADDR, HW_CC_SRAM_BASE_ADDRESS);
2171 for (counter = 0; counter < command_args.message_size_in_words; counter++, message_ptr++) {
2172 get_user(message_word, message_ptr);
2173 /* write data to SRAM */
2174 sep_write_reg(sep_dev, HW_SRAM_DATA_REG_ADDR, message_word);
2175 edbg("SEP Driver:message_word is %lu\n", message_word);
2176 /* wait for write complete */
2177 sep_wait_sram_write(sep_dev);
2179 dbg("SEP Driver:--------> sep_init_handler - finished getting messages from user space\n");
2181 sep_write_reg(sep_dev, HW_HOST_HOST_SEP_GPR0_REG_ADDR, 0x1);
2184 reg_val = sep_read_reg(sep_dev, HW_HOST_SEP_HOST_GPR3_REG_ADDR);
2185 while (!(reg_val & 0xFFFFFFFD));
2187 dbg("SEP Driver:--------> sep_init_handler - finished waiting for reg_val & 0xFFFFFFFD \n");
2189 /* check the value */
2190 if (reg_val == 0x1) {
2191 edbg("SEP Driver:init failed\n");
2193 error = sep_read_reg(sep_dev, 0x8060);
2194 edbg("SEP Driver:sw monitor is %lu\n", error);
2196 /* fatal error - read erro status from GPRO */
2197 error = sep_read_reg(sep_dev, HW_HOST_SEP_HOST_GPR0_REG_ADDR);
2198 edbg("SEP Driver:error is %lu\n", error);
2201 dbg("SEP Driver:<-------- sep_init_handler end\n");
2207 this function handles the request cache and resident reallocation
2209 static int sep_realloc_cache_resident_handler(unsigned long arg)
2212 unsigned long phys_cache_address;
2213 unsigned long phys_resident_address;
2214 struct sep_driver_realloc_cache_resident_t command_args;
2217 error = copy_from_user(&command_args, (void *) arg, sizeof(struct sep_driver_realloc_cache_resident_t));
2221 /* copy cache and resident to the their intended locations */
2222 error = sep_copy_cache_resident_to_area(command_args.cache_addr, command_args.cache_size_in_bytes, command_args.resident_addr, command_args.resident_size_in_bytes, &phys_cache_address, &phys_resident_address);
2226 /* lock the area (if needed) */
2227 sep_lock_cache_resident_area();
2229 command_args.new_base_addr = sep_dev->phys_shared_area_addr;
2231 /* find the new base address according to the lowest address between
2232 cache, resident and shared area */
2233 if (phys_resident_address < command_args.new_base_addr)
2234 command_args.new_base_addr = phys_resident_address;
2235 if (phys_cache_address < command_args.new_base_addr)
2236 command_args.new_base_addr = phys_cache_address;
2238 /* set the return parameters */
2239 command_args.new_cache_addr = phys_cache_address;
2240 command_args.new_resident_addr = phys_resident_address;
2242 /* set the new shared area */
2243 command_args.new_shared_area_addr = sep_dev->phys_shared_area_addr;
2245 edbg("SEP Driver:command_args.new_shared_area_addr is %08lx\n", command_args.new_shared_area_addr);
2246 edbg("SEP Driver:command_args.new_base_addr is %08lx\n", command_args.new_base_addr);
2247 edbg("SEP Driver:command_args.new_resident_addr is %08lx\n", command_args.new_resident_addr);
2248 edbg("SEP Driver:command_args.new_cache_addr is %08lx\n", command_args.new_cache_addr);
2250 /* return to user */
2251 error = copy_to_user((void *) arg, (void *) &command_args, sizeof(struct sep_driver_realloc_cache_resident_t));
2257 this function handles the request for get time
2259 static int sep_get_time_handler(unsigned long arg)
2262 struct sep_driver_get_time_t command_args;
2264 error = sep_set_time(&command_args.time_physical_address, &command_args.time_value);
2265 error = copy_to_user((void *) arg, (void *) &command_args, sizeof(struct sep_driver_get_time_t));
2271 This api handles the setting of API mode to blocking or non-blocking
2273 static int sep_set_api_mode_handler(unsigned long arg)
2276 unsigned long mode_flag;
2278 dbg("SEP Driver:--------> sep_set_api_mode_handler start\n");
2280 error = get_user(mode_flag, &(((struct sep_driver_set_api_mode_t *) arg)->mode));
2284 /* set the global flag */
2285 sep_dev->block_mode_flag = mode_flag;
2287 dbg("SEP Driver:<-------- sep_set_api_mode_handler end\n");
2292 This API handles the end transaction request
2294 static int sep_end_transaction_handler(unsigned long arg)
2296 dbg("SEP Driver:--------> sep_end_transaction_handler start\n");
2298 #if 0 /*!SEP_DRIVER_POLLING_MODE */
2300 sep_write_reg(sep_dev, HW_HOST_IMR_REG_ADDR, 0x7FFF);
2302 /* release IRQ line */
2303 free_irq(SEP_DIRVER_IRQ_NUM, &sep_dev->reg_base_address);
2305 /* lock the sep mutex */
2306 mutex_unlock(&sep_mutex);
2309 dbg("SEP Driver:<-------- sep_end_transaction_handler end\n");
2314 /* handler for flow done interrupt */
2315 static void sep_flow_done_handler(struct work_struct *work)
2317 struct sep_flow_context_t *flow_data_ptr;
2319 /* obtain the mutex */
2320 mutex_lock(&sep_mutex);
2322 /* get the pointer to context */
2323 flow_data_ptr = (struct sep_flow_context_t *) work;
2325 /* free all the current input tables in sep */
2326 sep_deallocated_flow_tables(&flow_data_ptr->input_tables_in_process);
2328 /* free all the current tables output tables in SEP (if needed) */
2329 if (flow_data_ptr->output_tables_in_process.physical_address != 0xffffffff)
2330 sep_deallocated_flow_tables(&flow_data_ptr->output_tables_in_process);
2332 /* check if we have additional tables to be sent to SEP only input
2333 flag may be checked */
2334 if (flow_data_ptr->input_tables_flag) {
2335 /* copy the message to the shared RAM and signal SEP */
2336 memcpy((void *) flow_data_ptr->message, (void *) sep_dev->shared_area_addr, flow_data_ptr->message_size_in_bytes);
2338 sep_write_reg(sep_dev, HW_HOST_HOST_SEP_GPR2_REG_ADDR, 0x2);
2340 mutex_unlock(&sep_mutex);
2345 This function creates a list of tables for flow and returns the data for
2346 the first and last tables of the list
2348 static int sep_prepare_flow_dma_tables(unsigned long num_virtual_buffers,
2349 unsigned long first_buff_addr, struct sep_flow_context_t *flow_data_ptr, struct sep_lli_entry_t *first_table_data_ptr, struct sep_lli_entry_t *last_table_data_ptr, bool isKernelVirtualAddress)
2352 unsigned long virt_buff_addr;
2353 unsigned long virt_buff_size;
2354 struct sep_lli_entry_t table_data;
2355 struct sep_lli_entry_t *info_entry_ptr;
2356 struct sep_lli_entry_t *prev_info_entry_ptr;
2361 prev_info_entry_ptr = 0;
2363 /* init the first table to default */
2364 table_data.physical_address = 0xffffffff;
2365 first_table_data_ptr->physical_address = 0xffffffff;
2366 table_data.block_size = 0;
2368 for (i = 0; i < num_virtual_buffers; i++) {
2369 /* get the virtual buffer address */
2370 error = get_user(virt_buff_addr, &first_buff_addr);
2374 /* get the virtual buffer size */
2376 error = get_user(virt_buff_size, &first_buff_addr);
2380 /* advance the address to point to the next pair of address|size */
2383 /* now prepare the one flow LLI table from the data */
2384 error = sep_prepare_one_flow_dma_table(virt_buff_addr, virt_buff_size, &table_data, &info_entry_ptr, flow_data_ptr, isKernelVirtualAddress);
2389 /* if this is the first table - save it to return to the user
2391 *first_table_data_ptr = table_data;
2393 /* set the pointer to info entry */
2394 prev_info_entry_ptr = info_entry_ptr;
2396 /* not first table - the previous table info entry should
2398 prev_info_entry_ptr->block_size = (0x1 << SEP_INT_FLAG_OFFSET_IN_BITS) | (table_data.block_size);
2400 /* set the pointer to info entry */
2401 prev_info_entry_ptr = info_entry_ptr;
2405 /* set the last table data */
2406 *last_table_data_ptr = table_data;
2413 This function creates one DMA table for flow and returns its data,
2414 and pointer to its info entry
2416 static int sep_prepare_one_flow_dma_table(unsigned long virt_buff_addr, unsigned long virt_buff_size, struct sep_lli_entry_t *table_data, struct sep_lli_entry_t **info_entry_ptr, struct sep_flow_context_t *flow_data_ptr, bool isKernelVirtualAddress)
2419 /* the range in pages */
2420 unsigned long lli_array_size;
2421 struct sep_lli_entry_t *lli_array;
2422 struct sep_lli_entry_t *flow_dma_table_entry_ptr;
2423 unsigned long *start_dma_table_ptr;
2424 /* total table data counter */
2425 unsigned long dma_table_data_count;
2426 /* pointer that will keep the pointer to the pages of the virtual buffer */
2427 struct page **page_array_ptr;
2428 unsigned long entry_count;
2430 /* find the space for the new table */
2431 error = sep_find_free_flow_dma_table_space(&start_dma_table_ptr);
2435 /* check if the pages are in Kernel Virtual Address layout */
2436 if (isKernelVirtualAddress == true)
2437 /* lock kernel buffer in the memory */
2438 error = sep_lock_kernel_pages(virt_buff_addr, virt_buff_size, &lli_array_size, &lli_array, &page_array_ptr);
2440 /* lock user buffer in the memory */
2441 error = sep_lock_user_pages(virt_buff_addr, virt_buff_size, &lli_array_size, &lli_array, &page_array_ptr);
2446 /* set the pointer to page array at the beginning of table - this table is
2447 now considered taken */
2448 *start_dma_table_ptr = lli_array_size;
2450 /* point to the place of the pages pointers of the table */
2451 start_dma_table_ptr++;
2453 /* set the pages pointer */
2454 *start_dma_table_ptr = (unsigned long) page_array_ptr;
2456 /* set the pointer to the first entry */
2457 flow_dma_table_entry_ptr = (struct sep_lli_entry_t *) (++start_dma_table_ptr);
2459 /* now create the entries for table */
2460 for (dma_table_data_count = entry_count = 0; entry_count < lli_array_size; entry_count++) {
2461 flow_dma_table_entry_ptr->physical_address = lli_array[entry_count].physical_address;
2463 flow_dma_table_entry_ptr->block_size = lli_array[entry_count].block_size;
2465 /* set the total data of a table */
2466 dma_table_data_count += lli_array[entry_count].block_size;
2468 flow_dma_table_entry_ptr++;
2471 /* set the physical address */
2472 table_data->physical_address = virt_to_phys(start_dma_table_ptr);
2474 /* set the num_entries and total data size */
2475 table_data->block_size = ((lli_array_size + 1) << SEP_NUM_ENTRIES_OFFSET_IN_BITS) | (dma_table_data_count);
2477 /* set the info entry */
2478 flow_dma_table_entry_ptr->physical_address = 0xffffffff;
2479 flow_dma_table_entry_ptr->block_size = 0;
2481 /* set the pointer to info entry */
2482 *info_entry_ptr = flow_dma_table_entry_ptr;
2484 /* the array of the lli entries */
2492 This function returns pointer to the flow data structure
2493 that contains the given id
2495 static int sep_find_flow_context(unsigned long flow_id, struct sep_flow_context_t **flow_data_ptr)
2497 unsigned long count;
2501 always search for flow with id default first - in case we
2502 already started working on the flow there can be no situation
2503 when 2 flows are with default flag
2505 for (count = 0; count < SEP_DRIVER_NUM_FLOWS; count++) {
2506 if (sep_dev->flows_data_array[count].flow_id == flow_id) {
2507 *flow_data_ptr = &sep_dev->flows_data_array[count];
2512 if (count == SEP_DRIVER_NUM_FLOWS)
2520 this function find a space for the new flow dma table
2522 static int sep_find_free_flow_dma_table_space(unsigned long **table_address_ptr)
2525 /* pointer to the id field of the flow dma table */
2526 unsigned long *start_table_ptr;
2527 unsigned long flow_dma_area_start_addr;
2528 unsigned long flow_dma_area_end_addr;
2529 /* maximum table size in words */
2530 unsigned long table_size_in_words;
2532 /* find the start address of the flow DMA table area */
2533 flow_dma_area_start_addr = sep_dev->shared_area_addr + SEP_DRIVER_FLOW_DMA_TABLES_AREA_OFFSET_IN_BYTES;
2535 /* set end address of the flow table area */
2536 flow_dma_area_end_addr = flow_dma_area_start_addr + SEP_DRIVER_FLOW_DMA_TABLES_AREA_SIZE_IN_BYTES;
2538 /* set table size in words */
2539 table_size_in_words = SEP_DRIVER_MAX_FLOW_NUM_ENTRIES_IN_TABLE * (sizeof(struct sep_lli_entry_t) / sizeof(long)) + 2;
2541 /* set the pointer to the start address of DMA area */
2542 start_table_ptr = (unsigned long *) flow_dma_area_start_addr;
2544 /* find the space for the next table */
2545 while (((*start_table_ptr & 0x7FFFFFFF) != 0) && ((unsigned long) start_table_ptr < flow_dma_area_end_addr))
2546 start_table_ptr += table_size_in_words;
2548 /* check if we reached the end of floa tables area */
2549 if ((unsigned long) start_table_ptr >= flow_dma_area_end_addr)
2552 *table_address_ptr = start_table_ptr;
2558 this function goes over all the flow tables connected to the given
2559 table and deallocate them
2561 static void sep_deallocated_flow_tables(struct sep_lli_entry_t *first_table_ptr)
2564 unsigned long *table_ptr;
2565 /* end address of the flow dma area */
2566 unsigned long num_entries;
2567 unsigned long num_pages;
2568 struct page **pages_ptr;
2569 /* maximum table size in words */
2570 struct sep_lli_entry_t *info_entry_ptr;
2572 /* set the pointer to the first table */
2573 table_ptr = (unsigned long *) first_table_ptr->physical_address;
2575 /* set the num of entries */
2576 num_entries = (first_table_ptr->block_size >> SEP_NUM_ENTRIES_OFFSET_IN_BITS)
2577 & SEP_NUM_ENTRIES_MASK;
2579 /* go over all the connected tables */
2580 while (*table_ptr != 0xffffffff) {
2581 /* get number of pages */
2582 num_pages = *(table_ptr - 2);
2584 /* get the pointer to the pages */
2585 pages_ptr = (struct page **) (*(table_ptr - 1));
2587 /* free the pages */
2588 sep_free_dma_pages(pages_ptr, num_pages, 1);
2590 /* goto to the info entry */
2591 info_entry_ptr = ((struct sep_lli_entry_t *) table_ptr) + (num_entries - 1);
2593 table_ptr = (unsigned long *) info_entry_ptr->physical_address;
2594 num_entries = (info_entry_ptr->block_size >> SEP_NUM_ENTRIES_OFFSET_IN_BITS) & SEP_NUM_ENTRIES_MASK;
2601 This function handler the set flow id command
2603 static int sep_set_flow_id_handler(unsigned long arg)
2606 unsigned long flow_id;
2607 struct sep_flow_context_t *flow_data_ptr;
2609 dbg("------------>SEP Driver: sep_set_flow_id_handler start\n");
2611 error = get_user(flow_id, &(((struct sep_driver_set_flow_id_t *) arg)->flow_id));
2615 /* find the flow data structure that was just used for creating new flow
2616 - its id should be default */
2617 error = sep_find_flow_context(SEP_TEMP_FLOW_ID, &flow_data_ptr);
2622 flow_data_ptr->flow_id = flow_id;
2625 dbg("SEP Driver:<-------- sep_set_flow_id_handler end\n");
2631 calculates time and sets it at the predefined address
2633 static int sep_set_time(unsigned long *address_ptr, unsigned long *time_in_sec_ptr)
2635 struct timeval time;
2636 /* address of time in the kernel */
2637 unsigned long time_addr;
2640 dbg("SEP Driver:--------> sep_set_time start\n");
2642 do_gettimeofday(&time);
2644 /* set value in the SYSTEM MEMORY offset */
2645 time_addr = sep_dev->message_shared_area_addr + SEP_DRIVER_SYSTEM_TIME_MEMORY_OFFSET_IN_BYTES;
2647 *(unsigned long *) time_addr = SEP_TIME_VAL_TOKEN;
2648 *(unsigned long *) (time_addr + 4) = time.tv_sec;
2650 edbg("SEP Driver:time.tv_sec is %lu\n", time.tv_sec);
2651 edbg("SEP Driver:time_addr is %lu\n", time_addr);
2652 edbg("SEP Driver:g_message_shared_area_addr is %lu\n", sep_dev->message_shared_area_addr);
2654 /* set the output parameters if needed */
2656 *address_ptr = sep_shared_area_virt_to_phys(time_addr);
2658 if (time_in_sec_ptr)
2659 *time_in_sec_ptr = time.tv_sec;
2661 dbg("SEP Driver:<-------- sep_set_time end\n");
2666 static void sep_wait_busy(struct sep_device *dev)
2671 reg = sep_read_reg(sep_dev, HW_HOST_SEP_BUSY_REG_ADDR);
2676 PATCH for configuring the DMA to single burst instead of multi-burst
2678 static void sep_configure_dma_burst(void)
2680 #define HW_AHB_RD_WR_BURSTS_REG_ADDR 0x0E10UL
2682 dbg("SEP Driver:<-------- sep_configure_dma_burst start \n");
2684 /* request access to registers from SEP */
2685 sep_write_reg(sep_dev, HW_HOST_HOST_SEP_GPR0_REG_ADDR, 0x2);
2687 dbg("SEP Driver:<-------- sep_configure_dma_burst finished request access to registers from SEP (write reg) \n");
2689 sep_wait_busy(sep_dev);
2691 dbg("SEP Driver:<-------- sep_configure_dma_burst finished request access to registers from SEP (while(revVal) wait loop) \n");
2693 /* set the DMA burst register to single burst */
2694 sep_write_reg(sep_dev, HW_AHB_RD_WR_BURSTS_REG_ADDR, 0x0UL);
2696 /* release the sep busy */
2697 sep_write_reg(sep_dev, HW_HOST_HOST_SEP_GPR0_REG_ADDR, 0x0UL);
2698 sep_wait_busy(sep_dev);
2700 dbg("SEP Driver:<-------- sep_configure_dma_burst done \n");
2705 function that is activaed on the succesfull probe of the SEP device
2707 static int __devinit sep_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
2711 edbg("Sep pci probe starting\n");
2713 /* enable the device */
2714 error = pci_enable_device(pdev);
2716 edbg("error enabling pci device\n");
2720 /* set the pci dev pointer */
2721 sep_dev->sep_pci_dev_ptr = pdev;
2723 /* get the io memory start address */
2724 sep_dev->io_memory_start_physical_address = pci_resource_start(pdev, 0);
2725 if (!sep_dev->io_memory_start_physical_address) {
2726 edbg("SEP Driver error pci resource start\n");
2730 /* get the io memory end address */
2731 sep_dev->io_memory_end_physical_address = pci_resource_end(pdev, 0);
2732 if (!sep_dev->io_memory_end_physical_address) {
2733 edbg("SEP Driver error pci resource end\n");
2737 sep_dev->io_memory_size = sep_dev->io_memory_end_physical_address - sep_dev->io_memory_start_physical_address + 1;
2739 edbg("SEP Driver:io_memory_start_physical_address is %08lx\n", sep_dev->io_memory_start_physical_address);
2741 edbg("SEP Driver:io_memory_end_phyaical_address is %08lx\n", sep_dev->io_memory_end_physical_address);
2743 edbg("SEP Driver:io_memory_size is %08lx\n", sep_dev->io_memory_size);
2745 sep_dev->io_memory_start_virtual_address = ioremap_nocache(sep_dev->io_memory_start_physical_address, sep_dev->io_memory_size);
2746 if (!sep_dev->io_memory_start_virtual_address) {
2747 edbg("SEP Driver error ioremap of io memory\n");
2751 edbg("SEP Driver:io_memory_start_virtual_address is %p\n", sep_dev->io_memory_start_virtual_address);
2753 sep_dev->reg_base_address = (void __iomem *) sep_dev->io_memory_start_virtual_address;
2756 /* set up system base address and shared memory location */
2758 sep_dev->rar_virtual_address = kmalloc(2 * SEP_RAR_IO_MEM_REGION_SIZE, GFP_KERNEL);
2760 if (!sep_dev->rar_virtual_address) {
2761 edbg("SEP Driver:cant kmalloc rar\n");
2765 sep_dev->rar_physical_address = __pa(sep_dev->rar_virtual_address);
2767 edbg("SEP Driver:rar_physical is %08lx\n", sep_dev->rar_physical_address);
2768 edbg("SEP Driver:rar_virtual is %p\n", sep_dev->rar_virtual_address);
2770 #if !SEP_DRIVER_POLLING_MODE
2772 edbg("SEP Driver: about to write IMR and ICR REG_ADDR\n");
2774 /* clear ICR register */
2775 sep_write_reg(sep_dev, HW_HOST_ICR_REG_ADDR, 0xFFFFFFFF);
2777 /* set the IMR register - open only GPR 2 */
2778 sep_write_reg(sep_dev, HW_HOST_IMR_REG_ADDR, (~(0x1 << 13)));
2780 /* figure out our irq */
2782 error = pci_read_config_byte(pdev, PCI_INTERRUPT_LINE, (u8 *) & sep_dev->sep_irq);
2784 edbg("SEP Driver: my irq is %d\n", sep_irq);
2786 edbg("SEP Driver: about to call request_irq\n");
2787 /* get the interrupt line */
2788 error = request_irq(sep_irq, sep_inthandler, IRQF_SHARED, "sep_driver", &sep_dev->reg_base_address);
2793 edbg("SEP Driver: about to write IMR REG_ADDR");
2795 /* set the IMR register - open only GPR 2 */
2796 sep_write_reg(sep_dev, HW_HOST_IMR_REG_ADDR, (~(0x1 << 13)));
2798 #endif /* SEP_DRIVER_POLLING_MODE */
2803 static struct pci_device_id sep_pci_id_tbl[] = {
2804 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x080c)},
2808 MODULE_DEVICE_TABLE(pci, sep_pci_id_tbl);
2810 /* field for registering driver to PCI device */
2811 static struct pci_driver sep_pci_driver = {
2812 .name = "sep_sec_driver",
2813 .id_table = sep_pci_id_tbl,
2818 this function registers th driver to
2819 the device subsystem( either PCI, USB, etc)
2821 int sep_register_driver_to_device(void)
2823 return pci_register_driver(&sep_pci_driver);
2828 /* major and minor device numbers */
2829 static dev_t sep_devno;
2831 /* the files operations structure of the driver */
2832 static struct file_operations sep_file_operations = {
2833 .owner = THIS_MODULE,
2837 .release = sep_release,
2842 /* cdev struct of the driver */
2843 static struct cdev sep_cdev;
2846 this function registers the driver to the file system
2848 static int sep_register_driver_to_fs(void)
2850 int ret_val = alloc_chrdev_region(&sep_devno, 0, 1, "sep_sec_driver");
2852 edbg("sep_driver:major number allocation failed, retval is %d\n", ret_val);
2857 cdev_init(&sep_cdev, &sep_file_operations);
2858 sep_cdev.owner = THIS_MODULE;
2860 /* register the driver with the kernel */
2861 ret_val = cdev_add(&sep_cdev, sep_devno, 1);
2864 edbg("sep_driver:cdev_add failed, retval is %d\n", ret_val);
2865 goto end_function_unregister_devnum;
2870 end_function_unregister_devnum:
2872 /* unregister dev numbers */
2873 unregister_chrdev_region(sep_devno, 1);
2880 this function unregisters driver from fs
2882 static void sep_unregister_driver_from_fs(void)
2884 cdev_del(&sep_cdev);
2885 /* unregister dev numbers */
2886 unregister_chrdev_region(sep_devno, 1);
2890 /*--------------------------------------------------------------
2892 ----------------------------------------------------------------*/
2893 static int __init sep_init(void)
2897 int size; /* size of memory for allocation */
2899 dbg("SEP Driver:-------->Init start\n");
2900 edbg("sep->shared_area_addr = %lx\n", (unsigned long) &sep_dev->shared_area_addr);
2902 /* transaction counter that coordinates the transactions between SEP
2904 sep_dev->host_to_sep_send_counter = 0;
2906 /* counter for the messages from sep */
2907 sep_dev->sep_to_host_reply_counter = 0;
2909 /* counter for the number of bytes allocated in the pool
2910 for the current transaction */
2911 sep_dev->data_pool_bytes_allocated = 0;
2913 /* set the starting mode to blocking */
2914 sep_dev->block_mode_flag = 1;
2916 ret_val = sep_register_driver_to_device();
2918 edbg("sep_driver:sep_driver_to_device failed, ret_val is %d\n", ret_val);
2919 goto end_function_unregister_from_fs;
2921 /* calculate the total size for allocation */
2922 size = SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES +
2923 SEP_DRIVER_SYNCHRONIC_DMA_TABLES_AREA_SIZE_IN_BYTES + SEP_DRIVER_DATA_POOL_SHARED_AREA_SIZE_IN_BYTES + SEP_DRIVER_FLOW_DMA_TABLES_AREA_SIZE_IN_BYTES + SEP_DRIVER_STATIC_AREA_SIZE_IN_BYTES + SEP_DRIVER_SYSTEM_DATA_MEMORY_SIZE_IN_BYTES;
2925 /* allocate the shared area */
2926 if (sep_map_and_alloc_shared_area(size, &sep_dev->shared_area_addr, &sep_dev->phys_shared_area_addr)) {
2928 /* allocation failed */
2929 goto end_function_unmap_io_memory;
2931 /* now set the memory regions */
2932 sep_dev->message_shared_area_addr = sep_dev->shared_area_addr;
2934 edbg("SEP Driver: g_message_shared_area_addr is %08lx\n", sep_dev->message_shared_area_addr);
2936 #if (SEP_DRIVER_RECONFIG_MESSAGE_AREA == 1)
2937 /* send the new SHARED MESSAGE AREA to the SEP */
2938 sep_write_reg(sep_dev, HW_HOST_HOST_SEP_GPR1_REG_ADDR, sep_dev->phys_shared_area_addr);
2940 /* poll for SEP response */
2941 retVal = sep_read_reg(sep_dev, HW_HOST_SEP_HOST_GPR1_REG_ADDR);
2942 while (retVal != 0xffffffff && retVal != sep_dev->phys_shared_area_addr)
2943 retVal = sep_read_reg(sep_dev, HW_HOST_SEP_HOST_GPR1_REG_ADDR);
2945 /* check the return value (register) */
2946 if (retVal != sep_dev->phys_shared_area_addr) {
2948 goto end_function_deallocate_message_area;
2951 /* init the flow contextes */
2952 for (counter = 0; counter < SEP_DRIVER_NUM_FLOWS; counter++)
2953 sep_dev->flows_data_array[counter].flow_id = SEP_FREE_FLOW_ID;
2955 sep_dev->flow_wq_ptr = create_singlethread_workqueue("sepflowwq");
2956 if (sep_dev->flow_wq_ptr == 0) {
2958 edbg("sep_driver:flow queue creation failed\n");
2959 goto end_function_deallocate_sep_shared_area;
2961 edbg("SEP Driver: create flow workqueue \n");
2963 /* register driver to fs */
2964 ret_val = sep_register_driver_to_fs();
2966 goto end_function_deallocate_sep_shared_area;
2967 /* load the rom code */
2968 sep_load_rom_code();
2970 end_function_unregister_from_fs:
2971 /* unregister from fs */
2972 sep_unregister_driver_from_fs();
2973 end_function_deallocate_sep_shared_area:
2974 /* de-allocate shared area */
2975 sep_unmap_and_free_shared_area(size, sep_dev->shared_area_addr, sep_dev->phys_shared_area_addr);
2976 end_function_unmap_io_memory:
2977 iounmap((void *) sep_dev->reg_base_address);
2978 /* release io memory region */
2979 release_mem_region(SEP_IO_MEM_REGION_START_ADDRESS, SEP_IO_MEM_REGION_SIZE);
2981 dbg("SEP Driver:<-------- Init end\n");
2986 /*-------------------------------------------------------------
2988 --------------------------------------------------------------*/
2989 static void __exit sep_exit(void)
2993 dbg("SEP Driver:--------> Exit start\n");
2995 /* unregister from fs */
2996 sep_unregister_driver_from_fs();
2997 /* calculate the total size for de-allocation */
2998 size = SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES +
2999 SEP_DRIVER_SYNCHRONIC_DMA_TABLES_AREA_SIZE_IN_BYTES + SEP_DRIVER_DATA_POOL_SHARED_AREA_SIZE_IN_BYTES + SEP_DRIVER_FLOW_DMA_TABLES_AREA_SIZE_IN_BYTES + SEP_DRIVER_STATIC_AREA_SIZE_IN_BYTES + SEP_DRIVER_SYSTEM_DATA_MEMORY_SIZE_IN_BYTES;
3000 /* free shared area */
3001 sep_unmap_and_free_shared_area(size, sep_dev->shared_area_addr, sep_dev->phys_shared_area_addr);
3002 edbg("SEP Driver: free pages SEP SHARED AREA \n");
3003 iounmap((void *) sep_dev->reg_base_address);
3004 edbg("SEP Driver: iounmap \n");
3005 /* release io memory region */
3006 release_mem_region(SEP_IO_MEM_REGION_START_ADDRESS, SEP_IO_MEM_REGION_SIZE);
3007 edbg("SEP Driver: release_mem_region \n");
3008 dbg("SEP Driver:<-------- Exit end\n");
3012 module_init(sep_init);
3013 module_exit(sep_exit);
3015 MODULE_LICENSE("GPL");