/*
 *---------------------------------------------------------------------------
 *
 *                  I N T E L   P R O P R I E T A R Y
 *
 *     COPYRIGHT (c)  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,  CALIFORNIA  95052-8119
 *
 *---------------------------------------------------------------------------
 */

#ifndef __ETHERNET_IPV4_C__
#define __ETHERNET_IPV4_C__

/*
 *	XXX - IPv4 and PPP microblock seem to be using UINT. They all should be 
 *	converted to standard types.
 */

typedef	unsigned int UINT;


/*
 * include files
 */

#include "dl_system.h"


#ifdef	BID_NEXT_BLOCK
#if	(BID_NEXT_BLOCK != IPV4_NEXT1)
#undef	BID_NEXT_BLOCK
#define	BID_NEXT_BLOCK	IPV4_NEXT1
#endif
#endif


#include "dl_source.c"
#include "ether.c"
#include "ipv4_fwder.c"


/*
 * 	ETHERNET_IPV4_kickstart()
 *
 *	 Description: 
 *
 *	Kick starts IPV4 Forwarder blocks across the 4 MEs
 *	(1) when the system initialization is complete.
 *	(2) signal thread 0 on beginning ME after which the
 *  thread order is maintained by DL functions.
 *
 *	All the MEs (and threads) running IPV4 Forwader call 
 *	this function. Only thread0 of first ME would execute 
 *	this fully. Other threads of first ME and all the
 *	threads on other MEs would continue and call the
 *	dl_source(DL_THREAD_ORDER,0x0), and wait for signal
 *	from previous thread. This would result in thread0
 *	of first ME kickstarting the whole chain.
 *
 *
 * 	Outputs:
 *	
 *		None.
 *
 *	Inputs
 *
 *		None.
 *
 *
 *	CONSTANTS
 *
 *
 *	Size: 
 *		N/A
 */
INLINE	ETHERNET_IPV4_kickstart(void)
{

	int tmp = L2_TABLE_SRAM_BASE;

#ifdef	IPV4_START_ME

	SIGNAL	system_init_signal;

	if (ctx()==0)
	{
		int sig;
		// issue self signal
		sig = __signal_number(&dl_sig_prev) << 3;
		local_csr_write(local_csr_same_me_signal,sig);

		// now initialize and wait on system init signal
		__assign_relative_register(&system_init_signal,ME_INIT_SIGNAL);

		// wait for system init signal
		wait_for_all(&system_init_signal);
	}
#endif
}



/*------------------------------------------------------------------------
 * The main function of the dispatch loop
 *------------------------------------------------------------------------
 */
int main()
{

	/*
 	 * initialize the microblocks
 	 */

	dl_init();					//initialize the dispatch loop

	/*
	 * kickstart the IPV4 microengines
	 */
	ETHERNET_IPV4_kickstart();			// kickstart the ethernet-IPV4 functional pipeline

	dl_source(DL_THREAD_ORDER,0x0);	// begin with receiving packets in order

	/*
 	 * Execute microblocks in infinite loop
 	 */
	while(1)
	{

		SIGNAL			scratch_put;		// signal in scratch write
		SIGNAL_MASK		sig_mask = 0x0;		// mask of signals to wait on


		ether_decap_classify(pkt_hdr,ETHER_HEADER_OFFSET,DRAM_RD_REG);

		Ipv4Fwder(pkt_hdr,IP_HDR_OFFSET,pkt_hdr,IP_HDR_OFFSET,DRAM_RD_REG,DRAM_WR_REG);

		__implicit_read(&scratch_put);
		dl_qm_sink(&sig_mask,&scratch_put);		// dispose the packet

		dl_source(DL_THREAD_NO_ORDER,sig_mask);	// source next packet


	} // end while

	return 0;
}



#endif