/***********************************************************************************
 *                                                                      
 *                  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: scheduler_pkt.h
 * 
 * 		Purpose:	  Header file for Egress DRR scheduler 
 *
 ************************************************************************************
 *
 * 		History:
 *
 * 		Date			Comment										By
 *		---------------------------------------------------------------------------
 *
 *		03/17/02		Created										Uday Naik
 *
 *************************************************************************************/


#ifndef __EGRESS_SCHEDULER_DRR_H__
#define __EGRESS_SCHEDULER_DRR_H__

/*************************************************************************************

 ALL THE BELOW NEED TO MOVE TO DL_SYSTEM_H

 */

/*
 * Ring id for scratch ring (from dl_system.h --- MOVE THIS TO DL_SYSTEM.H
 */

#define	EGRESS_SCHEDULER_DEQUEUE_RING_ID					SCHEDULER_TO_QM_SCR_RING
#define	EGRESS_SCHEDULER_DEQUEUE_RING_FULL_VALUE			inp_state_scr_ring5_full

/* Need 16 words of 0 to initialize xfer registers 0..15. Set this up correctly. 
 * Right now points to channel 0, location 0
 */

#ifndef 		SRAM_ZERO_BLOCK
#define 		SRAM_ZERO_BLOCK   		0
#endif

#ifndef SIG_NONE
#define SIG_NONE	0
#define SIG_DONE	1
#endif


/***************************************************************************************/

#include <ixp.h>

/***************************************************************************************/

/*
 *	ISO C99: 7.18 Integer types <stdint.h> : For now define them here
 */

#ifndef _STDINT_H
#define _STDINT_H   1

/* Exact integral types.  */
/* Signed.  */

typedef signed char     int8_t;
typedef short int       int16_t;
typedef int             int32_t;
typedef long long int   int64_t;

/* Unsigned.  */

typedef unsigned char           uint8_t;
typedef unsigned short int      uint16_t;
typedef unsigned int            uint32_t;
typedef unsigned long long int  uint64_t;

#endif /* _STDINT_H */.

#ifndef INLINE
#define INLINE __forceinline
#endif


/*************************************************************************************
 *
 * Constants for the algorithm. These should be replaced with import vars to make 
 * the code more configurable
 *
 ************************************************************************************/

/* Number of ports */

#define 		NUMBER_OF_PORTS              16

/* Bit vector that says which ports have credit. Set this up appropriately. For e.g.
 * if there are only 4 ports, then set it up as 0xf. For now we will set up all 16 
 * ports
 */

#define 		PORT_INITIAL_CREDIT_VECTOR	 0xffff


/* Number of queues per port */

#define 		NUMBER_OF_QUEUES_PER_PORT    16

/* Queue Mask */

#define		    QUEUE_MASK					((1 << NUMBER_OF_QUEUES_PER_PORT) - 1)

/* The port and queue in the port are encoded into one id. LSB 4 bits are used for 
 * queue id and then 4 bits for port id
 */

#define 		NUMBER_OF_BITS_FOR_QUEUE	4

/* bits for port */

#define 		NUMBER_OF_BITS_FOR_PORT		4

/* MTU for the media */

#define		 	MTU							(9*1024)

/* Number of bits used to encode the packet size */

#define 		BITS_FOR_PACKET_LENGTH          7

/* units in which packet size and queue credit increments are counted */

#define			CHUNK_SIZE                   (1 << BITS_FOR_PACKET_LENGTH)


