#ifndef _INC_PARAMS_H
#define _INC_PARAMS_H
/* new file in RC 3.02 */

/** 
@defgroup Common_Statistics Statistics

A broad array of module statistics is available.  Statistics values are accessed
through the @c Control() interface of the CPHAL.  There are 5 different levels
of statistics, each of which correspond to a unique set of data.  Furthermore,
certain statistics data is indexed by using a channel number and Tx queue number.
The following is a brief description of each statistics level, along with the
indexes used for the level:

- Level 1:  Hardware Statistics (index with channel)
- Level 2:  CPHAL Software Statistics (channel, queue)
- Level 3:  CPHAL Flags (channel, queue)
- Level 4:  CPHAL Channel Configuration (channel)
- Level 5:  CPHAL General Configuration (no index)

The caller requests statistics information by providing a Key string to the
@c Control() API in the following format: "Stats;[Level #];[Ch #];[Queue #]".
The only valid Action parameter for statistics usage is "Get".  

Code Examples:
@code
unsigned int *StatsData;

# Get Level 0 stats for Channel 1
HalFunc->Control(OsDev->HalDev, "Stats.0.1", "Get", &StatsData);

# Get Level 2 stats for Channel 0, Queue 0
HalFunc->Control(OsDev->HalDev, "Stats.2.0.0", "Get", &StatsData);

# Get Level 4 stats
HalFunc->Control(OsDev->HalDev, "Stats.4", "Get", &StatsData);
@endcode

The information returned in the Value parameter of @c Control() is an
array of pointers to strings.  The pointers are arranged in pairs.
The first pointer is a pointer to a name string for a particular statistic.  
The next pointer is a pointer to a string containing the representation of 
the integer statistic value corresponding to the first pointer.  This is followed 
by another pair of pointers, and so on, until a NULL pointer is encountered.  The
following is example code for processing the statistics data.  Note that the OS 
is responsible for freeing the memory passed back through the Value parameter of 
@c Control().

@code
unsigned int *StatsData;

# Get Level 0 stats for Channel 1
HalFunc->Control(OsDev->HalDev, "Stats.0.1", "Get", &StatsData);

# output Statistics data
PrintStats(StatsData);

...

void PrintStats(unsigned int *StatsPtr)
  {
   while(*StatsPtr)
     { 
      printf("%20s:",  (char *)*StatsPtr);
      StatsPtr++;
      printf("%11s\n", (char *)*StatsPtr);
      StatsPtr++;
     }
   MySioFlush();

   # the upper layer is responsible for freeing stats info
   free(StatsPtr);
  }  
@endcode

Within each statistics level, there are several statistics defined.  The statistics that
are common to every CPPI module are listed below.  In addition, each module may define
extra statistics in each level, which will be documented within the module-specific
documentation appendices.

- Level 0 Statistics
  - All level 0 statistics are module-specific.
- Level 1 Statistics 
  - DmaLenErrors
  - TxMisQCnt
  - RxMisQCnt
  - TxEOQCnt
  - RxEOQCnt
  - RxPacketsServiced
  - TxPacketsServiced
  - RxMaxServiced
  - TxMaxServiced
  - RxTotal
  - TxTotal
- Level 2 Statistics
  - RcbPool
  - RxActQueueCount
  - RxActQueueHead
  - RxActQueueTail
  - RxActive
  - RcbStart
  - RxTeardownPending
  - TcbPool
  - TxActQueueCount
  - TxActQueueHead
  - TxActQueueTail
  - TxActive
  - TcbStart
  - TxTeardownPending
- Level 3 Statistics
  - RxBufSize
  - RxBufferOffset
  - RxNumBuffers
  - RxServiceMax
  - TxNumBuffers
  - TxNumQueues
  - TxServiceMax
- Level 4 Statistics
  - Base Address
  - Offset (VLYNQ)
  - Interrupt Line
  - Debug
  - Inst
  - ResetBase
  - ResetBit
*/

/* 
 * Parameter Table
 *
 * Field breakdown of Type:
 *  00:00  Initialize    (if set, must be initialized)
 *  01:01  Required      (if 1, Param is required)
 *  02:02  Writable      (if set, param is writable)
 *  03:03  WriteAfterOpen (if writable, can you write it after open?)
 *  04:04  Clearable     (if set, param can be cleared)
 *  05:06  Substructure  (0:HalDev, 1:ChData, 2:Stats(AAL5), 3:?)
 *  07:09  Group         (8 groups)
 *  10:10  IsString      (binary(0) or char string(1))
 *  11:16  Field Width   (up to 63 bit width)
 *  17:21  Field Offset  (up to 31 bit offset/shift)
 *  23:26  Device        (16 devices supported per table)
 *  27:28  Name          (0: Param, 1: Device Name, 2: Channel Name) 
 *  29:30  Index         (0: No Index, 1: Channel #, 2: Ch and Queue #)
 *  31:31  ChDirection   (0: Tx, 1: Rx)
 */

