/*****************************************************************************
 *                            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
 *****************************************************************************/

/**
 *****************************************************************************
 * @ingroup PppEncap
 * File:  ppp_encap_util.h
 * @description
 *        Utility file for PPP Encap microblock in egress pipeline.
 *****************************************************************************/

/*****************************************************************************
 *
 * Contents:
 *        Definitions of following functions:
 *            PppEncap_InitGprs   
 *			  PppEncap_SetSignal
 *            PppEncap_ClearSignal
 *            PppEncap_SetSignalPair
 *            PppEncap_ClearSignalPair
 *            PppEncap_saveSrctoSink
 *            PppEncap_ReadDram
 *            PppEncap_UpdateMetaData
 *            PppEncap_WritePppHeader
 *
 *****************************************************************************/

#ifndef __PPP_ENCAP_UTIL_C__
#define __PPP_ENCAP_UTIL_C__

#include <ppp_encap.h>
#include <dl_meta.c>

/*****************************************************************************
 * Abstract:
 *	Initialize the common globals in context relative gprs to save 
 *  instruction cycles.
 *
 * Side Effects:
 *    None
 *
 * Assumptions:
 * 	  None
 *****************************************************************************/
INLINE void										/* No return value 			 */
PppEncap_InitGprs()
{
	sigmask_phs1Default = __signals(&sig_next_thrd_2, &sig_sramRead);
	sigmask_phs2Default = __signals(&sig_next_thrd_3, &sig_dramRead);
	sigmask_phs3Default = __signals(&sig_next_thrd_4, &sig_sramWrite, &sig_dramWrite);
	sigmask_phs4Default = __signals(&sig_next_thrd_1, &sig_scratchRead, &sig_scratchWrite);
	scrRingSource = L2_ENCAP_SOURCE_SCR_RING << 2;
	scrRingSink = L2_ENCAP_SINK_SCR_RING <<2;
} /*PppEncap_init_gprs()*/

/*****************************************************************************
 * Abstract:
 *  Set a signal in a signal mask 
 *
 * Side Effects:
 *    None
 *
 * Assumptions:
 * 	  None
 *****************************************************************************/
INLINE  int								/* OUT: Signal mask	     			 */
PppEncap_SetSignal(					
			int io_sigmask, 			/* IN:	Signals mask				 */
			SIGNAL *pinSig)				/* IN:  Pointer to a signal			 */
{
	return(io_sigmask | ( 1 << __signal_number(pinSig)));
} /*PppEncap_SetSignal()*/

/*****************************************************************************
 * Abstract:
 *  Set a signal_pair in a signal mask 
 *
 * Side Effects:
 *    None
 *
 * Assumptions:
 * 	  None
 *****************************************************************************/
INLINE  int								/* OUT: Signal mask	     			 */							
PppEncap_SetSignalPair(					
			int io_sigmask, 			/* IN:	Signals mask				 */
			SIGNAL_PAIR *pinSigPair)	/* IN:  Pointer to a signal			 */
{
	return(io_sigmask | __signals(pinSigPair));
} /*PppEncap_SetSignalPair()*/

/*****************************************************************************
 * Abstract:
 *  Clear a signal from a signal mask 
 *
 * Side Effects:
 *    None
 *
 * Assumptions:
 * 	  None
 *****************************************************************************/
INLINE  int 							/* OUT: the signal mask				 */
PppEncap_ClearSignal(			
				int io_sigmask,			/* IN: signal mask 					 */
				SIGNAL * pinSig)		/* IN: pointer to a signal			 */
{
	return(io_sigmask & ~(1 << __signal_number(pinSig)));
} /*PppEncap_ClearSignal()*/

/*****************************************************************************
 * Abstract:
 *  Clear a signal_pair from a signal mask 
 *
 * Side Effects:
 *    None
 *
 * Assumptions:
 * 	  None
 *****************************************************************************/
INLINE  int 							/* OUT: the signal mask				 */
PppEncap_ClearSignalPair(			
				int io_sigmask,			/* IN: signal mask 					 */
				SIGNAL_PAIR * pinSigPair) /* IN: pointer to a signal		 */
{
	return(io_sigmask & ~(__signals(pinSigPair)));
} /*PppEncap_ClearSignalPair()*/

/*****************************************************************************
 * Abstract:
 *    Initialized hardware MSF registers.
 *
 * Side Effects:
 *    None
 *
 * Assumptions:
 *    None
 *
 *****************************************************************************/
INLINE void
PppEncap_saveSrctoSink(
void)
{
	sinkIfMessage.value[0] = srcIfMessage.value[0];
	sinkIfMessage.value[1] = srcIfMessage.value[1]; 
	sinkIfMessage.value[2] = srcIfMessage.value[2];	 
}

/*****************************************************************************
 * Abstract:
 *    Read 8 bytes from dram aroune Initialized hardware MSF registers.
 *
 * Side Effects:
 *    None
 *
 * Assumptions:
 *    None
 *
 *****************************************************************************/
INLINE
void PppEncap_ReadDram(					/* OUT: No return value			 	*/
	unsigned int inPayLoadOffset,		/* IN: Payload offset		 	 	*/ 
	unsigned int indramAddr,			/* IN: Beggining dram address  	 	*/
	unsigned int inNumb)				/* IN: Number of quadwords to read 	*/
{
	dram_read((__declspec(dram_read_reg) void *)&inPayload, 
			(volatile __declspec(dram) void *)(indramAddr + inPayLoadOffset), 
			inNumb, sig_done, &sig_dramRead);
}