/* Maximum number of packets in flight */
/* MAX_IN_FLIGHT is 16 in MPHY_16 mode, and 32 in other modes */
#if TX_PHY_MODE == MPHY_16	
#define 		MAX_IN_FLIGHT			16
#else	/* not MPHY_16  mode */
#define 		MAX_IN_FLIGHT			32
#endif /* end of #if TX_PHY_MODE == MPHY_16 */	

				
/*************************************************************************************
 *
 *
 * For each port there are 8 words in local memory. (16 * 8 = 128 words)
 *
 *
 * portScheduleVector			: Bit vector for which queues have credit > 0 
 *								  (Uses NUMBER_OF_QUEUES_PER_PORT bits in the vector)
 *
 * portCurrentQueueMask         : Used to round robin among queues in a port 
 *
 * portQueueEmptyVector			: Bit vector for which queues have data for a port 
 *
 * portPacketsScheduled			: Packets scheduled for this port
 *
 * portCurrentCredit			: Current WRR credit for port
 *
 * portWeight:					: Weight for the port
 *
 * portReserved[2]				: Reserved
 *
 *
 * For each queue there are 2 words in local memory (256 * 2 = 512 words)
 *
 * queueCurrentCredit			: Current Credit for the queue
 *
 * queueCreditIncrement         : The credit increment to be given to a queue at the
 *								  end of every round
 *
 *
 *************************************************************************************/

/* The below define fields in the port data structure */

typedef __declspec(local_mem shared aligned(32)) struct __port_struct
{

	uint32_t	portScheduleVector;
	uint32_t	portCurrentQueueMask;
	uint32_t	portQueueEmptyVector;
	uint32_t	portPacketsScheduled;
	uint32_t	portCurrentCredit;
	uint32_t	portWeight;
	uint32_t	portReserved[2];

} port_t;

typedef __declspec(local_mem shared aligned(8)) struct __queue_struct
{

	int32_t		queueCurrentCredit;
	uint32_t	queueCreditIncrement;

} queue_t;	

/* define an array of ports in local memory */

extern  __declspec(local_mem shared aligned(32)) port_t globalPorts[NUMBER_OF_PORTS];
												
/* define an array of queues in local memory */

extern  queue_t globalQueues[NUMBER_OF_PORTS * NUMBER_OF_QUEUES_PER_PORT];

/* define a global bit vector for ports which have data */

extern __declspec(shared) uint32_t	globalPortEmptyVector;
extern __declspec(shared) uint32_t	globalPortCreditVector;
extern __declspec(shared) uint32_t  globalPortMask;

/* define a global signal for inter thread signaling */

extern volatile SIGNAL sig_prevThread;

// Array of read transfer registers holding packets transmitted count. These
// are written via a reflect write by the tx block
#if(TX_PHY_MODE == SPHY_1_32)

__declspec(visible dram_read_reg) uint32_t	transmit_count ;

#else

#ifdef TX_IN_UCODE

__declspec(visible dram_read_reg)	uint32_t	transmit_count0, transmit_count1,
						transmit_count2, transmit_count3, transmit_count4,
						transmit_count5, transmit_count6, transmit_count7;		

#else

__declspec(visible dram_read_reg) uint32_t	transmit_count[16] ;

#endif
#endif

															 
/*************************************************************************************

 QM to Scheduler message 		

 *************************************************************************************/

typedef __declspec(packed)	struct __qm_message_t 
{
	union 
	{
		struct
		{
			uint32_t	valid						:1;			/* valid bit */
			uint32_t	enqueueDequeueTransition	:1;			/* reserved  */
			uint32_t 	invalidDequeue				:1;			/* invalid dequeue */
			uint32_t	reserved					:1;			/* reserved */
			uint32_t	packetLength				:8;			/* packet length */
			uint32_t	reserved_2					:12;		/* reserved */

#ifdef WORKAROUND

			uint32_t	portNumber					:4;
			uint32_t	queueNumber					:4;	

#else
			union 
			{

				struct
				{
				
					uint32_t	portNumber			:4;			/* port # */
					uint32_t	queueNumber			:4;			/* queue # in port */

				};

				uint32_t		queueId				:8;			/* queue id # */

			};

#endif

		};

		uint32_t value;
	};
	

} qm_message_t;

/*************************************************************************************/


#endif 		/* __EGRESS_SCHEDULER_DRR_H__ */


/**************************************************************************************/