/* Parameter defines */
#define DO_INIT             (1  <<  0)
#define REQ                 (1  <<  1)

/* Permissions */
#define WRITABLE            (1  <<  2)
#define WR_AFTER_OPEN       (1  <<  3)
#define CLEARABLE           (1  <<  4)

/* Substructures */
#define HAL_DEV             (0  <<  5)
#define CH_DATA             (1  <<  5)
#define STATS               (2  <<  5)

/* Stat Groups */
#define GROUP1              (1  <<  7)
#define GROUP2              (2  <<  7)
#define GROUP3              (3  <<  7)
#define GROUP4              (4  <<  7)
#define GROUP5              (5  <<  7)

/* Define this if the parameter is a string */
#define ISSTRING            (1  << 10)

/* Width and offset currently unused */
#define WIDTH(n)            (n  << 11)
#define OFFSET(n)           (n  << 17)

/* defines which device the parameter applies to */
#define DEV(n)              (n  << 23)
  /* use the following device numbers in your parm table */
  #define DEV_CPSAR        1
  #define DEV_AAL5         2
  #define DEV_AAL2         3
  #define DEV_CPMAC        4
  #define DEV_VDMA         5
  #define DEV_VLYNQ        6
  #define DEV_CPPI         7
  #define DEV_CPMDIO       8

/* each param may be an actual parameter (default), a device name,
   or a channel name */
#define DEV_NAME            (1  << 27)
#define CH_NAME             (2  << 27)

/* if the parameter is an array indexed by channel, define CH_INDEX.
   If the parameter is an array indexed by ch and queue, define CH_Q_INDEX. */
#define CH_INDEX            (1  << 29)
#define CH_Q_INDEX          (2  << 29)

/* for channel parameters, use either RX or TX define to indicate that the
   parameter is a TX or RX only parameter.  Ex: RxBufSize is an RX parameter. */
#define CH_DIRECTION        (1  << 30)
#define RX                  (1  << 30)
#define TX                  (0  << 30)

/* various shifts, defines, and macros used by the code below */
#define DEV_MASK            (0xf)
#define INDEX_SHIFT         29
#define GROUP_SHIFT         7
#define NAME_MASK           (3  << 27)
#define INDEX_MASK          (3  << 29)
#define SUBSTRUCTURE_MASK   (3  <<  5)
#define GROUP_MASK          (7  <<  7)
#define DEV_CHECK(type, dev) (((type & DEV(DEV_MASK))>>23) == dev) 
    
/* the parameter table structure */

typedef struct XXX
  {
   const  char *pszKey;
   const  unsigned int Type;
   size_t Offset;
   const  unsigned int Default;
   const  unsigned int LowValue;
   const  unsigned int HighValue;
  }DEVICE_PARAMS;

#define MAX_SUB_STRUCT 3

typedef struct 
          {
          void   *sub_struct;
          bit32u sub_struct_size;
          bit32u sub_index_size1;
          bit32u sub_index_size2;
          }SUB_STRUCT;

typedef struct
         {
         const char *key;
         const char *keyparm;
         bit32u errorval;
         }CONFIG_PARAMS;

int cpswHalUtlParamsControl(void *HalDev,OS_FUNCTIONS *OsFunc,const DEVICE_PARAMS *pp,SUB_STRUCT *SubStruct, const char *Key, int Action, void *Value);
int cpswHalUtlParamsDump(void *HalDev,OS_FUNCTIONS *OsFunc,const DEVICE_PARAMS *pp);
int cpswHalUtlParamsGetConfigArray(void *HalDev,OS_FUNCTIONS *OsFunc,const DEVICE_PARAMS *DeviceParams,SUB_STRUCT *SubStructs,
                                   char *sectionname,char *pSKey,const char *pWKey,int loops,bit32u err,int more);
int cpswHalUtlParamsGetConfig(void *HalDev,OS_FUNCTIONS *OsFunc,const CONFIG_PARAMS *pp,const DEVICE_PARAMS *DeviceParams,SUB_STRUCT *SubStructs);
int cpswHalUtlParamsCheckAllParams(void *HalDev,OS_FUNCTIONS *OsFunc,const DEVICE_PARAMS *DeviceParams);
int cpswHalUtlParamsInit(void *HalDev,OS_FUNCTIONS *OsFunc,const DEVICE_PARAMS *DeviceParams);

#endif
