/*******************************************************************************
 *                            Intel Proprietary
 *
 * Copyright (c) 1998-2002 By Intel Corporation.  All rights reserved.  
 * No part of this program or publication may be reproduced, transmitted,
 * transcribed, stored in a retrieval system, or translated into any language
 * or computer language in any form or by any means, electronic, mechanical,
 * magnetic, optical, chemical, manual, or otherwise, without the prior
 * written permission of:
 *                        Intel Corporation
 *                        2200 Mission College Blvd.
 *                        Santa Clara, CA  95052-8119
 *******************************************************************************/


#ifndef	__IPV4_FWDER_MICROC_H__
#define	__IPV4_FWDER_MICROC_H__

/*
 * include files
 */


#include "ixptypes.h"
#include "dl_system.h"
#include "ixp_lib.h"
#include "ixp_ipv4.c"
#include "ipv4_fwder_uc.h"


/*
 * Until a header file defines these ...
 */

typedef	unsigned int	uint32_t;
typedef	int				int32_t;
typedef	unsigned char	uint8_t;
typedef	unsigned short	uint16_t;

/**
 *************************************************************************
 * @defgroup Ipv4Fwder IPV4 Forwarder Microblock
 * IPV4 Forwarder Microblock
 *
 * @purpose 
 *     This group implements the IPV4 Forwarder Microblock.
 ************************************************************************/

#define	NEXTHOP_INFO_SIZE			16	
#define	NEXTHOP_INFO_SIZE_LW		4			

/**
 *************************************************************************
 * @ingroup Ipv4Fwder
 * Nexthop Information structure
 *
 * @purpose
 *     This structure stores the information useful in forwarding
 *     the packet.
 *
 * @see nexthop_info_t
 ************************************************************************/
typedef	__declspec(packed) struct	nexthop_info_s	
{
	unsigned int reserved1:24;
	unsigned int flags:8;

	unsigned int fabricPortId:8;
	unsigned int nexthopIdType:4;
	unsigned int reserved2:4;
	unsigned int nexthopId:16;

	uint16_t	mtu;
	uint16_t	outputPort;

	uint32_t	reserved3;
} nexthop_info_t;

/*
 * macros to access the nexthop information
 */
#define	GET_NH_ID(a)		(a).nexthopId
#define	GET_NH_BLADE_ID(a)	(a).fabricPortId
#define	GET_NH_PORT(a)		(a).outputPort
#define	GET_NH_FLAGS(a)		(a).flags
#define	GET_NH_MTU(a)		(a).mtu
#define	GET_NH_ID_TYPE(a)	(a).nexthopIdType

/**
 *************************************************************************
 * @ingroup Ipv4Fwder
 * IPV4 Forwarder Control Block Information structure
 *
 * @purpose
 *     This structure stores the dynamic configuration information for the
 *	   microblock. This information should be in SRAM.
 *
 * @see ipv4_fwder_control_block_t
 ************************************************************************/

#define	IPV4_FWDER_MAX_PORTS	32	/**< @ingroup Ipv4Fwder Number of ports supported */

typedef	__declspec(packed) struct	ipv4_fwder_control_block_s
{
	uint32_t	portStatus;	/* supports IPV4_FWDER_MAX_PORTS ports */
	uint32_t	reserved[3];
} ipv4_fwder_control_block_t;

/*
 * internal macros to access the meta data
 */

#define	DL_META_GET_INPUT_PORT()		dlMeta.inputPort
#define	DL_META_GET_PACKET_SIZE()		dlMeta.packetSize
#define	DL_META_SET_OUTPUT_PORT(x)		dlMeta.outputPort = (x);
#define	DL_META_SET_FABRIC_PORT(x)		dlMeta.fabricPort = (x);
#define	DL_META_SET_NEXTHOP_ID(x)		dlMeta.nextHopId = (x);
#define	DL_META_GET_NEXTHOP_ID()		dlMeta.nextHopId
#define	DL_META_SET_NEXTHOP_ID_TYPE(x)	dlMeta.nhidType = (x);
#define	DL_META_GET_NEXTHOP_ID_TYPE()	dlMeta.nhidType



/*
 * for debugging
 */
#define	LOG(x,y)		Ipv4FwderDbgLogWait((x),(y))

/**
 *************************************************************************
 * @ingroup Ipv4Fwder
 * IPV4 Forwarder per port statistics
 *
 * @purpose
 *     	This structure stores the packet statistics per port. The statistics
 *		are maintained as 32bit counters.
 *
 * @see ipv4_fwder_me_stat_t
 ************************************************************************/
typedef	struct	ipv4_fwder_me_stat_s
{

	uint32_t	rx;			/* packets received */
	uint32_t	fwd;		/* packets fwded */
	uint32_t	drop;		/* packets dropped */
	uint32_t	excp;		/* packets sent as exception */
	uint32_t	badHdr;		/* packets with bad header */
	uint32_t	badLen;		/* packets with bad IP length field */
	uint32_t	badTtl;		/* packets with expired TTL */
	uint32_t	noRoute;	/* packets with no route to dest */
	uint32_t	tooSmall;	/* packets truncated */

} ipv4_fwder_me_stat_t;


#ifdef	IPV4_COUNTERS
	
#define	IPV4_INCR_RX(a)			Ipv4FwderIncrCounter((uint32_t*)(a),0)
#define	IPV4_INCR_FWD(a)		Ipv4FwderIncrCounter((uint32_t*)(a),1)
#define	IPV4_INCR_DROP(a)		Ipv4FwderIncrCounter((uint32_t*)(a),2)
#define	IPV4_INCR_EXCP(a)		Ipv4FwderIncrCounter((uint32_t*)(a),3)
#define	IPV4_INCR_BADHDR(a)		Ipv4FwderIncrCounter((uint32_t*)(a),4)
#define	IPV4_INCR_BADLEN(a)		Ipv4FwderIncrCounter((uint32_t*)(a),5)
#define	IPV4_INCR_BADTTL(a)		Ipv4FwderIncrCounter((uint32_t*)(a),6)
#define	IPV4_INCR_NOROUTE(a)	Ipv4FwderIncrCounter((uint32_t*)(a),7)
#define	IPV4_INCR_TOOSMALL(a)	Ipv4FwderIncrCounter((uint32_t*)(a),8)

#else

	/* these should turn off */
#define	IPV4_INCR_RX(a)		
#define	IPV4_INCR_FWD(a)
#define	IPV4_INCR_DROP(a)
#define	IPV4_INCR_EXCP(a)
#define	IPV4_INCR_BADHDR(a)
#define	IPV4_INCR_BADLEN(a)
#define	IPV4_INCR_BADTTL(a)
#define	IPV4_INCR_NOROUTE(a)
#define	IPV4_INCR_TOOSMALL(a)

#endif

/*
 * global variables
 */
extern	ipv4_fwder_me_stat_t	*pIpv4FwderCounterBase;

#ifndef	INLINE	
#define	INLINE	static __forceinline
#endif

/*
 *	By default Ipv4Fwder() is inline. However, if you want it as a function
 *	overide IPV4_INLINE.
 */
#ifndef	IPV4_INLINE
#define	IPV4_INLINE		INLINE
#endif

#endif	/*__IPV4_FWDER_UC_H__  */