//------------------------------------------------------------------------------------
//                                                                      
//                   I N T E L   P R O P R I E T A R Y                   
//                                                                       
//      COPYRIGHT (c)  2001 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                  
//                                                                       
//------------------------------------------------------------------------------------
/////////////////////////////////////////////////////////////////////////////
//
//
//      File Name: 	ipv4_fwder_dl.c
//
//      Purpose: 	This file contains dispatch loop for IPV4 Forwarding application.
//
//      History:
//
//
//      Date            Comment                         By
//      ---------------------------------------------------------------------
//
//      04/29/2002      Created                         Eswar Eduri
//
//
/////////////////////////////////////////////////////////////////////////////

// for dispatch loop constants
#include	"dl.h"

// ipv4_fwder related
#include "ipv4_fwder_uc.h"

// thread specific global variable to store the statistics base
int	counter_base;

/////////////////////////////////////////////////////////////////////////////////////////
//
// _ipv4_fwder_init()
//
//	 	Description: 
//
//
//	 	Outputs:
//			
//
//		Inputs
//
//			None.
//
//
//		CONSTANTS
//
//
//		Size: 
//			N/A
////////////////////////////////////////////////////////////////////////////////////////
void	_ipv4_fwder_init(void)
{

	// nothing to do here.

	// the base addresses will be constants

}

/////////////////////////////////////////////////////////////////////////////////////////
//
// _ipv4_fwder_kick_start()
//
//	 	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
////////////////////////////////////////////////////////////////////////////////////////
void	_ipv4_fwder_kick_start(void)
{
	// The IPV4 fwder code can run on single ME or multiple MEs. For
	// Point Reyes, we run this code on 4 MEs as a chain. These MEs
	// need to wait for the system initialization to complete which
	// is communicated by sending a signal. So, thread0 of the 
	// first ME waits for this signal. Once, this signal is received.
	// this thread kick starts the ME chain. (Actually any thread on
	// any ME can act as kick starter).

	// We need to know the ME number to get this right. If we pickup
	// different MEs, the following line has to be modified accordingly.
	// For Point Reyes, '0x1' is the first ME in the chain. 

#if	(ME_NUMBER == START_ME_NUMBER)

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

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

		LOG(0xbabe,0x0);

	}

#endif

}

/////////////////////////////////////////////////////////////////////////////////////////
//
// main()
//
//	 	Description: 
//			This function executes the IPV4 forwarder dispatch loop.
//
//	 	Outputs:
//			None.
//
//		Inputs
//			None.
//
//
//		CONSTANTS
//
//
//		Size: 
//			N/A
////////////////////////////////////////////////////////////////////////////////////////
int main()
{

	// the ipv4 Fwder dispatch loop.
	dl_ipv4_fwder_init();

	// first initialization
	_ipv4_fwder_init();

	// kick start the fwder first time around
	_ipv4_fwder_kick_start();

	// get packets in order
	dl_source(DL_THREAD_ORDER,0x0);

	// enter infinite loop
	while(1)
	{
		int	result;
		SIGNAL			sig_scratch;
		SIGNAL_MASK		sig_mask = 0x0;


		// call IPV4 Forwarder microblock
		_ipv4_fwder(iphdr,IP_HDR_OFFSET,iphdr,IP_HDR_OFFSET);

		// now, send the packet to next block.
		sig_mask = dl_qm_sink(sig_scratch);

		// then source next packet in strict order.
		dl_source(DL_THREAD_NO_ORDER,sig_mask);

	} // end while


} // end main