/**
 * ============================================================================
 * = COPYRIGHT
 *              INTEL CORPORATION PROPRIETARY INFORMATION
 *   This software is supplied under the terms of a license agreement or
 *   nondisclosure agreement with Intel Corporation and may not be copied 
 *   or disclosed except in accordance with the terms in that agreement.
 *      Copyright (C) 2000-2001 Intel Corporation. All rights reserved.
 *
 * = PRODUCT
 *      Intel(r) IXA SDK 3.0 for the IXP2400 Network Processor
 *
 * = LIBRARY
 *      
 *
 * = MODULE
 *      IPv4 Forwarder Core Component
 *
 * = FILENAME
 *      ix_cc_ipv4_init.h
 *
 * = DESCRIPTION
 *      This file defines all data types and function prototypes required internaly by the 
 *      IPv4 CCI module.
 *
 * = AUTHOR
 *       Govindan Nair
 *       govindan.nair@intel.com
 *
 * = AKNOWLEDGEMENTS
 *      
 *
 * = CREATION TIME
 *      06/24/2002 5:30 PM
 *
 * = CHANGE HISTORY
 * ============================================================================
 * $Id: ix_cc_ipv4_init.h,v 1.24 2003/11/01 02:59:26 rranjeet Exp $
 */

#if !defined(__IX_CC_IPV4_INIT_H__)
#define __IX_CC_IPV4_INIT_H__