/*****************************************************************************
 * Abstract:
 *    Update meta data with new offset, buffer size, and packet size
 *
 * Side Effects:
 *    None
 *
 * Assumptions:
 *    None
 *
 *****************************************************************************/
INLINE 
void PppEncap_UpdateMetaData(			/* OUT: No return value			 */
	void)
{
	dlMeta.bufferSize = inMetaData.bufferSize + PPP_L2_HEADER_SIZE;
	dlMeta.offset = inMetaData.offset - PPP_L2_HEADER_SIZE;
	dlMeta.packetSize	= inMetaData.packetSize + PPP_L2_HEADER_SIZE;
	// Flush the meta data to SRAM two LWs (1 to 2) 
	// of the meta data are flushed. 
	Dl_MetaFlushCacheSkip0(srcIfMessage.sopBufHandle, &sig_sramWrite, SIG_NONE, 2);
}	

/*****************************************************************************
 * Abstract:
 *    Write PPP header into dram just before payload.
 *
 * Side Effects:
 *    None
 *
 * Assumptions:
 *    None
 *
 *****************************************************************************/
INLINE
void PppEncap_WritePppHeader(			/* OUT: No return value			 */
	unsigned int inPayLoadOffset,		/* IN: Payload offset		 	 */ 
	unsigned int indramAddr)			/* IN: Beggining dram address  	 */
{
	unsigned offsetMod8 = inPayLoadOffset & 0x7;
	unsigned newOffset = inPayLoadOffset - 8;

	switch(offsetMod8)
	{
		case 0:
			outHdrPayload.value[0] = 0;
			outHdrPayload.value[1] = pppHeader;
			dram_write((__declspec(dram_write_reg) void *)&outHdrPayload, 
				(volatile __declspec(dram) void *)(indramAddr + newOffset), 
				1, sig_done, &sig_dramWrite);
			break;
		case 1:
			outHdrPayload.value[0] = 0;
			outHdrPayload.value[1] = pppHeader >> 8;
			outHdrPayload.value[2] = (pppHeader <<24) | (inPayload.value[0] & 0xFFFFFF);
			outHdrPayload.value[3] = inPayload.value[1];
			dram_write((__declspec(dram_write_reg) void *)&outHdrPayload, 
				(volatile __declspec(dram) void *)(indramAddr + newOffset), 
				2, sig_done, &sig_dramWrite);
			break;
		case 2:
			outHdrPayload.value[0] = 0;
			outHdrPayload.value[1] = pppHeader >> 16;
			outHdrPayload.value[2] = (pppHeader << 16) | (inPayload.value[0] & 0xFFFF);
			outHdrPayload.value[3] = inPayload.value[1];
			dram_write((__declspec(dram_write_reg) void *)&outHdrPayload, 
				(volatile __declspec(dram) void *)(indramAddr + newOffset), 
				2, sig_done, &sig_dramWrite);
			break;
		case 3:
			outHdrPayload.value[0] = 0;
			outHdrPayload.value[1] = pppHeader >> 24;
			outHdrPayload.value[2] = (pppHeader << 8) | (inPayload.value[0] & 0xFF);
			outHdrPayload.value[3] = inPayload.value[1];
			dram_write((__declspec(dram_write_reg) void *)&outHdrPayload, 
				(volatile __declspec(dram) void *)(indramAddr + newOffset), 
				2, sig_done, &sig_dramWrite);
			break;
		case 4:
			outHdrPayload.value[0] = (pppHeader << 8) | (inPayload.value[0] & 0xFF);
			outHdrPayload.value[1] = inPayload.value[1];
			dram_write((__declspec(dram_write_reg) void *)&outHdrPayload, 
				(volatile __declspec(dram) void *)(indramAddr + inPayLoadOffset), 
				1, sig_done, &sig_dramWrite);
			break;
		case 5:
			outHdrPayload.value[0] = pppHeader >> 8;
			outHdrPayload.value[1] = (pppHeader << 24) | (inPayload.value[1] & 0xFFFFFF);
			dram_write((__declspec(dram_write_reg) void *)&outHdrPayload, 
				(volatile __declspec(dram) void *)(indramAddr + inPayLoadOffset), 
				1, sig_done, &sig_dramWrite);
			break;
		case 6:
			outHdrPayload.value[0] = pppHeader >> 16;
			outHdrPayload.value[1] = (pppHeader << 16) | (inPayload.value[1] & 0xFFFF);
			dram_write((__declspec(dram_write_reg) void *)&outHdrPayload, 
				(volatile __declspec(dram) void *)(indramAddr + inPayLoadOffset), 
				1, sig_done, &sig_dramWrite);
			break;
		case 7:
			outHdrPayload.value[0] = pppHeader >> 24;
			outHdrPayload.value[1] = (pppHeader << 8) | (inPayload.value[1] & 0xFF);
			dram_write((__declspec(dram_write_reg) void *)&outHdrPayload, 
				(volatile __declspec(dram) void *)(indramAddr + inPayLoadOffset), 
				1, sig_done, &sig_dramWrite);
			break;
	}
}

#endif 		// __PPP_ENCAP_UTIL_C__
