/*
 * Copyright (c) 2004-2005 Endace Technology Ltd, Hamilton, New Zealand.
 * All rights reserved.
 *
 * This source code is proprietary to Endace Technology Limited and no part
 * of it may be redistributed, published or disclosed except as outlined in
 * the written contract supplied with this product.
 *
 * $Id: dagipf_types.h 6096 2007-01-19 02:59:08Z lipi $
 */

#ifndef DAGIPF_TYPES_H
#define DAGIPF_TYPES_H


/* C Standard Library headers. */
#if defined (__linux__) || defined (__FreeBSD__)
#include <inttypes.h>
#endif

/**
 * \file
 * \brief Data types for coprocessor registers [to be excluded from API]
 *
 * This is really low-level stuff, used by the API implementation, not
 * meant for the users of the packet filtering API.
 */


/** Each header mask memory region is 312b wide and 16 entries deep. */
#define HEADER_MASK_REGION_BYTES 624

/** Colour memory is 36b wide and 512k entries deep, but only 16b are used in each entry. 
 * Treat it as an array of uint16_t.
 */
#define COLOUR_MEMORY_BYTES 2*512*1024

/** Output memory is 256b wide and 16 entries deep. */
#define OUTPUT_MEMORY_BYTES 512


/** main_control register. */
typedef struct main_control_t
{
	volatile uint32_t go : 1;
	volatile uint32_t auto_inc_enable : 1;
	volatile uint32_t unused : 30;

} main_control_t;

/** search_control register.
 * Enable/disable specific search features. */
typedef struct search_control_t
{
	volatile uint32_t search_check_0 : 1;
	volatile uint32_t search_check_1 : 1;
	volatile uint32_t search_check_2 : 1;
	volatile uint32_t search_check_3 : 1;
	volatile uint32_t search_check_4 : 1;
	volatile uint32_t pattern_check : 1;
	volatile uint32_t ttl_check : 1;
	volatile uint32_t length_check : 1;
	volatile uint32_t unused : 24;

} search_control_t;

/** search_tags register. */
typedef struct search_tags_t
{
	volatile uint32_t tag_e : 4; /**< Search Register E */
	volatile uint32_t tag_d : 4; /**< Search Register D */
	volatile uint32_t tag_c : 4; /**< Search Register C */
	volatile uint32_t tag_b : 4; /**< Search Register B */
	volatile uint32_t tag_p : 4; /**< Search Register for Payload */
	volatile uint32_t unused : 12;

} search_tags_t;

/** memory_select_address register. */
typedef struct memory_select_t
{
	volatile uint32_t mem_addr : 20;      /**< Bits  0-19.  Sets the address for memory being accessed. */
	volatile uint32_t mem_select_lsb : 8; /**< Bits 20-27.  Selects a region within the memory space. */
	volatile uint32_t sram_b : 1;         /**< Bit 28.      Selects SRAM B. */
	volatile uint32_t sram_a : 1;         /**< Bit 29.      Selects SRAM A. */
	volatile uint32_t mem_select_msb : 2; /**< Bits 30-31.  Selects one of four memory spaces. */

} memory_select_t;

/** memory_data_high register. */
typedef struct memory_data_high_t
{
	volatile uint32_t mem_addr : 4; /**< Bits 0-3.  Upper 4 bits of data written/read to/from a 36-bit memory. */
	volatile uint32_t unused : 28;  /**< Bits 4-31. */

} memory_data_high_t;

/** min_max_ip_length register. */
typedef struct ip_length_t
{
	volatile uint32_t length_min : 16; /**< Bits  0-15. The minimum value (inclusive) for the IP length comparison. */
	volatile uint32_t length_max : 16; /**< Bits 16-31. The maximum value (inclusive) for the IP length comparison. */

} ip_length_t;

/** min_max_ttl register. */
typedef struct ttl_t
{
	volatile uint32_t ttl_min : 8; /**< Bits  0-7. The minimum value (inclusive) for the TTL comparison. */
	volatile uint32_t ttl_max : 8; /**< Bits  8-15. The maximum value (inclusive) for the TTL comparison. */
	volatile uint32_t unused : 16; /**< Bits 16-31. */

} ttl_t;

/** layer3_protocols_a register. */
typedef struct layer3_protocols_a_t
{
	volatile uint32_t l3_proto_2 : 16; /**< Bits  0-15 inclusive. Selects HMA region 2 on match. */
	volatile uint32_t l3_proto_3 : 16; /**< Bits 16-31 inclusive. Selects HMA region 3 on match. */

} layer3_protocols_a_t;

/** layer3_protocols_a register. */
typedef struct layer3_protocols_b_t
{
	volatile uint32_t l3_proto_0 : 16; /**< Bits  0-15 inclusive. Selects HMA region 0 on match. */
	volatile uint32_t l3_proto_1 : 16; /**< Bits 16-31 inclusive. Selects HMA region 1 on match. */

} layer3_protocols_b_t;