#if defined(__cplusplus)
extern "C" {
#endif /* end defined(__cplusplus) */


#define IX_CC_IPV4_DEST_IP_ZERO 0x0 /* 0.0.0.0 */
#define IX_CC_IPV4_DEST_IP_ZERO_MASK 0xffffffff /*255.255.255.255 ; this is to differentiate from default route */
#define IX_CC_IPV4_DEST_IP_LOOPBACK 0x7f000000 /* 127.0.0.0 */ 
#define IX_CC_IPV4_DEST_IP_LOOPBACK_MASK 0xff000000 /* 255.0.0.0 */
#define IX_CC_IPV4_DEST_IP_CLASS_D 0xe0000000
#define IX_CC_IPV4_DEST_IP_CLASS_D_MASK 0xe0000000
#define IX_CC_IPV4_DEST_IP_CLASS_E 0xf0000000
#define IX_CC_IPV4_DEST_IP_CLASS_E_MASK 0xf0000000
#define IX_CC_IPV4_DEST_IP_LIMITED_BROADCAST 0xffffffff /* 255.255.255.255 */
#define IX_CC_IPV4_DEST_IP_LIMITED_BROADCAST_MASK 0xffffffff /* 255.255.255.255 */


#define IX_CC_IPV4_DISABLE_PORT_STATUS IX_CC_PHYSICAL_IF_STATUS_DOWN
#define IX_CC_IPV4_ENABLE_PORT_STATUS IX_CC_PHYSICAL_IF_STATUS_UP


#define IX_CC_IPV4_REGISTRY_KEY_ROUTE_TABLE_SIZE  "IPV4/ROUTE_TABLE_SIZE_HINT"
#define IX_CC_IPV4_REGISTRY_KEY_ROUTE_TABLE_TYPE  "IPV4/ROUTE_TABLE_TYPE"
#define IX_CC_IPV4_REGISTRY_KEY_RTM_LOOKUP_MEMORY_TYPE  "IPV4/RTM_LOOKUP_MEMORY_TYPE"
#define IX_CC_IPV4_REGISTRY_KEY_RTM_LOOKUP_CHANNEL  "IPV4/RTM_LOOKUP_CHANNEL"
#define IX_CC_IPV4_REGISTRY_KEY_NEXT_HOP_TABLE_SIZE  "IPV4/NEXT_HOP_TABLE_SIZE_HINT"
#define IX_CC_IPV4_REGISTRY_KEY_NEXT_HOP_DATABASE_MEMORY_TYPE  "IPV4/NEXT_HOP_MEMORY_TYPE"
#define IX_CC_IPV4_REGISTRY_KEY_NEXT_HOP_DATABASE_CHANNEL  "IPV4/NEXT_HOP_DATABASE_CHANNEL"
#define IX_CC_IPV4_REGISTRY_KEY_LOCAL_BLADE_ID  "IPV4/LOCAL_BLADE_ID"
#define IX_CC_IPV4_REGISTRY_KEY_ME_FOR_IPV4  "IPV4/ME_FOR_IPV4"


#if (_IX_HARDWARE_TYPE_ == _IX_HW_2800_)

#define IX_CC_IPV4_SRAM_CHANNEL_DBCAST_TBL   2 /* Channel 2 for DBCAST table */
#define IX_CC_IPV4_SRAM_CHANNEL_CTRL_BLOCK   0 /* Chhnnel 0 for control block */
#define IX_CC_IPV4_RTM_LOOKUP_CHANNEL 1 /* RTM look up SRAM Channel number */

#else /* (_IX_HARDWARE_TYPE_ == _IX_HW_2800_) */

#if (_IX_BOARD_TYPE_ == _IX_IXDP2401_)
#define IX_CC_IPV4_SRAM_CHANNEL       0
#define IX_CC_IPV4_RTM_LOOKUP_CHANNEL 0 /* RTM look up SRAM Channel number */
#else
#define IX_CC_IPV4_SRAM_CHANNEL       1
#define IX_CC_IPV4_RTM_LOOKUP_CHANNEL 1 /* RTM look up SRAM Channel number */
#endif

#endif /* (_IX_HARDWARE_TYPE_ == _IX_HW_2800_) */


#define IX_CC_IPV4_NUMBER_OF_MB_COUNTERS 9  /* number of mucroblock counters */
#define IX_CC_IPV4_DBCAST_TABLE_BLOCK_SIZE 8 /* number of entries in dbcast table block */
#define IX_CC_IPV4_NUMBER_OF_DBCAST_TABLE_BLOCK 256 /* total number of dbcast table blocks */
#define IX_CC_IPV4_NUMBER_OF_DBCAST_EXTRA_BUCKETS 32 /* number of extra dbcast table blocks */
#define IX_CC_IPV4_SIZE_OF_CONTROL_BLOCK 4 /* size of microblock control block */

#if (_IX_HARDWARE_TYPE_ == _IX_HW_2800_)

#define IX_CC_IPV4_NUMBER_OF_SYMBOLS 5 /* number symbols to be patched */

#else /* (_IX_HARDWARE_TYPE_ == _IX_HW_2800_) */

#define IX_CC_IPV4_NUMBER_OF_SYMBOLS 6 /* number symbols to be patched */

#endif /* (_IX_HARDWARE_TYPE_ == _IX_HW_2800_) */


#define IX_CC_IPV4_COUNTER_OVERFLOW_TIME 13000 /* counter overflow time for 64 bit counter create */
#define IX_CC_IPV4_MILLISECONDS_PER_SECOND 1000 /* millseconds */



#define IX_CC_IPV4_ICMP_EVENT_PRIORITY 1



#define IX_CC_IPV4_ROUTE_TABLE_SIZE_HINT 256 /* Route table size hint */
#define IX_CC_IPV4_RTM_LOOKUP_TYPE  IX_CC_RTMV4_LKUP_SOFTWARE /* Route table type: TCAM or Software */
#define IX_CC_IPV4_RTM_LOOKUP_MEMORY_TYPE IX_CC_RTMV4_MEM_SRAM  /* Look up memory type SRAM or SDRAM */
#define IX_CC_IPV4_NEXT_HOP_TABLE_SIZE_HINT 256 /* Next hop data base table size hint */

#if (_IX_BOARD_TYPE_ == _IX_IXDP2401_)
/**
 * On IXDP2401 board we usually have only SRAM channel 0, so we move the
 * next hop table to DRAM to reduce utilization of SRAM controller 0.
 */
#ifdef NEXTHOP_INFO_SRAM
#define IX_CC_IPV4_NEXT_HOP_MEMORY_TYPE IX_CC_RTMV4_MEM_SRAM
#define IX_CC_IPV4_NEXT_HOP_CHANNEL     0
#else
#define IX_CC_IPV4_NEXT_HOP_MEMORY_TYPE IX_CC_RTMV4_MEM_SDRAM
#define IX_CC_IPV4_NEXT_HOP_CHANNEL     0
#endif /* NEXTHOP_INFO_SRAM*/

#else /* (_IX_BOARD_TYPE_ == _IX_IXDP2401_) */

#if (_IX_HARDWARE_TYPE_ == _IX_HW_2800_)
#define IX_CC_IPV4_NEXT_HOP_MEMORY_TYPE IX_CC_RTMV4_MEM_SRAM
#define IX_CC_IPV4_NEXT_HOP_CHANNEL     2
#else /* (_IX_HARDWARE_TYPE_ == _IX_HW_2800_) */
#define IX_CC_IPV4_NEXT_HOP_MEMORY_TYPE IX_CC_RTMV4_MEM_SRAM
#define IX_CC_IPV4_NEXT_HOP_CHANNEL     0
#endif /* (_IX_HARDWARE_TYPE_ == _IX_HW_2800_) */

#endif /* _IX_BOARD_TYPE_ == _IX_IXDP2401_ */


#if (_IX_HARDWARE_TYPE_ == _IX_HW_2800_)

#define IX_CC_IPV4_NUMBER_OF_MICROENGINES 16 /* number of microengines: 8 for IXP2400 */
#define IX_CC_IPV4_ME                     0x3007 /* Micro engine allocated for IPv4 are 0x00,0x01, 0x02, 0x14, and 0x15 */

#else

#define IX_CC_IPV4_NUMBER_OF_MICROENGINES 8 /* number of microengines: 8 for IXP2400 */
#define IX_CC_IPV4_ME 0x66 /* Micro engine allocated for IPv4 are 0x01,0x02,0x11,0x12 */

#endif /* (_IX_HARDWARE_TYPE_ == _IX_HW_2800_) */

#define IX_CC_IPV4_SYMBOL_SIZE 128 /* Maximum size of symbol name */
#define IX_CC_IPV4_PATCHNAME_STATS_TABLE "IPV4_STATS_TABLE_BASE" /* symbol name for statistics table */
#define IX_CC_IPV4_PATCHNAME_DBCAST_TABLE "DBCAST_TABLE_SRAM_BASE" /*symbol name for directed broadcast table*/
#define IX_CC_IPV4_PATCHNAME_CONTROL_BLOCK "CONTROL_BLOCK_SRAM_BASE" /* symbol name for control block name */
#define IX_CC_IPV4_PATCHNAME_ID   "THIS_BLADE_ID" /* symbol name for IPv4 Forwarder blade ID */
#define IX_CC_IPV4_PATCHNAME_TRIE_TABLE  "TRIE_TABLE_SRAM_BASE" /* symbol name for RTM Trie table base */

#if (_IX_BOARD_TYPE_ == _IX_IXDP2401_)

#ifdef NEXTHOP_INFO_SRAM
#define IX_CC_IPV4_PATCHNAME_NEXTHOP_TABLE "NEXTHOP_TABLE_SRAM_BASE"
#else
#define IX_CC_IPV4_PATCHNAME_NEXTHOP_TABLE "NEXTHOP_TABLE_SDRAM_BASE"
#endif

#else

#define IX_CC_IPV4_PATCHNAME_NEXTHOP_TABLE "NEXTHOP_TABLE_SRAM_BASE" /* symbol name for RTM next hop table */
#endif


#define TOTAL_NUMBER_OF_PORTS MAX_NUMBER_OF_BLADES * MAX_NUMBER_OF_PORTS_PER_BLADE


#define IX_IPV4_MEM_UINT32_READ(pAddr)\
(*pAddr);

#define IX_IPV4_MEM_UINT32_WRITE(pAddr,data)\
(*pAddr = data);

#ifdef IX_DEBUG
/*
 * Trace levels shall be used in the following way:
 * 0 - stay quite
 * 1 - trace major errors (default)
 * 2 - trace even minor errors plus major operations
 * 3 - trace all function calls except for very frequent or short timers
 * 4 - trace all functions, even periodic
 */
extern int ipTraceLevel;

#ifdef __KERNEL__
#define IpTrace(level, format, args...)  \
        (level > ipTraceLevel) ? : printk("IP: " format, ##args)
#else /* __KERNEL__ */
#define IpTrace(level, format, args...)  \
        (level > ipTraceLevel) ? : printf("IP: " format, ##args)
#endif /* __KERNEL__ */

#else /* not IX_DEBUG */

#define IpTrace(level, format, args...)

#endif /* not IX_DEBUG */


/**
 * TYPENAME: ix_cc_ipv4_prop_data
 * 
 * DESCRIPTION: This structure defines format for dynamic property data.
 *
 */

typedef struct ix_s_cc_ipv4_prop_data
{
    ix_uint32 ipAddr;
    ix_uint32 netMask;
} ix_cc_ipv4_prop_data;

/**
 * TYPENAME: ix_cc_ipv4_mb_ctrl
 * 
 * DESCRIPTION: This structure defines format for microblock
 * control data structure
 */

typedef struct ix_s_cc_ipv4_mb_ctrl
{
    ix_uint32 portForward;
    ix_uint32 reserved1;
    ix_uint32 reserved2;
    ix_uint32 reserved3;
} ix_cc_ipv4_mb_ctrl;

/**
 * TYPENAME: ix_cc_ipv4_fwd_stats
 * 
 * DESCRIPTION: This structure defines the format for IPV4 Statisrics
 *
 */
typedef struct ix_s_cc_ipv4_fwd_stats
{
    ix_uint32 ipv4CorestatsForwardingAttempted;
    ix_uint32 ipv4CorestatsLocalDelivery;
    ix_uint32 ipv4CorestatsNorouteFound;
    ix_uint32 ipv4CorestatsInvalidHeader;
    ix_uint32 ipv4CorestatsInvalidAddress;
    ix_uint32 ipv4CorestatsIncomingDatagrams;
} ix_cc_ipv4_fwd_stats;


/* In uCode we have ipv4 statistics per port
   we have to change it in Core Components so that no iligal use of 
   SCRATCH is done. This may be a temporary solution */
/**
 * TYPENAME: ix_cc_64bit_handles
 * 
 * DESCRIPTION: This structure defines the array of handles for 64-bit
 * counters maintained by the core component.
 * 
 * NOTE: This is a count of handles per port on a blade.
 *
 */
typedef struct ix_s_cc_64bit_handles
{
    /* 64-bit counter handles */
    ix_counter_64bit_handle ahCounter64BitHandle[IX_CC_IPV4_NUMBER_OF_MB_COUNTERS];

} ix_cc_64bit_handles;


/**
 * TYPENAME: ix_cc_ipv4_context
 * 
 * DESCRIPTION: This structure defines format for IPv4 Forwarder core component context
 *
 */
typedef struct ix_s_cc_ipv4_context
{
    ix_cc_handle hIpv4Handle; /* Handle of IPv4 Forwarder core component */
    ix_cc_rtmv4 hRtm; /* RTM handle  */

    /* In uCode we have ipv4 statistics per port
    we have to change it in Core Components so that no iligal use of 
    SCRATCH is done. This may be a temporary solution */
    ix_cc_64bit_handles counter64BitHandle[MAX_NUMBER_OF_PORTS_PER_BLADE];
	
#if IX_EXCLUDE_CCI
    ix_ossl_thread_t icmpThreadId; /* ICMP thread id - this is for level0 support */
#else
    ix_event_handle hEventHandle; /* Event handler handle  */
#endif
    ix_ossl_mutex_t ipv4Mutex; /* mutex id */
    ix_uint32* pMbBase; /* base address of micro block and IPv4 shared data */
    ix_uint32* pMbStatsBase; /* statistics base address created in SRAM  for microblock patching */
    ix_uint32* pMbDbBase;  /* source directed broadcast base address created in SRAM  for microblock patching */
    ix_cc_ipv4_mb_ctrl* pMbCbBase; /* control base address created in SRAM  for microblock patching */
    ix_buffer_free_list_handle hBufferFreeList; /* handle of free list buffer */
    ix_cc_ipv4_prop_data ipv4PropTable[TOTAL_NUMBER_OF_PORTS];
    ix_cc_ipv4_fwd_stats ipv4FwdStats; /* IPv4 core statistics */
} ix_cc_ipv4_context;




/**
 * TYPENAME: ix_cc_ipv4_registry_data
 * 
 * DESCRIPTION: This structure defines format for registry data.
 *
 */

typedef struct ix_s_cc_ipv4_registry_data
{
    ix_cc_rtmv4_config rtmConfig; /* RTM configuration information */
    ix_uint32 localBladeId; /* id of our blade */
    ix_uint32 meNumbers; /* Me numbers for IPv4 forwarder */
} ix_cc_ipv4_registry_data;


extern ix_cc_ipv4_context* g_pIpv4Context;

/**
 * NAME: _ix_cc_ipv4_retrieve_registry_data
 *
 * DESCRIPTION: This primitive will be used to retreive data from registry 
 * for a given property type.If there is no registry, then the data structure 
 * will be filled with data from header file.
 *           .
 * 
 * @Param:  - IN arg_pPropertyName - pointer to property name string 
 *
 * @Param:  - OUT arg_pPropertyValue - pointer to property value 
 *
 * @Return: IX_SUCCESS if successful or a valid error token for failure.
 *
 * Error Codes:
 * 
 * IX_CC_IPV4_ERROR_REGISTRY  - failed to access registry
 * 
 */


ix_error _ix_cc_ipv4_retrieve_registry_data(const char* arg_pPropertyName,
                                            ix_uint32* arg_pPropertyValue);




/**
 * NAME: _ix_cc_ipv4_registry
 *
 * DESCRIPTION: This primitive will be used to retreive data from registry for
 * all IPV4 static data and stored in ipv4RegistyData 
 *           .
 * 
 * @Param:  - IN 
 *
 * @Param:  - OUT 
 *
 * @Return: IX_SUCCESS if successful or a valid error token for failure.
 *
 * Error Codes:
 * 
 * IX_CC_IPV4_ERROR_REGISTRY  - not able to access registry.
 * 
 */

ix_error _ix_cc_ipv4_registry(void);

/**
 * NAME: _ix_cc_ipv4_alloc_symbols
 *
 * DESCRIPTION: This primitive will be used to alloc memory for symbols to be patched. 
 * 
 *           .
 * 
 * @Param:  - IN 
 *
 * @Param:  - OUT 
 *
 * @Return: IX_SUCCESS if successful or a valid error token for failure.
 *
 * Error Codes:
 * 
 * IX_CC_ERROR_OOM  - not able to allocate memory
 * 
 */

ix_error _ix_cc_ipv4_alloc_symbols(void);


/**
 * NAME: _ix_cc_ipv4_patch_symbols
 *
 * DESCRIPTION: This primitive will be used to patch symbols to ipv4 microblocks. 
 * 
 *           .
 * 
 * @Param:  - IN 
 *
 * @Param:  - OUT 
 *
 * @Return: IX_SUCCESS if successful or a valid error token for failure.
 *
 * Error Codes:
 * IX_CC_IPV4_ERROR_RTM - error from RTM module
 * IX_CC_IPV4_ERROR_FAILED_PATCHING - failed patching by calling resource manager function
 * 
 */
ix_error _ix_cc_ipv4_patch_symbols(void);


/**
 * NAME: _ix_cc_ipv4_create_64bit_counters
 *
 * DESCRIPTION: This primitive will be used to create 64 bit counters.   .
 * 
 * @Param:  - IN 
 *
 * @Param:  - OUT 
 *
 * @Return: IX_SUCCESS if successful or a valid error token for failure.
 *
 * Error Codes:
 * IX_CC_ERROR_OOM_64BIT_COUNTER - error in creating 64 bit counter
 * 
 * 
 */

ix_error _ix_cc_ipv4_create_64bit_counters(void);


/**
 * NAME: _ix_cc_ipv4_add_reserved_next_hops
 *
 * DESCRIPTION: This primitive will be used to add reserved next hops into RTM    .
 * 
 * @Param:  - IN 
 *
 * @Param:  - OUT 
 *
 * @Return: IX_SUCCESS if successful or a valid error token for failure.
 *
 * Error Codes:
 * IX_CC_IPV4_ERROR_RTM - error from RTM
 * 
 * 
 */

ix_error _ix_cc_ipv4_add_reserved_next_hops(void);



/**
 * NAME: _ix_cc_ipv4_add_invalid_routes
 *
 * DESCRIPTION: This primitive will be used to add martian addresses to RTM    .
 * 
 * @Param:  - IN 
 *
 * @Param:  - OUT 
 *
 * @Return: IX_SUCCESS if successful or a valid error token for failure.
 *
 * Error Codes:
 * IX_CC_IPV4_ERROR_RTM - error from RTM function call
 * 
 * 
 */

ix_error _ix_cc_ipv4_add_invalid_routes(void);



/**
 * NAME: _ix_cc_ipv4_configure_rtm
 *
 * DESCRIPTION: This primitive will be used to configure RTM    .
 * 
 * @Param:  - IN 
 *
 * @Param:  - OUT 
 *
 * @Return: IX_SUCCESS if successful or a valid error token for failure.
 *
 * Error Codes:
 * 
 * IX_CC_IPV4_ERROR_RTM - error from RTM function
 * 
 */

ix_error _ix_cc_ipv4_configure_rtm(void);


/**
 * NAME: _ix_cc_ipv4_register_message_handler
 *
 * DESCRIPTION: This primitive will be used to register message handler. 
 *
 * @Param:  - IN 
 *
 * @Param:  - OUT 
 *
 * @Return: IX_SUCCESS if successful or a valid error token for failure.
 *
 * Error Codes:
 * 
 * IX_CC_IPV4_ERROR_CCI - Error from CCI
 * 
 */

ix_error _ix_cc_ipv4_register_message_handler(void);


/**
 * NAME: _ix_cc_ipv4_register_cci_packet_handlers
 *
 * DESCRIPTION: This primitive will be used to register packet handler with CCI. 
 * @Param:  - IN 
 *
 * @Param:  - OUT 
 *
 * @Return: IX_SUCCESS if successful or a valid error token for failure.
 *
 * Error Codes:
 * 
 * IX_CC_IPV4_ERROR_CCI - error from CCI
 * 
 */

ix_error _ix_cc_ipv4_register_cci_packet_handlers(void);


/**
 * NAME: _ix_cc_ipv4_register_rm_packet_handlers
 *
 * DESCRIPTION: This primitive will be used to register packet handler with 
 * resource manager. This will be used in level 0 system
 *
 *
 * @Param:  - IN 
 *
 * @Param:  - OUT 
 *
 * @Return: IX_SUCCESS if successful or a valid error token for failure.
 *
 * Error Codes:
 * 
 * IX_CC_IPV4_ERROR_CCI - error from resource manager
 * 
 */

ix_error _ix_cc_ipv4_register_rm_packet_handlers(void);


/**
 * NAME: _ix_cc_ipv4_register_packet_handlers
 *
 * DESCRIPTION: This primitive will be used to register packet handlers. 
 * 
 *           .
 * 
 * @Param:  - IN 
 *
 * @Param:  - OUT 
 *
 * @Return: IX_SUCCESS if successful or a valid error token for failure.
 *
 * Error Codes:
 * 
 * IX_CC_IPV4_ERROR_CCI - error from CCI
 * 
 */

ix_error _ix_cc_ipv4_register_packet_handlers(void);




/**
 * NAME: _ix_cc_ipv4_add_icmp_event_handler
 *
 * DESCRIPTION: This primitive will be used to add icmp event handler.This is usefull to
 * drain ICMP packets priodically from queue           .
 * 
 * @Param:  - IN 
 *
 * @Param:  - OUT 
 *
 * @Return: IX_SUCCESS if successful or a valid error token for failure.
 *
 * Error Codes:
 * 
 * IX_CC_IPV4_ERROR_CCI - error from event handler
 * 
 */

ix_error _ix_cc_ipv4_add_icmp_event_handler(void);


/**
 * NAME: _ix_cc_ipv4_create_event_handler
 *
 * DESCRIPTION: This primitive is used to create event handler if there is no
 * CCI. Used needs to call _ix_cc_ipv4_icmp_send_message function periodically
 * to drain ICMP packets from queue.
 * 
 * @Param:  - IN 
 *
 * @Param:  - OUT 
 *
 * @Return: IX_SUCCESS if successful or a valid error token for failure.
 *
 * Error Codes:
 *  
 * IX_CC_IPV4_ERROR_CCI - error to create event handler
 * 
 */

ix_error _ix_cc_ipv4_create_event_handler(void* arg_pContext,
                                          ix_ossl_thread_t* arg_pEventId);




#if defined(__cplusplus)
}
#endif /* end defined(__cplusplus) */

#endif /* end !defined(__IX_CC_IPV4_INIT_H__) */
