1353 lines
42 KiB
C
1353 lines
42 KiB
C
|
|
/****************************************************************************
|
|
* Sec2Driver.h - Private/local include file for SEC2 security driver
|
|
****************************************************************************
|
|
* Copyright (c) 2003, 2004 Freescale Semiconductor
|
|
* All Rights Reserved. Proprietary and Confidential.
|
|
*
|
|
* NOTICE: The information contained in this file is proprietary
|
|
* to Freescale Semiconductor, and is being made available to
|
|
* Freescale's customers under strict license agreements.
|
|
* Use or disclosure of this information is permissible only
|
|
* under the terms of the existing license agreement.
|
|
***************************************************************************/
|
|
|
|
|
|
/* Revision History:
|
|
* 1.0 Aug 24,2003 dgs adapted from the final version of mpc18x
|
|
* May 12,2004 sec - moved interrupt assign for MPC8555
|
|
* May 26,2004 sec - add support for scatter buffers
|
|
* Aug 27,2004 sec - fixed channel interrupt masks
|
|
* 1.1.0 Nov 05,2004 sec - integrate/merge linux changes from prior revs
|
|
* 1.2 Jan 27,2005 sec - move global inhibit bit
|
|
*/
|
|
|
|
#ifndef SEC2DRIVER_H
|
|
#define SEC2DRIVER_H
|
|
|
|
#ifdef __KERNEL__
|
|
#include <linux/module.h>
|
|
/* Interpeak begin */
|
|
#include <linux/init.h>
|
|
/* Interpeak end */
|
|
#include <linux/config.h>
|
|
#include <linux/kernel.h>
|
|
#include <linux/slab.h>
|
|
#include <linux/interrupt.h>
|
|
#include <linux/delay.h>
|
|
#include <linux/list.h>
|
|
#include <linux/spinlock.h>
|
|
#include <asm/uaccess.h>
|
|
#include <asm/atomic.h>
|
|
#include <asm/semaphore.h>
|
|
#include <asm/irq.h>
|
|
#include <asm/page.h>
|
|
#include <asm/io.h>
|
|
|
|
#undef malloc
|
|
#undef free
|
|
#define free kfree
|
|
#define malloc(a) kmalloc(a, GFP_KERNEL)
|
|
#undef semGive
|
|
#undef semTake
|
|
#define semDelete(x)
|
|
#define semGive(a) up(&a)
|
|
#define semTake(a, b) down_interruptible_timeout(&a, b)
|
|
|
|
extern long __down_interruptible_timeout(struct semaphore *sem, long timeout);
|
|
extern inline int down_interruptible_timeout(struct semaphore *sem, long timeout)
|
|
{
|
|
int ret = 0;
|
|
#if WAITQUEUE_DEBUG
|
|
CHECK_MAGIC(sem->__magic);
|
|
#endif
|
|
|
|
if (atomic_dec_return(&sem->count) < 0)
|
|
ret = __down_interruptible_timeout(sem, timeout);
|
|
|
|
smp_wmb();
|
|
return ret;
|
|
}
|
|
|
|
#define taskIdSelf() current->pid
|
|
#define __vpa(va) ((pte_val(*pte_offset(pmd_offset(pgd_offset_k(va), (va)), (va))) & PAGE_MASK) + (va & ~PAGE_MASK))
|
|
#define SEC2_DEVMAJOR 0
|
|
#else /* assume VXWORKS */
|
|
|
|
#include "vxWorks.h"
|
|
#include "iosLib.h"
|
|
#include "msgQLib.h"
|
|
#include "stdlib.h"
|
|
#include "semLib.h"
|
|
#include "time.h"
|
|
#include "string.h"
|
|
#include "taskLib.h"
|
|
#include "cacheLib.h"
|
|
#include "signal.h"
|
|
|
|
#define IVEC_TO_INUM(intVec) ((int) (intVec))
|
|
#define INUM_TO_IVEC(intNum) ((VOIDFUNCPTR *) (intNum))
|
|
|
|
#define __vpa(pa) (pa)
|
|
#endif
|
|
|
|
|
|
#include "Sec2.h"
|
|
|
|
#define VERSION "1.2"
|
|
|
|
#define SEC2_DEVNAME "sec2"
|
|
|
|
/* This might move out to a board-specfic header somewhere, */
|
|
/* not a core-specific header such as this */
|
|
#define INUM_SEC2 0x29 /* SEC core is wired to #29 within the MPC8555 */
|
|
|
|
/* Define an offset from the peripheral base register where the core */
|
|
/* should be located relative to */
|
|
#define TALITOS2X_BASE_ADDRESS (0x00030000)
|
|
|
|
/* Define the size of the register region */
|
|
#define SEC2_BASE_SIZE (0x10000)
|
|
|
|
|
|
/* When static scatter pool fully functional, define here */
|
|
/* Else, use dynamic pool */
|
|
#define DYNAMIC_SCATTER_POOL
|
|
|
|
|
|
/* Do right-justifies output shift for PKHA results due to errata */
|
|
#define PKHA_OUTPUT_SHIFT
|
|
|
|
/* Interpeak begin */
|
|
#ifdef __KERNEL__
|
|
typedef struct Ctx_queue_element_struct
|
|
{
|
|
struct Ctx_queue_element_struct *next;
|
|
int pid;
|
|
void *ctx;
|
|
}
|
|
Ctx_queue_element;
|
|
|
|
|
|
typedef struct Ctx_queue_header_struct
|
|
{
|
|
Ctx_queue_element *head;
|
|
Ctx_queue_element *tail;
|
|
}
|
|
Ctx_queue_header;
|
|
|
|
extern Ctx_queue_header ctx_done_queue;
|
|
extern Ctx_queue_header ctx_error_queue;
|
|
|
|
#endif
|
|
/* Interpeak end */
|
|
|
|
|
|
/*
|
|
* Debug message type enabler switches for SEC2DebugLevel:
|
|
* DBGTXT_SETRQ - all messages from request setups
|
|
* DBGTXT_SVCRQ - all messages from request servicing
|
|
* DBGTXT_INITDEV - all messages from initialization
|
|
* DBGTXT_DPDSHOW - content of each DPD before it's queued
|
|
* DBGTXT_INFO - general driver information messages
|
|
*/
|
|
|
|
#ifdef DBG
|
|
#define DBGTXT_SETRQ ((unsigned long)0x00000001)
|
|
#define DBGTXT_SVCRQ ((unsigned long)0x00000002)
|
|
#define DBGTXT_INITDEV ((unsigned long)0x00000004)
|
|
#define DBGTXT_DPDSHOW ((unsigned long)0x00000008)
|
|
#define DBGTXT_INFO ((unsigned long)0x00000010)
|
|
/* Interpeak begin */
|
|
#define DBGTXT_INTERPEAK ((unsigned long)0x00000020)
|
|
/* Interpeak end */
|
|
extern unsigned long SEC2DebugLevel;
|
|
|
|
#ifdef VXWORKS
|
|
#define SEC2Dump(LEVEL,STRING) \
|
|
do { \
|
|
unsigned long _level = (LEVEL); \
|
|
if ((_level == 0)||(SEC2DebugLevel & _level)) { \
|
|
printf STRING; \
|
|
} \
|
|
} while (0)
|
|
#else
|
|
#define SEC2Dump(LEVEL,STRING) \
|
|
do { \
|
|
unsigned long _level = (LEVEL); \
|
|
if ((_level == 0)||(SEC2DebugLevel & _level)) { \
|
|
printk STRING; \
|
|
} \
|
|
} while (0)
|
|
#endif
|
|
|
|
|
|
#else /* ndef DBG */
|
|
#define SEC2Dump(LEVEL,STRING)
|
|
#endif /* DBG */
|
|
|
|
|
|
|
|
#ifdef VXWORKS
|
|
#define IOLockChannelAssignment() (void) semTake(ChannelAssignSemId, WAIT_FOREVER)
|
|
#define IOUnLockChannelAssignment() (void) semGive(ChannelAssignSemId)
|
|
#endif
|
|
|
|
#ifdef __KERNEL__
|
|
extern unsigned long irq_flag;
|
|
|
|
#define IOLockChannelAssignment() spin_lock_irqsave(&ChannelAssignLock,irq_flag)
|
|
#define IOUnLockChannelAssignment() spin_unlock_irqrestore(&ChannelAssignLock,irq_flag)
|
|
|
|
#define M_ioLib (12 << 16)
|
|
#define S_ioLib_UNKNOWN_REQUEST (M_ioLib | 2)
|
|
|
|
typedef long DEV_HDR;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#define IO_STATUS int
|
|
#define MAX_DPDS (24)
|
|
/* Interpeak begin */
|
|
/* #define QUEUE_ENTRY_DEPTH (16) */
|
|
#define QUEUE_ENTRY_DEPTH (32)
|
|
/* Interpeak end */
|
|
|
|
/* internal flag for pointer register - indirect pointer */
|
|
#define PTRTYPE_JBIT (0x00008000)
|
|
|
|
|
|
/* SEC2_MASTER_CONTROL_REGISTER - Master Control Register offset */
|
|
#define SEC2_MASTER_CONTROL_REGISTER ((unsigned long)0x00001030)
|
|
|
|
/* SEC2_RESET - software-controller reset of the SEC2 core */
|
|
#define SEC2_RESET ((unsigned long)0x00000001)
|
|
|
|
/* SEC2_GLOBAL_INHIBIT - */
|
|
#define SEC2_GLOBAL_INHIBIT ((unsigned long)0x00000002)
|
|
|
|
|
|
|
|
/*! \def MAX_MESSAGES
|
|
\brief (VxWorks Only) Queue Length for Isr queue represented
|
|
by global variale #IsrMsgQId
|
|
*/
|
|
#define MAX_MESSAGES (40)
|
|
|
|
/*! \def PROCESSING_COMPLETE_PRIORITY
|
|
\brief (VxWorks Only) #ProcessingComplete() Task priority
|
|
*/
|
|
#define PROCESSING_COMPLETE_PRIORITY (3)
|
|
|
|
/*! \def PROCESSING_COMPLETE_STACKSIZE
|
|
\brief (VxWorks Only) #ProcessingComplete() Task stack size
|
|
*/
|
|
/* Interpeak begin */
|
|
/* #define PROCESSING_COMPLETE_STACKSIZE (2048) */
|
|
#define PROCESSING_COMPLETE_STACKSIZE (4096)
|
|
/* Interpeak end */
|
|
|
|
|
|
/*! \def CHANNEL_FREE
|
|
\brief Channel is available
|
|
|
|
Indicates that the channel assignment is FREE or available.
|
|
*/
|
|
#define CHANNEL_FREE (unsigned char) (0)
|
|
/*! \def CHANNEL_DYNAMIC
|
|
\brief Channel is assigned as dynamic
|
|
|
|
Indicates that the channel assignment is dynamic.
|
|
A process is in the middle of performing a dynamic operation.
|
|
*/
|
|
#define CHANNEL_DYNAMIC (unsigned char) (1)
|
|
|
|
/*! \def CHA_DYNAMIC
|
|
\brief The CHA is available for dynamic acquisition
|
|
|
|
This applies to the #ChaAssignments array. Any element in this
|
|
array that is set to CHA_DYNAMIC means that the CHA represented
|
|
by the array index is available
|
|
*/
|
|
#define CHA_DYNAMIC (0)
|
|
|
|
#define CHA_DES (0)
|
|
#define CHA_AESA (1)
|
|
#define CHA_MDHA (2)
|
|
#define CHA_AFHA (3)
|
|
#define CHA_RNG (4)
|
|
#define CHA_PKHA (5)
|
|
#define CHA_MDHA_DES (106)
|
|
#define CHA_MDHA_AES (105)
|
|
|
|
|
|
/*! \def CHA_AFHA_BITMASK
|
|
\brief An internal bitmask representation for an ARC4 CHA
|
|
*/
|
|
#define CHA_AFHA_BITMASK (0x1)
|
|
/*! \def CHA_DESA_BITMASK
|
|
\brief An internal bitmask representation for a DES CHA
|
|
*/
|
|
#define CHA_DESA_BITMASK (0x2)
|
|
/*! \def CHA_MDHA_BITMASK
|
|
\brief An internal bitmask representation for an MD CHA
|
|
*/
|
|
#define CHA_MDHA_BITMASK (0x4)
|
|
/*! \def CHA_RNGA_BITMASK
|
|
\brief An internal bitmask representation for an RNG CHA
|
|
*/
|
|
#define CHA_RNGA_BITMASK (0x8)
|
|
/*! \def CHA_PKHA_BITMASK
|
|
\brief An internal bitmask representation for a PK CHA
|
|
*/
|
|
#define CHA_PKHA_BITMASK (0x10)
|
|
/*! \def CHA_AESA_BITMASK
|
|
\brief An internal bitmask representation for a AESA CHA
|
|
*/
|
|
#define CHA_AESA_BITMASK (0x20)
|
|
/*! \def CHA_KEA_BITMASK
|
|
\brief An internal bitmask representation for a KEA CHA
|
|
*/
|
|
#define CHA_KEA_BITMASK (0x40)
|
|
|
|
|
|
/*! \def DES_BLOCK
|
|
\brief Size of DES block
|
|
*/
|
|
#define DES_BLOCK (8)
|
|
/*! \def ARC4_MIN_KEYBYTES
|
|
\brief Minimum ARC4 key length
|
|
*/
|
|
#define ARC4_MIN_KEYBYTES (1)
|
|
/*! \def ARC4_MAX_KEYBYTES
|
|
\brief Maximum ARC4 key length
|
|
*/
|
|
#define ARC4_MAX_KEYBYTES (16)
|
|
/*! \def ARC4_CONTEXTBYTES
|
|
\brief Context length for ARC4
|
|
*/
|
|
#define ARC4_CONTEXTBYTES (259)
|
|
|
|
/*! \def DOUBLE_WORD_ALIGNMENT
|
|
\brief Mask to be applied to address in order to determine
|
|
if it is double word aligned or not
|
|
*/
|
|
#ifdef NO_DOUBLE_WORD_ALIGNMENT
|
|
#define DOUBLE_WORD_ALIGNMENT ((unsigned long)0x00000000)
|
|
#else
|
|
#define DOUBLE_WORD_ALIGNMENT ((unsigned long)0x00000007)
|
|
#endif
|
|
|
|
/*! \def IO_BASE_ADDRESS_MASK
|
|
\brief Mask to be applied to base address value return from IO
|
|
bus
|
|
*/
|
|
#define IO_BASE_ADDRESS_MASK ((unsigned long)0xFFFE0000)
|
|
|
|
/*! \def INTERRUPT_CONTROL_OFFSET
|
|
\brief Offset for the Interrupt Control Register.
|
|
|
|
This is relative to the base address register for the
|
|
SEC2 coprocessor. It is used to setup the
|
|
#InterruptControlRegister variable during Driver Startup
|
|
*/
|
|
#define INTERRUPT_CONTROL_OFFSET ((unsigned long)0x00001008)
|
|
|
|
/*! \def INTERRUPT_STATUS_OFFSET
|
|
\brief Offset for the Interrupt Status Register.
|
|
|
|
This is relative to the base address register for the
|
|
SEC2 coprocessor. It is used to setup the
|
|
#InterruptStatusRegister variable during Driver Startup
|
|
*/
|
|
#define INTERRUPT_STATUS_OFFSET ((unsigned long)0x00001010)
|
|
|
|
/*! \def INTERRUPT_CLEAR_OFFSET
|
|
\brief Offset for the Interrupt Clear Register.
|
|
|
|
This is relative to the base address register for the
|
|
SEC2 coprocessor. It is used to setup the
|
|
#InterruptClearRegister variable during Driver Startup
|
|
*/
|
|
#define INTERRUPT_CLEAR_OFFSET ((unsigned long)0x00001018)
|
|
|
|
/*! \def IDENTIFICATION_OFFSET
|
|
\brief Offset for the ID Register.
|
|
|
|
This is relative to the base address register for the
|
|
SEC2 coprocessor. It is used to setup the
|
|
#IDRegister variable during Driver Startup
|
|
*/
|
|
#define IDENTIFICATION_OFFSET ((unsigned long)0x00001020)
|
|
|
|
/* Possible core ID mask values */
|
|
/* Least-significant 4 bits may end up as sub-version mask */
|
|
#define SEC_COREID_2_0_0 (0x00000040)
|
|
#define SEC_COREID_2_1_0 (0x00000080)
|
|
|
|
|
|
/*! \def CHA_ASSIGNMENT_STATUS_OFFSET
|
|
\brief Offset for the CHA Assignment Control Register.
|
|
|
|
This is relative to the base address register for the
|
|
SEC2 coprocessor. It is used to setup the
|
|
#ChaAssignmentStatusRegister variable during Driver Startup
|
|
*/
|
|
#define CHA_ASSIGNMENT_STATUS_OFFSET ((unsigned long)0x00001028)
|
|
|
|
/*! \def CHANNEL_CONFIG_BASE
|
|
\brief Base address for the Channel # 1's
|
|
Channel Configuration Register.
|
|
|
|
This is relative to the base address register for the
|
|
SEC2 coprocessor. It is used to setup the
|
|
#ChannelConfigRegister variable array during Driver Startup
|
|
Each channel has a Channel Configuration Register that is offset
|
|
#CHANNEL_DISTANCE from the previous.
|
|
*/
|
|
#define CHANNEL_CONFIG_BASE ((unsigned long)0x00001108)
|
|
|
|
|
|
/*! \def CHANNEL_POINTER_STATUS_BASE
|
|
\brief Base address for the Channel # 1's
|
|
Channel Pointer Status Register.
|
|
|
|
This is relative to the base address register for the
|
|
SEC2 coprocessor. It is used to setup the
|
|
#ChannelPointerStatusRegister variable array during Driver Startup
|
|
Each channel has a Channel Pointer Status Register that is offset
|
|
#CHANNEL_DISTANCE from the previous.
|
|
*/
|
|
#define CHANNEL_POINTER_STATUS_BASE ((unsigned long)0x00001110)
|
|
|
|
/*! \def CHANNEL_NEXT_DESCRIPTOR_BASE
|
|
\brief Base address for the Channel # 1's
|
|
Channel Next Descriptor Register.
|
|
|
|
This is relative to the base address register for the
|
|
SEC2 coprocessor. It is used to setup the
|
|
#ChannelNextDescriptorRegister variable array during Driver Startup
|
|
Each channel has a Channel Next Descriptor Register that is offset
|
|
#CHANNEL_DISTANCE from the previous.
|
|
*/
|
|
#define CHANNEL_NEXT_DESCRIPTOR_BASE ((unsigned long)0x00001148)
|
|
|
|
/* Debugging Only definition
|
|
*/
|
|
|
|
#define CHANNEL_DBR_BASE ((unsigned long)0x00001180)
|
|
#define CHANNEL_CDPR_BASE ((unsigned long)0x00002040)
|
|
|
|
/*! \def CHANNEL_DISTANCE
|
|
\brief Number of bytes to the next channel register
|
|
*/
|
|
#define CHANNEL_DISTANCE ((unsigned long)0x00000100)
|
|
|
|
/*! \def CHA_RESET_CONTROL_BASE
|
|
\brief Base address for the CHA # 1 (DES)
|
|
CHA Reset Control Register.
|
|
|
|
This is relative to the base address register for the
|
|
SEC2 coprocessor. It is used to setup the
|
|
#ChaResetControlRegister variable array during Driver Startup
|
|
Each CHA has a CHA Reset Control Register that is offset
|
|
#CHA_DISTANCE from the previous.
|
|
*/
|
|
#define CHA_RESET_CONTROL_BASE ((unsigned long)0x00002018)
|
|
|
|
/*! \def CHA_INTERRUPT_STATUS_BASE
|
|
\brief Base address for the CHA # 1 (DES)
|
|
CHA Interrupt Status Register.
|
|
|
|
This is relative to the base address register for the
|
|
SEC2 coprocessor. It is used to setup the
|
|
#ChaInterruptStatusRegister variable array during Driver Startup
|
|
Each CHA has a CHA Interrupt Status Register that is offset
|
|
#CHA_DISTANCE from the previous.
|
|
*/
|
|
#define CHA_INTERRUPT_STATUS_BASE ((unsigned long)0x00002030)
|
|
|
|
/*! \def CHA_INTERRUPT_CONTROL_BASE
|
|
\brief Base address for the CHA # 1 (DES)
|
|
CHA Interrupt Control Register.
|
|
|
|
This is relative to the base address register for the
|
|
SEC2 coprocessor. It is used to setup the
|
|
#ChaInterruptControlRegister variable array during Driver Startup
|
|
Each CHA has a CHA Interrupt Control Register that is offset
|
|
#CHA_DISTANCE from the previous.
|
|
*/
|
|
#define CHA_INTERRUPT_CONTROL_BASE ((unsigned long)0x00002038)
|
|
|
|
/*! \def AFHA_STATUS_OFFSET
|
|
\brief Debugging Only definition.
|
|
*/
|
|
#define AFHA_STATUS_OFFSET ((unsigned long)0x0008028)
|
|
|
|
/*! \def PKHA_STATUS_BASE
|
|
\brief Debugging Only definition.
|
|
*/
|
|
#define PKHA_STATUS_BASE ((unsigned long)0x0000C028)
|
|
|
|
|
|
/* CHA_DISTANCE
|
|
Number of bytes to the next CHA register
|
|
*/
|
|
#define CHA_DISTANCE ((unsigned long)0x00002000)
|
|
|
|
|
|
/* CHANNEL_INTEN
|
|
Channel Interrupt Enable
|
|
*/
|
|
#define CHANNEL_INTEN ((unsigned long)0x00000002)
|
|
|
|
|
|
/* Force channel burst size to 128 bytes (normal default is 64) */
|
|
#define CHANNEL_BURST128 ((unsigned long)0x00000100)
|
|
|
|
|
|
|
|
/* CHANNEL_RESET
|
|
Bit field setting to write to the
|
|
#ChannelConfigRegister in order to reset the channel. First Word
|
|
|
|
The bit setting indicates that we are resetting the channel
|
|
*/
|
|
#define CHANNEL_RESET ((unsigned long)0x00000001)
|
|
|
|
|
|
|
|
/* Bit field mask for reading from the
|
|
#ChannelPointerStatusRegister in order
|
|
to determine if a CHA assigned to the channel generated
|
|
an error or not. First Word
|
|
*/
|
|
#define CHANNEL_CHA_ERROR_DOF ((unsigned long)0x80000000)
|
|
|
|
#define CHANNEL_CHA_ERROR_SOF ((unsigned long)0x40000000)
|
|
|
|
#define CHANNEL_CHA_ERROR_GER ((unsigned long)0x00100000)
|
|
|
|
#define CHANNEL_CHA_ERROR_SES ((unsigned long)0x00001000)
|
|
|
|
/* Bit field mask for reading from the
|
|
#ChannelPointerStatusRegister in order
|
|
to determine if there is an illegal descriptor or not
|
|
Second Word
|
|
*/
|
|
|
|
#define CHANNEL_SCATTER_LENGTH_ERROR ((unsigned long) 0x00000010)
|
|
#define CHANNEL_SCATTER_BOUND_ERROR ((unsigned long) 0x00000020)
|
|
#define CHANNEL_GATHER_LENGTH_ERROR ((unsigned long) 0x00000040)
|
|
#define CHANNEL_GATHER_BOUND_ERROR ((unsigned long) 0x00000080)
|
|
#define CHANNEL_CHA_ERROR ((unsigned long) 0x00000100)
|
|
#define CHANNEL_CHA_ASSIGN_ERROR ((unsigned long) 0x00000200)
|
|
#define CHANNEL_UNRECOGNIZED_HEADER_ERROR ((unsigned long) 0x00000400)
|
|
#define CHA_PARITY_SYSTEM_ERROR ((unsigned long) 0x00000800) /* compatibility */
|
|
#define CHANNEL_NULL_FETCH_POINTER ((unsigned long) 0x00000800)
|
|
#define CHANNEL_ZERO_SCATTER_LEN_ERROR ((unsigned long) 0x00001000)
|
|
#define CHANNEL_BUS_MASTER_ERROR ((unsigned long) 0x00002000)
|
|
#define CHANNEL_FETCH_FIFO_NEARMISS_ERROR ((unsigned long) 0x00004000)
|
|
#define CHANNEL_FETCH_FIFO_OVERFLOW_ERROR ((unsigned long) 0x00008000)
|
|
|
|
/*! \def SET_ALL_CHA_INT_DONE_MASK
|
|
\brief Bit field setting to write to the
|
|
#InterruptControlRegister in order to disable interrupts when
|
|
any of the CHAs have completed an operation
|
|
*/
|
|
/*! \def SET_ALL_CHA_INT_DONE_MASK
|
|
\brief Bit field setting to write to the
|
|
#InterruptControlRegister in order to disable interrupts when
|
|
any of the CHAs have completed an operation
|
|
*/
|
|
/*! \def CHA_SOFTWARE_RESET
|
|
\brief Bit field setting to write to any of the
|
|
#ChaResetControlRegister"s" in order to software reset the CHA
|
|
*/
|
|
/*! \def CHA_MODULE_INIT
|
|
\brief Bit field setting to write to any of the
|
|
#ChaResetControlRegister"s" in order to initialize the CHA
|
|
*/
|
|
/*! \def CHA_RESET_INT
|
|
\brief Bit field setting to write to any of the
|
|
#ChaResetControlRegister"s" in order to reset the CHA
|
|
*/
|
|
/*! \def CHA_RESET_INT
|
|
\brief Bit field setting to write to any of the
|
|
#ChaResetControlRegister"s" in order to reset the CHA
|
|
*/
|
|
/*! \def CHA_DESA_KEY_PARITY_ERROR_DISABLE
|
|
\brief Bit field setting to write to any of the
|
|
#ChaInterruptControlRegister"s" in order to disable parity errors
|
|
for the CHA. This is only good for DES specific CHAs.
|
|
*/
|
|
/*! \def CHA_PKHA_ILLEGAL_ADDR_ERROR_DISABLE
|
|
\brief Bit field setting to write to any of the
|
|
#ChaInterruptControlRegister"s" in order to disable illegal address errors
|
|
for the CHA. This is only good for PK specific CHAs.
|
|
*/
|
|
#define SET_ALL_CHA_INT_DONE_MASK ((unsigned long)0x00111111)
|
|
#define CHA_SOFTWARE_RESET ((unsigned long)0x00000001)
|
|
#define CHA_DESA_KEY_PARITY_ERROR_DISABLE ((unsigned long)0x00002000)
|
|
#define CHA_PKHA_ILLEGAL_ADDR_ERROR_DISABLE ((unsigned long)0x00000040)
|
|
|
|
/* NUM_DPD_FLDS
|
|
Number of fields in a ::dpd
|
|
*/
|
|
#define NUM_DPD_FLDS 7
|
|
|
|
/* This is the physical representation of a DPD. It is how
|
|
the SEC2 sees a DPD.
|
|
*/
|
|
typedef struct dpd
|
|
{
|
|
unsigned long header;
|
|
unsigned long dpd_reserved;
|
|
/* Each field in a DPD. They are length and pointer pairs. */
|
|
struct dpd_fld
|
|
{
|
|
unsigned long len;
|
|
unsigned long ptr;
|
|
} fld[NUM_DPD_FLDS];
|
|
} DPD;
|
|
/* CHANNEL_ASSIGNMENT Controls the assignment of channels */
|
|
typedef struct channel_assignment
|
|
{
|
|
unsigned char assignment; /* The current state of the channel.
|
|
It can be one of the following values:
|
|
#CHANNEL_FREE, or #CHANNEL_BUSY
|
|
*/
|
|
int ownerTaskId; /* Task Id that currently owns the
|
|
channel.
|
|
*/
|
|
GENERIC_REQ *pReq; /* Pointer to the start of a linked
|
|
list describing the request
|
|
*/
|
|
GENERIC_REQ *pCurrReq; /* Pointer to the current linked list
|
|
member. Used when the list is chunked
|
|
*/
|
|
DPD **Dpds; /* Array of pointers to DPDs that can
|
|
used when generating DPD requests
|
|
|
|
#MAX_DPDS identifies
|
|
how many DPDs are allocated during
|
|
startup.
|
|
*/
|
|
} CHANNEL_ASSIGNMENT;
|
|
|
|
/* A double linked list to pending dynamic requests */
|
|
typedef struct queue_entry
|
|
{
|
|
int requestingTaskId; /* Requesting task's Id.
|
|
|
|
This becomes
|
|
channel_assignment::ownerTaskId
|
|
when a channel can be assigned.
|
|
*/
|
|
int chan; /* channel if static
|
|
be free before the entry can
|
|
be assigned to a channel
|
|
*/
|
|
GENERIC_REQ *pReq; /* Pointer to the start of a
|
|
linked list describing the request
|
|
|
|
This becomes
|
|
channel_assignment::pReq
|
|
when a channel can be assigned.
|
|
*/
|
|
struct queue_entry *next; /* pointer to next entry */
|
|
struct queue_entry *previous; /* pointer to previous entry */
|
|
} QUEUE_ENTRY;
|
|
|
|
|
|
/* (!sec) these may be obsolete */
|
|
#define ALL_INT_ERRORS_MASK_LOW ((unsigned long)0x000000ff)
|
|
#define ALL_INT_ERRORS_MASK_HIGH ((unsigned long)0x00333333)
|
|
|
|
|
|
/* All possible channel done interrupts from high interrupt status word */
|
|
#define ALL_CHANNEL_INT_DONE_MASK ((unsigned long)0x00000055)
|
|
#define CHANNEL_INT_DONE_1 ((unsigned long)0x00000001)
|
|
#define CHANNEL_INT_DONE_2 ((unsigned long)0x00000004)
|
|
#define CHANNEL_INT_DONE_3 ((unsigned long)0x00000010)
|
|
#define CHANNEL_INT_DONE_4 ((unsigned long)0x00000040)
|
|
|
|
/* All possible CHA done interrupts from low interrupt status word */
|
|
#define ALL_CHA_INT_DONE_MASK ((unsigned long)0x00111111)
|
|
#define CHA_INT_DONE_DEU ((unsigned long)0x00000001)
|
|
#define CHA_INT_DONE_AESU ((unsigned long)0x00000010)
|
|
#define CHA_INT_DONE_MDEU ((unsigned long)0x00000100)
|
|
#define CHA_INT_DONE_AFEU ((unsigned long)0x00001000)
|
|
#define CHA_INT_DONE_RNG ((unsigned long)0x00010000)
|
|
#define CHA_INT_DONE_PKEU ((unsigned long)0x00100000)
|
|
|
|
/* All possible channel error interrupts from high interrupt status word */
|
|
#define ALL_CHANNEL_INT_ERROR_MASK ((unsigned long)0x000000aa)
|
|
#define CHANNEL_INT_ERROR_1 ((unsigned long)0x00000002)
|
|
#define CHANNEL_INT_ERROR_2 ((unsigned long)0x00000008)
|
|
#define CHANNEL_INT_ERROR_3 ((unsigned long)0x00000020)
|
|
#define CHANNEL_INT_ERROR_4 ((unsigned long)0x00000080)
|
|
|
|
/* All possible CHA done interrupts from low interrupt status word */
|
|
#define ALL_CHA_INT_ERROR_MASK ((unsigned long)0x00222222)
|
|
#define CHA_INT_ERROR_DEU ((unsigned long)0x00000002)
|
|
#define CHA_INT_ERROR_AESU ((unsigned long)0x00000020)
|
|
#define CHA_INT_ERROR_MDEU ((unsigned long)0x00000200)
|
|
#define CHA_INT_ERROR_AFEU ((unsigned long)0x00002000)
|
|
#define CHA_INT_ERROR_RNG ((unsigned long)0x00020000)
|
|
#define CHA_INT_ERROR_PKEU ((unsigned long)0x00200000)
|
|
|
|
|
|
|
|
/*! \struct device_regs
|
|
\brief A grouping of status and error indication registers
|
|
*/
|
|
typedef struct device_regs
|
|
{
|
|
unsigned long IntStatus[2]; /*!< The Interrupt
|
|
Status Register
|
|
(#InterruptStatusRegister)*/
|
|
unsigned long IntStatusDbg[2]; /*!< The Interrupt
|
|
Status Register
|
|
(#InterruptStatusRegister)*/
|
|
unsigned long ChaAssignmentStatus[2]; /*!< The CHA
|
|
Assignment Status
|
|
Register
|
|
(#ChaAssignmentStatusRegister)
|
|
*/
|
|
unsigned long ChannelError[NUM_CHANNELS][2]; /*!< An array of
|
|
Channel Pointer Status
|
|
Registers. One per
|
|
channel
|
|
(#ChannelPointerStatusRegister)
|
|
*/
|
|
unsigned long ChaError[NUM_CHAS][2]; /*!< an array of
|
|
CHA Interrupt Status
|
|
Registers. One per CHA
|
|
(#ChaInterruptStatusRegister)
|
|
*/
|
|
} DEVICE_REGS;
|
|
|
|
|
|
|
|
/* Queueing */
|
|
#ifdef __KERNEL__
|
|
#define PREGS_QUEUE_DEPTH 16
|
|
extern DEVICE_REGS pRegs_queue[PREGS_QUEUE_DEPTH];
|
|
extern unsigned PQ_head, PQ_tail, PQ_entries;
|
|
|
|
#define QmsgSend() \
|
|
if (PQ_entries == PREGS_QUEUE_DEPTH) { \
|
|
panic("SEC driver's pRegs queue overflow!"); \
|
|
} \
|
|
pRegs_queue[PQ_tail] = *pRegs; \
|
|
PQ_tail = (PQ_tail + 1) % PREGS_QUEUE_DEPTH; \
|
|
PQ_entries ++; \
|
|
tasklet_schedule(&isr_tasklet)
|
|
|
|
#define QmsgWait() \
|
|
disable_irq(MPC85xx_IRQ_SEC); \
|
|
if (!PQ_entries) { \
|
|
enable_irq(MPC85xx_IRQ_SEC); break;} \
|
|
*pRegs = pRegs_queue[PQ_head]; \
|
|
PQ_head = (PQ_head + 1) % PREGS_QUEUE_DEPTH; \
|
|
PQ_entries --; \
|
|
enable_irq(MPC85xx_IRQ_SEC)
|
|
#endif
|
|
|
|
|
|
|
|
|
|
/* Components of a SEC2 scatter/gather list element. This is the native format */
|
|
/* that the channel processor expects to see so as to translate a scattered */
|
|
/* buffer in the course of processing */
|
|
|
|
|
|
#define MAX_SCATTER_FRAGS 1024 /* limit of static fragment descriptor pool */
|
|
|
|
/* used in "linkStat" below */
|
|
#define SEGLIST_RETURN 0x0200
|
|
#define SEGLIST_NEXT 0x0100
|
|
|
|
typedef struct _sec2scatterListElement
|
|
{
|
|
unsigned short segLen;
|
|
unsigned short linkStat;
|
|
void *segAddr;
|
|
} SCATTER_ELEMENT;
|
|
|
|
|
|
|
|
#if defined(SEC2_GLOBAL) || defined(__cplusplus)
|
|
|
|
/* unsigned long ChaDoneInterruptMasks[NUM_CHAS]
|
|
An array of CHA done completion bit masks.
|
|
|
|
The index of the array represents the CHA. This bit mask
|
|
is applied against #InterruptStatusRegister in order to
|
|
determine if an interrupt is due to a CHA completion or not.
|
|
*/
|
|
const unsigned long ChaDoneInterruptMasks[NUM_CHAS] =
|
|
{
|
|
0x00000001,
|
|
0x00000010,
|
|
0x00000100,
|
|
0x00001000,
|
|
0x00010000,
|
|
0x00100000
|
|
|
|
};
|
|
|
|
/* unsigned long ChannelDoneInterruptMasks[NUM_CHANNELS]
|
|
An array of channel done completion bit masks.
|
|
|
|
The index of the array represents the channel. This bit mask
|
|
is applied against #InterruptStatusRegister in order to
|
|
determine if an interrupt is due to a channel completion or not.
|
|
*/
|
|
const unsigned long ChannelDoneInterruptMasks[NUM_CHANNELS] =
|
|
{
|
|
0x00000001,
|
|
0x00000004,
|
|
0x00000010,
|
|
0x00000040
|
|
};
|
|
|
|
/*! \var unsigned long ChannelErrorInterruptMasks[NUM_CHANNELS]
|
|
\brief An array of channel error bit masks.
|
|
|
|
The index of the array represents the channel. This bit mask
|
|
is applied against #InterruptStatusRegister in order to
|
|
determine if an interrupt is due to a channel error or not.
|
|
*/
|
|
const unsigned long ChannelErrorInterruptMasks[NUM_CHANNELS] =
|
|
{
|
|
0x00000002,
|
|
0x00000008,
|
|
0x00000020,
|
|
0x00000080
|
|
};
|
|
|
|
/*! \var unsigned long ChaErrorInterruptMasks[NUM_CHAS]
|
|
\brief An array of CHA error bit masks.
|
|
|
|
The index of the array represents the CHA. This bit mask
|
|
is applied against #InterruptStatusRegister in order to
|
|
determine if an interrupt is due to a CHA error or not.
|
|
*/
|
|
const unsigned long ChaErrorInterruptMasks[NUM_CHAS] =
|
|
{
|
|
0x00000002,
|
|
0x00000020,
|
|
0x00000200,
|
|
0x00002000,
|
|
0x00020000,
|
|
0x00200000
|
|
};
|
|
|
|
#else
|
|
|
|
extern const unsigned long ChaDoneInterruptMasks[];
|
|
extern const unsigned long ChannelDoneInterruptMasks[];
|
|
extern const unsigned long ChannelErrorInterruptMasks[];
|
|
extern const unsigned long ChaErrorInterruptMasks[];
|
|
|
|
#endif
|
|
|
|
#ifndef SEC2_GLOBAL
|
|
#define SEC2_GLOBAL extern
|
|
#endif
|
|
|
|
/* SEC2_GLOBAL
|
|
A definition used to control allocation and referencing
|
|
of global variables.
|
|
|
|
When the definition is not set it is considered
|
|
to be used as a reference (extern is prepended).
|
|
|
|
When the definition is set (to nothing) it is considered to be
|
|
allocating the global variable. This is done in one place
|
|
only. In init.c
|
|
*/
|
|
|
|
/* CHANNEL_ASSIGNMENT ChannelAssignments
|
|
A global variable which is a array of channel assignment
|
|
structures. Each channel is reqresented by its own channel
|
|
assignment structure.
|
|
*/
|
|
SEC2_GLOBAL DPD Descriptors[NUM_CHANNELS][MAX_DPDS] ;
|
|
SEC2_GLOBAL CHANNEL_ASSIGNMENT ChannelAssignments[NUM_CHANNELS];
|
|
SEC2_GLOBAL DPD *dpd[NUM_CHANNELS][MAX_DPDS];
|
|
SEC2_GLOBAL QUEUE_ENTRY Queue[QUEUE_ENTRY_DEPTH];
|
|
|
|
|
|
/* A global variable which is an array of CHAs that
|
|
are assigned to channels.
|
|
|
|
The value in each element is either
|
|
#CHA_BUSY which is unassigned or the channel that is
|
|
assigned (1-4) to the CHA represented by the array index.
|
|
*/
|
|
SEC2_GLOBAL unsigned char ChaAssignments[16];
|
|
|
|
/* A global variable which is the address of the base
|
|
address register for the SEC2 coprocessor
|
|
|
|
All registers accessed are offsets from this register.
|
|
This variable is initialized during startup.
|
|
*/
|
|
SEC2_GLOBAL unsigned long IOBaseAddress;
|
|
|
|
/* A global variable which is a pointer to the CHA
|
|
Assignment Status Register
|
|
|
|
This variable is initialized during startup. It is determined
|
|
to be a fixed offset from the #IOBaseAddress
|
|
register. See the SEC2 manual for details.
|
|
*/
|
|
SEC2_GLOBAL volatile unsigned long *ChaAssignmentStatusRegister;
|
|
|
|
/* A global variable which is a pointer to the CHA
|
|
Assignment Control Register
|
|
|
|
This variable is initialized during startup. It is determined
|
|
to be a fixed offset from the #IOBaseAddress
|
|
register. See the SEC2 manual for details.
|
|
*/
|
|
SEC2_GLOBAL volatile unsigned long *ChaAssignmentControlRegister;
|
|
|
|
/* A global variable which is a pointer to the Interrupt
|
|
Control Register
|
|
|
|
This variable is initialized during startup. It is determined
|
|
to be a fixed offset from the #IOBaseAddress
|
|
register. See the SEC2 manual for details.
|
|
*/
|
|
SEC2_GLOBAL volatile unsigned long *InterruptControlRegister;
|
|
|
|
/* A global variable which is a pointer to the Interrupt
|
|
Status Register
|
|
|
|
This variable is initialized during startup. It is determined
|
|
to be a fixed offset from the #IOBaseAddress
|
|
register. See the SEC2 manual for details.
|
|
*/
|
|
SEC2_GLOBAL volatile unsigned long *InterruptStatusRegister;
|
|
|
|
/* A global variable which is a pointer to the Interrupt
|
|
Clear Register
|
|
|
|
This variable is initialized during startup. It is determined
|
|
to be a fixed offset from the #IOBaseAddress
|
|
register. See the SEC2 manual for details.
|
|
*/
|
|
SEC2_GLOBAL volatile unsigned long *InterruptClearRegister;
|
|
|
|
/* A global variable which is a pointer to the ID Register
|
|
|
|
This variable is initialized during startup. It is determined
|
|
to be a fixed offset from the #IOBaseAddress
|
|
register. See the SEC2 manual for details.
|
|
*/
|
|
SEC2_GLOBAL volatile unsigned long *IdRegister;
|
|
|
|
/* A global variable which is a array of pointers to the
|
|
Channel Config Registers. There is one per channel.
|
|
|
|
This pointers are initialized during startup. They are determined
|
|
to be a fixed offset from the #IOBaseAddress
|
|
register. See the SEC2 manual for details.
|
|
*/
|
|
SEC2_GLOBAL volatile unsigned long *ChannelConfigRegister[NUM_CHANNELS];
|
|
|
|
/* A global variable which is a array of pointers to the
|
|
Channel Pointer Status Registers. There is one per channel.
|
|
|
|
This pointers are initialized during startup. They are determined
|
|
to be a fixed offset from the #IOBaseAddress
|
|
|
|
register. See the SEC2 manual for details.
|
|
*/
|
|
SEC2_GLOBAL volatile unsigned long *ChannelPointerStatusRegister[NUM_CHANNELS];
|
|
|
|
/* A global variable which is a array of pointers to the
|
|
Channel Next Descriptor Registers. There is one per channel.
|
|
|
|
This pointers are initialized during startup. They are determined
|
|
to be a fixed offset from the #IOBaseAddress
|
|
register. See the SEC2 manual for details.
|
|
*/
|
|
SEC2_GLOBAL volatile unsigned long *ChannelNextDescriptorRegister[NUM_CHANNELS];
|
|
|
|
/* A global variable which is a array of pointers to the
|
|
CHA Reset Control Registers. There is one per CHA.
|
|
|
|
This pointers are initialized during startup. They are determined
|
|
to be a fixed offset from the #IOBaseAddress
|
|
register. See the SEC2 manual for details.
|
|
*/
|
|
SEC2_GLOBAL volatile unsigned long *ChaResetControlRegister[NUM_CHAS];
|
|
|
|
/* A global variable which is a array of pointers to the
|
|
CHA Interrupt Status Registers. There is one per CHA.
|
|
|
|
This pointers are initialized during startup. They are determined
|
|
to be a fixed offset from the #IOBaseAddress
|
|
register. See the SEC2 manual for details.
|
|
*/
|
|
SEC2_GLOBAL volatile unsigned long *ChaInterruptStatusRegister[NUM_CHAS];
|
|
|
|
/* A global variable which is a array of pointers to the
|
|
CHA Interrupt Control Registers. There is one per CHA.
|
|
|
|
This pointers are initialized during startup. They are determined
|
|
to be a fixed offset from the #IOBaseAddress
|
|
register. See the SEC2 manual for details.
|
|
*/
|
|
SEC2_GLOBAL volatile unsigned long *ChaInterruptControlRegister[NUM_CHAS];
|
|
|
|
/* Debugging Only variables.
|
|
*/
|
|
SEC2_GLOBAL volatile unsigned long *ChannelDataBufferDescriptorRegister[NUM_CHANNELS];
|
|
SEC2_GLOBAL volatile unsigned long *ChannelCurrentDescriptorPointerRegister[NUM_CHANNELS];
|
|
|
|
/* long *MasterControlRegister
|
|
A global variable which is a pointer to the
|
|
Master Control Register
|
|
|
|
This variable is initialized during startup. It is determined
|
|
to be a fixed offset from the #IOBaseAddress
|
|
register. See the SEC2 manual for details.
|
|
*/
|
|
SEC2_GLOBAL volatile unsigned long *MasterControlRegister;
|
|
|
|
/* FreeChannels
|
|
A global variable which keeps track of the number of
|
|
free channels
|
|
*/
|
|
SEC2_GLOBAL int FreeChannels;
|
|
|
|
/*! \var int FreeRngas
|
|
\brief A global variable which keeps track of the number of
|
|
free RNG CHAs
|
|
*/
|
|
SEC2_GLOBAL int FreeRngas;
|
|
|
|
/*! \var int FreeAfhas
|
|
\brief A global variable which keeps track of the number of
|
|
free ARC4 CHAs
|
|
*/
|
|
SEC2_GLOBAL int FreeAfhas;
|
|
|
|
/*! \var int FreeDesas
|
|
\brief A global variable which keeps track of the number of
|
|
free DES CHAs
|
|
*/
|
|
SEC2_GLOBAL int FreeDesas;
|
|
|
|
/*! \var int FreeMdhas
|
|
\brief A global variable which keeps track of the number of
|
|
free MD CHAs
|
|
*/
|
|
SEC2_GLOBAL int FreeMdhas;
|
|
|
|
/*! \var int FreePkhas
|
|
\brief A global variable which keeps track of the number of
|
|
free PK CHAs
|
|
*/
|
|
SEC2_GLOBAL int FreePkhas;
|
|
|
|
/*! \var int FreeAesas
|
|
\brief A global variable which keeps track of the number of
|
|
free AESA CHAs
|
|
*/
|
|
SEC2_GLOBAL int FreeAesas;
|
|
|
|
/*! \var int FreeKeas
|
|
\brief A global variable which keeps track of the number of
|
|
free KEA CHAs
|
|
*/
|
|
SEC2_GLOBAL int FreeKeas;
|
|
|
|
/*! \var unsigned long BlockSize
|
|
\brief A global variable which indicates what the current block size
|
|
is
|
|
*/
|
|
SEC2_GLOBAL unsigned long BlockSize;
|
|
|
|
/*! \var ProcessQueueTop
|
|
\brief A global variable which is a pointer to the top
|
|
of the Pending dynamic request list (list of ::queue_entry"s").
|
|
*/
|
|
SEC2_GLOBAL QUEUE_ENTRY *ProcessQueueTop;
|
|
/*! \var ProcessQueueBottom
|
|
\brief A global variable which is a pointer to the bottom
|
|
of the Pending dynamic request list (list of ::queue_entry"s").
|
|
*/
|
|
SEC2_GLOBAL QUEUE_ENTRY *ProcessQueueBottom;
|
|
|
|
/*! \var unsigned long QueueEntryDepth
|
|
\brief A global variable which keeps track of the number
|
|
of entries in the Pending dynamic request list pointed to
|
|
by #ProcessQueueTop
|
|
*/
|
|
SEC2_GLOBAL unsigned long QueueEntryDepth;
|
|
|
|
/*! \var SEM_ID ChannelAssignSemId
|
|
\brief (VxWorks Only) A global variable which is used as a mutual exclusion
|
|
semaphore for the #ChannelAssignments array.
|
|
|
|
The variable is not used directly. It used by calling
|
|
#IOLockChannelAssignment() to lock and #IOUnLockChannelAssignment()
|
|
to unlock.
|
|
*/
|
|
#if defined(VXWORKS)
|
|
SEC2_GLOBAL SEM_ID ChannelAssignSemId;
|
|
#else
|
|
#ifdef __KERNEL__
|
|
extern spinlock_t ChannelAssignLock;
|
|
#else
|
|
#ifdef INIT_C
|
|
DECLARE_MUTEX(ChannelAssignSemId);
|
|
#else
|
|
extern struct semaphore ChannelAssignSemId;
|
|
#endif
|
|
#endif
|
|
#endif
|
|
|
|
/*! \var SEM_ID QueueSemId
|
|
\brief (VxWorks Only) A global variable which is used as a mutual exclusion
|
|
semaphore for the Queue
|
|
|
|
The variable is not used directly. It used by calling
|
|
#IOLockBlockSize() to lock and #IOUnLockBlockSize()
|
|
to unlock.
|
|
*/
|
|
#if defined(VXWORKS)
|
|
SEC2_GLOBAL SEM_ID QueueSemId;
|
|
#else
|
|
#ifdef INIT_C
|
|
DECLARE_MUTEX(QueueSemId);
|
|
#else
|
|
extern struct semaphore QueueSemId;
|
|
#endif
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef VXWORKS
|
|
/* The queue identifier is used to queue register values read by the
|
|
ISR (#InterruptServiceRoutine()) to the deferred interrupt process
|
|
routine (#ProcessingComplete())
|
|
*/
|
|
SEC2_GLOBAL MSG_Q_ID IsrMsgQId;
|
|
|
|
/* OS's identification of the device*/
|
|
SEC2_GLOBAL int driverNum;
|
|
#endif
|
|
|
|
|
|
#ifdef __KERNEL__
|
|
/* Device major number registered at device initialization */
|
|
SEC2_GLOBAL int sec2_devmajor;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
SEC2_GLOBAL unsigned int cha_idx[6];
|
|
|
|
|
|
/*! \var DEV_HDR vxworksDrvDev
|
|
\brief (VxWorks Only) Used in driver startup.
|
|
*/
|
|
#ifdef VXWORKS
|
|
SEC2_GLOBAL DEV_HDR vxworksDrvDev;
|
|
#endif
|
|
|
|
|
|
|
|
/* coremask holds the core ID register for version/feature control */
|
|
SEC2_GLOBAL unsigned long coremask;
|
|
|
|
|
|
|
|
|
|
/* Forward declarations for internal driver functions not meant for "public use" */
|
|
|
|
int ReleaseChannel(unsigned long, int, BOOLEAN);
|
|
|
|
int MapScatterFragments(unsigned long ,
|
|
unsigned long *);
|
|
|
|
void UnmapScatterFragments(unsigned long *);
|
|
|
|
|
|
|
|
/* Read/write a block of data from hardware registers (obsolete) */
|
|
void IORead(unsigned long *, int, volatile unsigned long *);
|
|
void IOWrite(unsigned long *, int, volatile unsigned long *);
|
|
|
|
|
|
/* Register driver and it's handlers with the OS */
|
|
IO_STATUS IORegisterDriver(void);
|
|
|
|
/* Set up internal driver semaphores */
|
|
void IOInitSemaphores(void);
|
|
|
|
/* Initialize drive queues */
|
|
IO_STATUS IOInitQs(void);
|
|
|
|
/* Enable/Disable the hardware interrupt */
|
|
IO_STATUS IOConnectInterrupt(void);
|
|
void IODisconnectInterrupt(void);
|
|
|
|
/* Allocate/free a dynamic queue entry (obsolete) */
|
|
QUEUE_ENTRY *IOAllocateQEntry(void);
|
|
void IOFreeQEntry(QUEUE_ENTRY *);
|
|
|
|
/* Initialize/Allocate/Release channel assignment table */
|
|
IO_STATUS InitChannelAssignment(int);
|
|
void FreeChannelAssignment(int);
|
|
|
|
/* Translate CHA index to type */
|
|
int ChaNumToType(int);
|
|
|
|
/* Check to see if the CHA type is available */
|
|
extern int CheckChas(unsigned long);
|
|
|
|
/* Open a new connection to this driver */
|
|
#ifdef __KERNEL__
|
|
int SEC2Open(struct inode *, struct file *);
|
|
#else
|
|
int SEC2Open(DEV_HDR *, int, int);
|
|
#endif
|
|
|
|
/* Close a connection to this driver */
|
|
#ifdef __KERNEL__
|
|
int SEC2Close(struct inode *, struct file *);
|
|
#else
|
|
int SEC2Close(int);
|
|
#endif
|
|
|
|
/* Request a driver operation*/
|
|
#ifdef __KERNEL__
|
|
int SEC2_ioctl(struct inode *, struct file *, unsigned int, unsigned long);
|
|
#else
|
|
int SEC2_ioctl(int, register int, register void *);
|
|
#endif
|
|
|
|
/* Driver's top level ISR handler */
|
|
#ifdef __KERNEL__
|
|
void InterruptServiceRoutine(int irq, void *dev_id, struct pt_regs *pt_regs);
|
|
#else
|
|
void InterruptServiceRoutine(void);
|
|
#endif
|
|
|
|
/* ISR's Deferred processing (bottom half) handler */
|
|
#if defined(VXWORKS) || defined(_MSC_VER)
|
|
extern void ProcessingComplete(void);
|
|
#else
|
|
extern void ProcessingComplete(unsigned long not_used);
|
|
#endif
|
|
|
|
/* External function to mark scatter buffers for kernel-state usage */
|
|
#ifdef __KERNEL__
|
|
int MarkScatterBuffer(void *, void *);
|
|
#endif
|
|
|
|
/* Take a user request, build a DPD, and submit it for processing */
|
|
int ProcessRequest(GENERIC_REQ *, int);
|
|
|
|
/* Start any pending requests */
|
|
void ScheduleNext(void);
|
|
|
|
/*! \fn BOOLEAN StartDescriptor(int channel, unsigned long addr)
|
|
\brief Start a DPD request to the SEC2
|
|
|
|
Write \a addr to the #ChannelNextDescriptorRegister register
|
|
for this \a channel
|
|
|
|
Timers are launched if USE_TIMERS are defined
|
|
|
|
\param channel
|
|
\param addr address to be saved in #ChannelNextDescriptorRegister
|
|
\retval TRUE if successful
|
|
*/
|
|
extern BOOLEAN StartDescriptor(int channel, unsigned long addr);
|
|
|
|
/*! \fn int CompleteRequest(int channel, int status, BOOLEAN bDoNotify, DEVICE_REGS *pRegs)
|
|
\brief Complete a request
|
|
|
|
Call FinishIoRequest()
|
|
|
|
Cleanup the ::req_list associated with this request by calling
|
|
CleanupRequestList()
|
|
|
|
Make the #ChannelAssignment entry for the \a channel available
|
|
|
|
If \a bDoNotify is set, call a notify routine
|
|
|
|
\param channel Channel request was issued on
|
|
\param status Status of the request
|
|
\param bDoNotify Notify requester?
|
|
\param pRegs Pointer to register snapshot
|
|
\retval status
|
|
*/
|
|
extern int CompleteRequest(int channel, int status, BOOLEAN bDoNotify, DEVICE_REGS *pRegs);
|
|
|
|
/*! \fn void RemoveQueueEntry(QUEUE_ENTRY *entry)
|
|
\brief Remove entry from pending dynamic request list
|
|
|
|
\param entry ::queue_entry to be deleted
|
|
*/
|
|
extern void RemoveQueueEntry(QUEUE_ENTRY *entry);
|
|
/*! \fn int RequestToDpd(int channel)
|
|
\brief Transform the current request into a chain of DPDs
|
|
|
|
This routine will traverse a ::req_list populating
|
|
CHANNEL_ASSIGNMENT::Dpds for the given \a channel.
|
|
The ::req_list will have been built by BuildRequestList().
|
|
|
|
After successful completion, the caller will be able to
|
|
get the hardware to process the request by calling
|
|
StartDescriptor(). StartDescriptor() expects a Hardware
|
|
specific address, i.e. use CHANNEL_ASSIGNMENT::addrHwDpds
|
|
for the given \a channel.
|
|
|
|
\param channel Channel that DPD(s) will be launched on
|
|
\retval #SEC2_SUCCESS if successful
|
|
*/
|
|
extern int RequestToDpd(GENERIC_REQ *pReq, int channel);
|
|
|
|
/*! \fn void CopyRegsToStatus(STATUS_REQ *pStatus, DEVICE_REGS *pRegs)
|
|
\brief A helper function to copy a register snapshot into a status request
|
|
|
|
\param pStatus Pointer to status request
|
|
\param pRegs Pointer to register snapshot
|
|
*/
|
|
extern void CopyRegsToStatus(STATUS_REQ *pStatus, DEVICE_REGS *pRegs);
|
|
|
|
/*! \fn int SetBlockSize(unsigned long* newBlockSize)
|
|
\brief Set the Block Size for DPD requests
|
|
|
|
\param newBlockSize Size to set #BlockSize to.
|
|
\retval #SEC2_SUCCESS if successful
|
|
*/
|
|
extern int SetBlockSize(unsigned long* newBlockSize);
|
|
|
|
/*! \fn int GetStatus(STATUS_REQ *pStatus, int callingTaskId)
|
|
\brief Get Current Status of the Driver
|
|
|
|
\param pStatus Pointer to status request.
|
|
\param callingTaskId Id of Task that is making the request
|
|
\retval #SEC2_SUCCESS
|
|
*/
|
|
extern int GetStatus(STATUS_REQ *pStatus, int callingTaskId);
|
|
|
|
#endif /* SEC2DRIVER_H */
|