/** layer4_protocols register. */
typedef struct layer4_protocols_t
{
	volatile uint32_t l4_proto_0 : 8; /**< Bits  0-7 inclusive.  Selects HMA region 0 on match. */
	volatile uint32_t l4_proto_1 : 8; /**< Bits  8-15 inclusive. Selects HMA region 1 on match. */
	volatile uint32_t l4_proto_2 : 8; /**< Bits 16-23 inclusive. Selects HMA region 2 on match. */
	volatile uint32_t l4_proto_3 : 8; /**< Bits 24-31 inclusive. Selects HMA region 3 on match. */

} layer4_protocols_t;


/** Registers and offsets in the CP_IP1 register space. */
typedef struct ip_copro_registers 
{
	volatile main_control_t main_control;              /**< 0x00 */
	volatile search_control_t search_control;          /**< 0x04 */
	volatile search_tags_t search_tags;                /**< 0x08 */
	volatile memory_select_t memory_select_address;    /**< 0x0c */
	volatile uint32_t memory_data_low;                 /**< 0x10 */
	volatile memory_data_high_t memory_data_high;      /**< 0x14 */
	volatile ip_length_t ip_length;                    /**< 0x18 */
	volatile ttl_t ttl;                                /**< 0x1c */
	volatile layer3_protocols_a_t layer3_protocols_a;  /**< 0x20 */
	volatile layer3_protocols_b_t layer3_protocols_b;  /**< 0x24 */
	volatile layer4_protocols_t layer4_protocols;      /**< 0x28 */
	volatile uint32_t results_reg_invert_a;            /**< 0x2c */
	volatile uint32_t results_reg_invert_b;            /**< 0x30 */
	volatile uint32_t results_reg_invert_c;            /**< 0x34 */
	volatile uint32_t results_reg_invert_d;            /**< 0x38 */

} ip_copro_registers_t;


/* Masks for accessing registers in 32-bit chunks. */

/* search_tags register. */
#define tag_e_mask 0x0000000f
#define tag_d_mask 0x000000f0
#define tag_c_mask 0x00000f00
#define tag_b_mask 0x0000f000
#define tag_p_mask 0x000f0000

/* memory_select_address register. */
#define mem_addr_lo_mask    0x000fffff
#define mem_select_lsb_mask 0x3ff00000
#define mem_select_msb_mask 0xc0000000

/* memory_data_high register. */
#define mem_addr_hi_mask 0x0000000f

/* min_max_ip_length register. */
#define length_min_mask 0x0000ffff
#define length_max_mask 0xffff0000

/* min_max_ttl register. */
#define ttl_min_mask 0x000000ff
#define ttl_max_mask 0x0000ff00

/* layer3_protocols_b register. */
#define l3_proto_0_mask 0x0000ffff
#define l3_proto_1_mask 0xffff0000

/* layer3_protocols_a register. */
#define l3_proto_2_mask 0x0000ffff
#define l3_proto_3_mask 0xffff0000

/* layer4_protocols register. */
#define l4_proto_0_mask 0x000000ff
#define l4_proto_1_mask 0x0000ff00
#define l4_proto_2_mask 0x00ff0000
#define l4_proto_3_mask 0xff000000


/* Other enumerated types. */

/** A 2-bit field encoded in mem_select_msb. */
typedef enum mem_select_msb_t
{
	HMA_MEMORY            = 0x00,
	COLOUR_CONTROL_MEMORY = 0x01,
	OUTPUT_MASK_MEMORY    = 0x02

} mem_select_msb_t;

/** A 10-bit field encoded in mem_select_lsb. */
typedef enum mem_select_lsb_t
{
	SRAM_B = (1 << 8),
	SRAM_A = (1 << 9)

} mem_select_lsb_t;

/** A 4-bit field encoded in mem_select_lsb(3:0), ie bits 20-23 of the memory_select_address. */
typedef enum hma_strips
{
	STRIP_0 = 0x0, /**< Bits 143-128 of Search Register A. */
	STRIP_1 = 0x1, /**< Bits 127-96 of Search Register A. */
	STRIP_2 = 0x2, /**< Bits  95-64 of Search Register A. */
	STRIP_3 = 0x3, /**< Bits  63-32 of Search Register A. */
	STRIP_4 = 0x4, /**< Bits  31-0 of Search Register A. */
	STRIP_5 = 0x5, /**< Bits  67-64 of Search Register B. */
	STRIP_6 = 0x6, /**< Bits  63-32 of Search Register B. */
	STRIP_7 = 0x7, /**< Bits  31-0 of Search Register B. */
	STRIP_8 = 0x8, /**< Bits  31-0 of Search Register C. */
	STRIP_9 = 0x9, /**< Bits  31-0 of Search Register D. */
	STRIP_A = 0xa  /**< Bits  31-0 of Search Register E. */

} hma_strips_t;


#endif /* DAGIPF_TYPES_H */
