/* NETGEAR, Inc. 2000-2001 */

/**********************************************************************
*h*   
*
*   Name:       	hsm.h
* 
*   Description:  	
*		HSM related data structures. 
*  
*   Author:  
*  
*   History:  
*  
*h*   
**********************************************************************/

#pragma ident   "@(#)$RCSfile: hsm.h,v $ $Revision: 1.35 $ $Date: 2001/05/05 11:48:33 $ NETGEAR"

#ifndef _HSM_H
#define _HSM_H

#include "ga621.h"

/*** Define Constants ***/
#define	IP_HEADERLEN_OFFSET	14
#define	IP_SRCADDR			26
#define	IP_LENGTH_OFFSET	16
#define	IP_ALEN			4	/* Length of IP address in bytes */
#define	IP_PROTOCOL_TCP		6	/* protocol type for TCP packets */
#define	IP_PROTOCOL_UDP		17	/* protocol type for UDP packets */
#define	ETHER_HEADER_LENGTH	14
#define	UDP_HEADER_LENGTH	8
#define	TCP_CHECKSUM_OFFSET	16
#define	UDP_CHECKSUM_OFFSET	6

#define	HOTFIX_TCPPACKETLENGTH	64 /* Make sure this is even number */
/* The condifion for calculating  UDP checksum in driver is 
 * data length <=3. But
 * we cannot determine the IP options. So we are taking the hot fix
 * length in the following manner :
 * ETHER_HEADER_LENGTH+MAX(IP_HEADER)+UDP_HEADER_LENGTH+data_length.
 * 14+60+8+3+1. +1 is for making the length even for checksum 
 * calculation.
 */
#define	HOTFIX_UDPPACKETLENGTH	86 /* Make sure this is even number */

#ifdef _GA621_

#define 	MAXPRI_ADAPTER		4
#define		PRI_QUOTIENT		100

#elif _DP83815_

#define 	MAXPRI_ADAPTER		1

#endif

#define 	MAC_ADDR_LEN		6
#define 	PROMISCUOUS_ON 					0x1
#define 	ACCEPT_ALL_MULTICAST_ON 		0x2
#define 	ACCEPT_ALL_BROADCAST_ON 		0x4
#define 	MULTICAST_HASH_ENABLE 			0x8
#define 	ACCEPT_PERFECT_MATCH_ON 		0x10
#define 	ACCEPT_ALL_UNICAST_ON 			0x20
#define 	PROMISCUOUS_OFF 			0x40
#define 	ACCEPT_ALL_MULTICAST_OFF 		0x80

/*
 *	Defines for descriptor structure.
 */
#define		OWN		0x80000000   /* 31 bit	*/
#define		MORE		0x40000000   /* 30 bit	*/
#define		INTR		0x20000000   /* 29 bit	*/
#define		DESCOK		0x08000000   /* 27 bit	*/
/*
 * Transmit Status bit definitions.
 */
#define		TXA			0x04000000   /* 26 bit	*/
#define     TFU    		0x02000000   /* 25 bit	*/
#define     CRS    		0x01000000   /* 24 bit	*/
#define     TD    		0x00800000   /* 23 bit	*/
#define     OWC    		0x00200000   /* 21 bit	*/
#define     EC     		0x00100000   /* 20 bit	*/
#define     CCNT   		0x000F0000   /* 19-16 bit	*/

/*
 * Receive Status bit definitions.
 */
#define		RXA			0x04000000   /* 26 bit	*/
#define     RXO    		0x02000000   /* 25 bit	*/
#define     RXE_DEST   	0x01800000   /* 24 and 23 bit	*/
#define     RXE_LONG	0x00400000   /* 22 bit	*/
#define     RUNT    	0x00200000   /* 21 bit	*/
#define     ISE    		0x00100000   /* 20 bit	*/
#define     CRCE   		0x00080000   /* 19 bit	*/
#define     FAE   		0x00040000   /* 18 bit	*/
#define     LBP   		0x00020000   /* 17 bit	*/
#define     COL   		0x00010000   /* 16 bit	*/

#define		SUCCESS		0
#define		FAILURE		1

#define 	TCB_OK		SUCCESS
#define 	TCB_ERROR	FAILURE

/*
 For Indicating check-sum information to the
 adapter in the extended status
*/

#define 	UDPPKT 			0x00200000		/* bit 21 */
#define 	TCPPKT			0x00080000		/* bit 19 */
#define 	IPPKT			0x00020000		/* bit 17 */
#define 	UDPERR 			0x00400000		/* bit 22 */
#define 	TCPERR 			0x00100000		/* bit 20 */
#define 	IPERR 			0x00040000		/* bit 18 */
#define 	RXUDPON 		0x00200000		/* bit 21 */
#define 	RXTCPON			0x00080000		/* bit 19 */
#define 	RXIPON			0x00020000		/* bit 17 */
#define 	VPKT			0x00010000		/* bit 16 */

/*
 *	Defines for the Adapter Status.
 */
#define		ADAPTER_INITIALIZED			0x01
#define		ADAPTER_OPEN				0x02
#define		ADAPTER_RESETTING			0x04
#define		ADAPTER_OPEN_WAITFOR_RESET	0x08
#define		LINK_UP						0x10
#define		ADAPTER_SLEEPING			0x20
#define		ADAPTER_SUSPENDED			0x40

/*
 *	Defines for RCB.
 */
#define		RCB_FREE	0x00
#define		RCB_INUSE	0x01
#define		RCB_BAD		0x02

#define 	INTR_UNCLAIMED 	0
#define 	INTR_CLAIMED 	1

#define 	MAX_POWER_PTRN	4	/*	Max. number of pattern allowed	*/
#define		MAX_PTRN_SZ		128	/*	Max. Number of bytes for each pattern in 
									Pattern buffer memory.	*/
/*
 *	Defines for physical capabilities 
 */

#define		TX_CHKSUM_OFFLOAD_ON_GEN	0x00000001
#define		TX_CHKSUM_OFFLOAD_OFF_GEN	0x00000002

#define		TX_CHKSUM_OFFLOAD_ON_PP		0x00000004
#define		TX_CHKSUM_OFFLOAD_OFF_PP	0x00000008

#define		SET_RX_CHKSUM_OFFLOAD_ON	0x00000010
#define		SET_RX_CHKSUM_OFFLOAD_OFF	0x00000020

#define		RX_IP_CHKSUM_DISCARD_ON		0x00000040
#define		RX_IP_CHKSUM_DISCARD_OFF	0x00000080

#define		RX_TCP_CHKSUM_DISCARD_ON	0x00000100
#define		RX_TCP_CHKSUM_DISCARD_OFF	0x00000200

#define		RX_UDP_CHKSUM_DISCARD_ON	0x00000400
#define		RX_UDP_CHKSUM_DISCARD_OFF	0x00000800

#define		VLAN_TAG_REMOVAL_ON			0x00001000
#define		VLAN_TAG_DETECTION_ON		0x00002000

#define		AUTO_NEG_ON					0x00004000
#define		AUTO_NEG_OFF				0x00008000

#define		SET_WOL_ON					0x00010000
#define		SET_WOL_OFF					0x00020000

#define		VLAN_TAG_INSERTION_GEN_ON	0x00040000
#define		VLAN_TAG_INSERTION_GEN_OFF	0x00080000

#define		VLAN_TAG_INSERTION_PP_ON	0x00100000
#define		VLAN_TAG_INSERTION_PP_OFF	0x00200000

#define		JUMBO_FRAMES_ON				0x00400000
#define		JUMBO_FRAMES_OFF			0x00800000

#define		ADAPTER_PROMISCUOUS_ON		0x01000000

#define		BIG_ENDIAN					0x02000000

/*
 * Defines for Send and Receive routines.
 */

#define		RCB_THRESH		((RX_QUEUE_SZ) / 2)
#define 	WOL_FLAG		0x0000021F

#ifdef _GA621_

#define		RX_QUEUES		(RXDESC0 | RXDESC1 | RXDESC2 | RXDESC3)
#define		TX_QUEUES		(TXDESC0 | TXDESC1 | TXDESC2 | TXDESC3)

#endif

#define		TX_OK			DESCOK
#define		RX_OK			DESCOK
#define		RX_ERR			(ISE | CRCE | FAE | COL | RXA | RXO)
/*#define		TX_ERR			(TXA | TFU | OWC | EC | TD | CCNT)*/
#define		TX_ERR			(TXA | TFU | OWC | EC | TD)

#ifdef FWARE_DOWNLOAD

#define F_EAM				0x16
#define F_DR				0x1D
#define F_AR				0x1E
#define F_JAR				0x1F
#define F_START_ADDRESS		(0x8400)
#define F_VERIFY_ADDRESS	(0x8000)
#define DATA_SIZE			14592		

#endif

#ifdef PM_WOL

#define WKPAT0	0x00000020
#define WKPAT1	0x00000040
#define WKPAT2	0x00000080
#define WKPAT3	0x00000100

/* Revisit, reduce this */
#define MAX_PAT_LEN 200

#endif

#ifdef _GA621_

#define	CMDSTS_SIZE_MASK	0x0000ffff

#elif _DP83815_

#define	CMDSTS_SIZE_MASK	0x00000fff

#endif

#define		RESET_IN_PROGRESS	100
/*Cache line changes*/
#define		RX_BUF_ALIGNMENT	64

/*** Define Macros ***/
#define		SWAP_BYTE(in_byte) ((((in_byte) & 0xFF00) >> 8) | (((in_byte) & 0xFF) << 8))
#define		IP_HLEN(ip_verlen)	((ip_verlen & 0xf)<<2)

/*Check sum Macros*/

#define		UDP_PKT(Rcb)			((Rcb)->ExtSts & UDPPKT)
#define		TCP_PKT(Rcb)			((Rcb)->ExtSts & TCPPKT)
#define		IP_PKT(Rcb)			((Rcb)->ExtSts & IPPKT)
#define		UDPCHKSUMERR(Rcb)	((Rcb)->ExtSts & UDPERR)
#define		TCPCHKSUMERR(Rcb)	((Rcb)->ExtSts & TCPERR)
#define		IPCHKSUMERR(Rcb)	((Rcb)->ExtSts & IPERR)
#define		UDPCHKSUM(pAdapter)	((pAdapter)->ChksumFlags & RXUDPON)
#define		TCPCHKSUM(pAdapter)	((pAdapter)->ChksumFlags & RXTCPON)
#define		IPCHKSUM(pAdapter)	((pAdapter)->ChksumFlags & RXIPON)

#define 	RX_COMPLETE(pDesc) (pDesc) ? ((pDesc)->CmdSts & OWN) : 0

#define 	TX_DESC_SET_SIZE(pDesc,Size) \
				(pDesc)->CmdSts|=(CMDSTS_SIZE_MASK&(Size))

#define 	TX_DESC_SET_BUF(pDesc,pBuf) \
				(pDesc)->BufPtr=(UINT)(pBuf)

#define 	TX_DESC_SET_OWN(pDesc) \
				(pDesc)->CmdSts|=OWN

#define 	CLEAN_UP_DESC(CurrDesc)	\
				(CurrDesc)->CmdSts = 0;	\
				(CurrDesc)->ExtSts = 0;

/*#define 	TX_ERRORED(pDesc)		\
				((pDesc) ? ( !((pDesc)->CmdSts & TX_OK) ) : 0)
#define 	TX_ERRORED(pDesc)		\
				((pDesc) ? ( ((pDesc)->CmdSts & TX_ERR) ) : 0) 
	Both Bits should be checked ERR and !OK */
#define 	TX_ERRORED(pDesc)  ( ((pDesc)->CmdSts & TX_ERR) && (!((pDesc)->CmdSts & TX_OK)) ) 

#define 	RX_ERRORED(pDesc) ( ((pDesc)->CmdSts & (RX_ERR)) && (!((pDesc)->CmdSts & (RX_OK))) )
/*#define 	RX_ERRORED(pDesc) (!((pDesc)->CmdSts & (RX_OK))) */

#define 	TX_COMPLETE(pDesc) 			\
				((pDesc) ? (!( (pDesc)->CmdSts & (OWN) )) : 0)

#define 	GET_TCB_NEXT(pAdap,Priority) \
				(pAdap)->PriQue[(Priority)].pTcbListNext

#define 	GET_TCB_HEAD(pAdapter,Priority) \
				(pAdapter)->PriQue[Priority].pTcbListHead

#define 	GET_RCB_EXTENDED_STATUS(pAdapter, HsmRcb) \
			((HsmRcb)->pRxDp->ExtSts)

#define 	SET_TCB_HEAD(pAdapter,Priority,NewHead) \
				(pAdapter)->PriQue[Priority].pTcbListHead = (NewHead)

#define 	SET_TCB_NEXT(pAdapter, Priority, NewNext) \
				(pAdapter)->PriQue[Priority].pTcbListNext = (NewNext)

#define 	SET_RCB_HEAD(pAdapter,Priority,NewHead) \
				(pAdapter)->PriQue[Priority].pRcbListHead = (NewHead)

#define 	SET_RCB_TAIL(pAdapter, Priority, NewTail) \
				(pAdapter)->PriQue[Priority].pRcbListTail = (NewTail)

#ifdef _GA621_

#define 	SET_TCB_CHKSUM(pDesc,ChkSum) \
				(pDesc)->ExtSts |= (ChkSum)  
/*
 * 			Format for VLAN VTCI Bit Structure
 * 			2 Byte field arranged in the following manner
 * 			the VLAN ID is 12 bits, the CFI is 1 bit always 0
 * 			and the User_priority is 3 bits.
 *
 * 			VTCI[15:0] = VID[7:0],user_priority[2:0],CFI[0],VID[11:8]
 * 			
 * 			Set the VLAN ID Tag information and 
 * 			the  VLAN bit in the Desc.
 */
#define 	SET_VLAN(pDesc, Id, Priority) \
				(pDesc)->ExtSts |= (VPKT | Id | (Priority << 5))  

/*
 * 			Get the VLAN ID
 */
#define 	GET_VLAN_ID(pDesc) \
					(((pDesc->ExtSts >> 8) & 0xFF) | ((pDesc->ExtSts & 0xF) << 8))  

/*
 * 			Get the priority from the VLAN TAG.
 */
#define		GET_PRIORITY(pAdapter, pDesc) \
					((pDesc->ExtSts >> 5) & 0x7)

/*
 * 			Checks if the packet is a VLAN packet by looking
 * 			for the VPKT bit in the ExtSts.
 */
#define		IS_VLAN_PACKET(pDesc) \
					(pDesc->ExtSts & VPKT)

#elif _DP83815_

#define 	SET_TCB_CHKSUM(pDesc,ChkSum)

#endif

#define	 	TX_DESC_SET_MORE(pDesc,val) \
				( (val) ? ((pDesc)->CmdSts |= MORE) : \
				((pDesc)->CmdSts &= ~(MORE)) ) 

#define	 	TX_DESC_SET_INTR(Desc,Value) \
				( (Value) ? ((Desc)->CmdSts |= INTR) : \
				((Desc)->CmdSts &= ~(INTR)) ) 

#define 	INC_FREE_RX_DESC(pAdapter, Prio)  \
        		(pAdapter)->PriQue[Prio].iFreeRxDesc++

#define 	DEC_FREE_RX_DESC(pAdapter, Prio,count) \
        		(pAdapter)->PriQue[Prio].iFreeRxDesc -= (USHORT) count

#define 	FREE_RX_DESC(pAdapter, Prio)  \
        		(pAdapter)->PriQue[Prio].iFreeRxDesc

#define 	GET_RCB_NEXT(pAdapter, Priority) \
        		(pAdapter)->PriQue[Priority].pRcbListNext

#define 	GET_RCB_TAIL(pAdapter, Priority) \
        		(pAdapter)->PriQue[Priority].pRcbListTail

#define 	GET_RCB_HEAD(pAdapter, Priority) \
        		(pAdapter)->PriQue[Priority].pRcbListHead

#define 	SET_RCB_NEXT(pAdapter, Priority, NewNext) \
        		(pAdapter)->PriQue[Priority].pRcbListNext = (NewNext)

#define 	RCB_SET_MORE(pRcb) \
        	{ \
               	if((pRcb)->pRxDp->CmdSts & MORE) \
                   	(pRcb)->More = 1; \
               	else \
                   	LastFullPacket = (pRcb); \
        	}

#define 	DESC_CLEAR_OWN(pDesc) \
				(pDesc)->CmdSts &= ~(OWN)


#define		RX_DESC_GET_SIZE(pDesc) \
				(pDesc)->CmdSts & CMDSTS_SIZE_MASK

#define		UPDATE_RCB_TAIL(pRcbTail,pRcb) \
			{ \
				(pRcbTail)->pRxDp->link = (UINT) ((pRcb)->pRxDpPa);	\
				(pRcb)->pRxDp->link = 0;	\
				(pRcbTail)->pNext = (pRcb); \
				(pRcbTail) = (pRcb);  \
				(pRcbTail)->pNext = NULL; \
			}

#define 	INC_CURR_TCB(pAdapter, Priority, pTcb,count,base) \
 			((base) + \
 				(((UINT)pTcb - (UINT)base)/sizeof(HsmTCB) + count) % 	\
				pAdapter->PriQue[Priority].iMaxTxDesc)

#define		HsmMulticastDisable(pAdapter)	clear_mca_tbl((pAdapter))

#define 	HsmAttachBuffer(pRCB, Bufptr)  \
				(((pRCB)->pRxDp->BufPtr) = (UINT)(Bufptr))

#define		HsmIsRxPacketErrored(pRCB)	\
				(((pRCB)->pRxDp->CmdSts & RX_ERR)?1:0)

#define 	HsmSetRxdCmdSts(pRCB, Value)	\
				(((pRCB)->pRxDp->CmdSts) |= (UINT)(Value))

#define 	HsmClearRxdCmdSts(pRCB, Value)	\
				(((pRCB)->pRxDp->CmdSts) &= ~(Value))

#define		HsmGetMaxTxDesc(pAdapter, Prio)	\
				pAdapter->PriQue[Prio].iMaxTxDesc

#define		HsmGetMaxRxDesc(pAdapter, Prio)	\
				pAdapter->PriQue[Prio].iMaxRxDesc
/*
 * 	Macros to enable and disable interrupts.
 * 	Disabling the interrupts is done by writing a 0 to the IE flag in IER. 
 * 	Enabling the interrupts is done by writing a 1 to the IE flag in IER. 
 */

#define 	HsmEnableInterrupts(pAdapter)	\
				NsmRegWrite32((pAdapter)->pNsmContext, \
					((pAdapter)->RegAddr + IER), IE)

#define 	HsmDisableInterrupts(pAdapter)	\
				NsmRegWrite32((pAdapter)->pNsmContext, \
					((pAdapter)->RegAddr + IER), 0)


#ifdef ALLOC_PKTSTRUCT

/*
 * MACROS to Push and Pop the PktStruct's from the stack
 */


/*
 * Get the next free PktStruct from the stack
 */ 
#define HSMPOP_PKTSTRUCT(pAdapter, item) \
					NsmAcquireLock(pAdapter->pNsmContext, pAdapter->ListLock); \
					((GET_STACK_TOP(pAdapter)) <= -1) ? (item = NULL) : (item = (PktStruct *)((GET_STACK_PTR(pAdapter))[(GET_STACK_TOP(pAdapter))--])); \
					NsmReleaseLock(pAdapter->pNsmContext, pAdapter->ListLock)


/*
 * Increment the item counter and Push the free'd
 * PktStruct back into the stack
 */ 
#define HSMPUSH_PKTSTRUCT(pAdapter, item) \
					NsmAcquireLock(pAdapter->pNsmContext, pAdapter->ListLock); \
					((GET_STACK_PTR(pAdapter))[++(GET_STACK_TOP(pAdapter))]) = (PktStruct *)item; \
					NsmReleaseLock(pAdapter->pNsmContext, pAdapter->ListLock)

	
/*
 * MACRO's for Static Allocation of HsmPktStruct
 */

#define SET_STACK_TOP(pAdapter, no) \
				pAdapter->stacktop = no
				
#define GET_STACK_TOP(pAdapter) \
				pAdapter->stacktop
		
#define SET_STACK_PTR(pAdapter, item) \
				pAdapter->stackptr = (PktStruct **)item

#define GET_STACK_PTR(pAdapter) \
				pAdapter->stackptr

#endif /* ALLOC_PKTSTRUCT */

#ifdef PM_WOL
#define WAKE_STATE POWER_STATE_D0

#define WAKE_ON_LAN_MODES (MPR | PATM3 | PATM2 | PATM1 | PATM0 | PHYINT)

#define	ARR_OFFSET 		0	
#define	APAT_MASK		1	
#define	WKPAT_MASK		2

#define PAT_OFFSET	0x80

#define WKPAT (WKPAT0 | WKPAT1 | WKPAT2 | WKPAT3)

#define APAT_ALL (APAT0 | APAT1 | APAT2 | APAT3)

#ifdef DEBUG
UCHAR PatternHeadArray[] = {0xff,0xff, 0xff,
							0xff,0xff, 0xff,
							0x08, 0x0, 0x17,
							0x0b, 0x66, 0x16,
							0x08, 0x0};
#endif
#endif /* PM_WOL */
							
/*** Typedef Definitions ***/

typedef UCHAR MacAddr[6];

/*** Global (extern) Data Declarations ***/

/*
 *	Fragment Information Structure.
 */

typedef struct _FragInfo {

	UCHAR		*pFrag;		/*	Pointer to the fragment	*/
	USHORT		FragLen;	/*	Size of the fragment	*/

}FragInfo;

/*
 *	Packet Information structure.
 */

typedef struct _PktInfo { 

	UINT		NumFrags;				/*	Number of Fragments	*/
	FragInfo	FragArray[MAX_FRAGS];	/*	Fragment Array	*/
	PVOID		pOSCtrlBlk;				/*	Pointer to OS control block */
	UINT		ChkSum;
	UINT		TotalDataLength;
#ifdef LINK_AGGR
	PVOID		pDLHeader;
	UCHAR		SlowProtocolType;
#endif
#ifdef PRIORITY
	UCHAR		Priority;
#endif
} PktInfo;

/*
 *	Packet Structure.
 */

typedef struct _PktStruct { 

	USHORT		PktCount;			/*	No.of Packets to be transmitted	*/
	PktInfo		PktArray[MAX_PKTS];	/*	Array of packets	*/

} PktStruct;


/*
 *	Address Structure.
 */
typedef struct _AddrStruct {

	UCHAR 	*VirtAddr;	/*	pointer to Virtual address */
	UCHAR 	*PhysAddr;	/*	pointer to Physical address	*/
	UCHAR	*OrigPtr;	/* 	Pointer to the Virtual Address - before alingment */
	UINT	OrigSize;	/* 	Size of the buffer - before alingment */
	UINT	BufSize;	/*	Size of the buffer	*/
	/*UCHAR	OrigPtr;	 	Pointer to the Virtual Address - before alingment */
	/*UCHAR	OrigSize;	 	Size of the buffer - before alingment */
	/*USHORT	BufSize;		Size of the buffer	*/
	PVOID 	pCookie;	/*	Pointer to the cookie.	*/

} AddrStruct;


/*
 *	Descriptor structure.
 */
typedef struct BufDesc { 

	volatile	UINT	link;	/*	Link to the next descriptor.	*/
	volatile	UINT	BufPtr;	/*	Pointer to the buffer/fragment.	*/
	volatile	UINT	CmdSts;	/*	Status field */
	volatile	UINT	ExtSts;	/*	Extended status field */

} DevDesc;

/*
 *	Transmit Control Block.
 */

typedef struct _HsmTCB {

	struct _HsmTCB	*pNext;		/* Pointer to the Next TCB in the list.	*/

	PVOID 			pOsCtrlBlk; /* Pointer to the OS dependent packet structure
									eg. mblk pointer in Unix and pointer to 
									NDIS in Windows.	*/
	PVOID			pOldOsCtrlBlk;	 /* Pointer to the old packet if pull up of 
									    the packet has been done.	*/
	USHORT			TxStatus;		 /* Transmit Status and error conditions. */
	volatile DevDesc	*pStartDesc; 	/* Pointer to the first transmit
										descriptor for the current packet. */
	volatile DevDesc	*pStartDescPa; /* Pointer to the first transmit
										descriptor for the current packet.*/
	volatile DevDesc	*pEndDesc;		/* Pointer to the last transmit
										descriptor for the current packet. */
	volatile DevDesc	*pEndDescPa;	/* Pointer to the last transmit
										descriptor for the current packet. */
#ifdef LINK_AGGR
    UCHAR               SlowProtocolType;
#endif
} HsmTCB;

/*
 *	Receive Control Block.
 */

typedef struct _HsmRCB {

	struct _HsmRCB	*pNext;		/* Pointer to the Next TCB in the list.	*/
	PVOID			pOsCtrlBlk;
								/* Pointer to the OS dependent packet structure
									eg. mblk pointer in Unix and pointer to 
									NDIS in Windows. */
	volatile	DevDesc	*pRxDp;		/*Pointer to the corresponding recv. desc */
	volatile	DevDesc	*pRxDpPa;	/*Pointer to the corresponding recv. desc */

	UCHAR			*pDataBuf;	/*	Starting address (virtual) of the buffer
									given to the descriptor	*/

	UCHAR			Status;		/*	Status of the HsmRCB (FREE / INUSE / BAD) */
	UCHAR			More;		/*	Set to 1 if more the packet is spread across
									to the next HsmRCB, 0 otherwise	*/
	USHORT			PktSize;
	UINT			ExtSts;
	VOID 			*pCookie;

#ifdef PRIORITY
	UCHAR		Priority;	/* Priority got from VLAN ID */
#endif
	
} HsmRCB;

/*
 *	Priority Queue structure. 
 */
typedef struct _PriorityQue {

	USHORT		iMaxRxDesc;		/* Max. Rx Desc. for this priority.	*/
	USHORT		iFreeRxDesc;	/* No. of free Rx Desc. for this priority.	*/
	
	USHORT		iMaxTxDesc;		/* Max. Rx Desc. for this priority.	*/
	USHORT		iFreeTxDesc;	/* No of free Rx Desc. for this priority.	*/

	volatile DevDesc		*pTxdArray;		/* Pointer to the Txd array. */
	volatile DevDesc		*pTxdArrayPa;	/* Physical addr to Txd array. */

	volatile DevDesc		*pRxdArray;		/* Pointer to the Rxd array.	*/
	volatile DevDesc		*pRxdArrayPa;	/* Phys.Addr to Rxd array.	*/

	HsmTCB		*pTcbArray;		/* Pointer to the TCB array.	*/
	HsmRCB		*pRcbArray;		/* Pointer to the HsmRCB  array.	*/

	HsmTCB		*pTcbListHead;	/* Pointer to TCB head of this priority.	*/
	HsmTCB		*pTcbListNext;	/* Pointer to TCB next of this priority.	*/

	HsmRCB		*pRcbListHead;	/* Pointer to RCB head of this priority.	*/
	HsmRCB		*pRcbListNext;	/* Pointer to RCB next of this priority.	*/
	HsmRCB		*pRcbListTail;	/* Pointer to RCB tail next of this priority. */

} PriorityQue;


/*  
 *	Statistics Info structure 
 */

typedef struct _StatInfo
{
	UINT  txOkCount;				/* XMIT_OK */
	UINT  rxOkCount;				/* RCV_OK */
	UINT  txErrorCount;				/* XMIT_ERROR */
	UINT  rxErrorCount;				/* RCV_ERROR */
	UINT  txDroppedCount;
	UINT  rxDroppedCount;
	UINT  rxNoBufferCount;			/* RCV_NO_BUFFER */
									/* RCV_OVERRUN */
	UINT  txDirectedByteCount;		/* DIRECTED_BYTES_XMIT */
	UINT  txDirectedFrameCount;		/* DIRECTED_FRAMES_XMIT */
	UINT  txMulticastByteCount;		/* MULTICAST_BYTES_XMIT */
	UINT  txMulticastFrameCount;	/* MULTICAST_FRAMES_XMIT */
	UINT  txBroadcastByteCount;		/* BROADCAST_BYTES_XMIT */
	UINT  txBroadcastFrameCount;	/* BROADCAST_FRAMES_XMIT */

	UINT  rxDirectedByteCount;		/* DIRECTED_BYTES_RCV */
	UINT  rxDirectedFrameCount;		/* DIRECTED_FRAMES_RCV */
	UINT  rxMulticastByteCount;		/* MULTICAST_BYTES_RCV */
	UINT  rxMulticastFrameCount;	/* MULTICAST_FRAMES_RCV */
	UINT  rxBroadcastByteCount;		/* BROADCAST_BYTES_RCV */
	UINT  rxBroadcastFrameCount;	/* BROADCAST_FRAMES_RCV */
	UINT  rxCrcErrorCount;			/* RCV_CRC_ERROR */
	UINT  rxFaeCount;				/* RCV_ERROR_ALIGNMENT */
	UINT  txAbortCount;				/* RCV_ERROR_ALIGNMENT */
	UINT  txOneCollisionCount;		/* XMIT_ONE_COLLISION */
	UINT  txTotCollisionCount;		/* XMIT_ONE_COLLISION */
	UINT  txMultiCollisionCount;	/* XMIT_MORE_COLLISIONS */
	UINT  txExcessiveCollisionCount;/* XMIT_EXCESS_COLLISIONS */
	UINT  txDeferredCount;			/* XMIT_DEFERRED */
	UINT  txMaxCollisionCount;		/* XMIT_MAX_COLLISIONS */
	UINT  txLateCollisionCount;		/* XMIT_LATE_COLLISIONS */
	UINT  txUnderrunCount;			/* XMIT_UNDERRUN */
	UINT  txHeartbeatFailureCount;	/* XMIT_HEARTBEAT_FAILURE */
	UINT  txCrsLostCount;			/* XMIT_TIMES_CRS_LOST */
	UINT  rxSymbolErrors;
	UINT  rxFramesTooLong;
	UINT  txSQEerrors;
	UINT  AdapterReset;
	UINT  rxIRLErrors;			  
	UINT  rxBadOpcodes;			  
	UINT  rxPauseFrames;			  
	UINT  txPauseFrames;			  
#ifdef PM_WOL
	UINT  WakeOK;					/* The Number of times the card woke up */
#endif

} StatInfo;

typedef struct _mcast_hash_t { 

	UCHAR	MulticastAddr[6];
	struct _mcast_hash_t *next;

} mca_hash_t;

#ifdef LINK_AGGR
#define MAX_BUF 10
#define LACP_FLAG 0x02
#define SLOW_PROTOCOL_TYPE_BIG_ENDIAN 0x0988
/* 
 * Variables associated with Adapter 
 */

typedef struct _FuncPtrStruct {
	UCHAR	(*HsmSendPkt)();
	USHORT	(*HsmSendPkts)();
	VOID 	(*DrvSend)();
	UCHAR   (*HsmMulticastAdd)();
	UCHAR   (*HsmMulticastDelete)();
	UCHAR	(*HsmSetMacAddress)();
	UCHAR	(*HsmRxFilter)();
	UCHAR	(*HsmSetPhyCapabilities)();
	VOID	(*NsmSetPktStatus)();
	VOID	(*NsmIndicateLinkStatus)();
} FuncPtrStruct;
#endif

/*
 *	Adapter Context structure. 
 */
typedef struct _AdapterContext {

#ifdef _GA621_
	UINT TxDp[4][4];
	UINT RxDp[4][4];
#elif _DP83815_
	UINT TxDp[1][4];
	UINT RxDp[1][4];
#endif
	
	UCHAR		AdapterStatus;	/* Status of the adapter.	*/
	UINT		interruptStatus;
	UCHAR		PMFlag;			/* Flag used for Power Management.	*/
	PriorityQue	*PriQue;		/* Priority Queue.	*/
	UCHAR		NumPrio;		/* Number of priority queues supported.	*/
	UCHAR		TxNumPrio;		/* Number of priority queues supported in Tx.*/
	UCHAR		RxNumPrio;		/* Number of priority queues supported in Rx.*/
	UCHAR		OsPrio;			/* Number of priority queues supported by OS */
	USHORT		MaxPktSize;		/* Size of the Rx buffer.	*/
	StatInfo	MacStats;		/* Statistics structure. */
	mca_hash_t	*mca_tbl[128][16];	/* Multicast table	*/

	UCHAR		TxPriMapVal;	/* Priority mapping constant for Tx. */
	UCHAR		RxPriMapVal;	/* Priority mapping constant for Rx. */
	
	MacAddr		PermMacAddr;	/* Permanent MAC address.	*/
	MacAddr		CurrMacAddr;	/* Current MAC address. 	*/
	USHORT		MultiCastTableSize;	/* Multicast Table size.	*/
	USHORT		MediaSpeed;		/* Media Speed (10/100/1000 Mbps)	*/
	UCHAR		MediaType;		/* Media Type		*/
	UCHAR		DuplexMode;		/* Duplex Mode (FULL_DUPLEX / HALF_DUPLEX) */
	UINT		PhysCapabilities;	/* Physical Capabilities of the adapter	*/
	UINT		rxMatchControl;	/* Receive Filter value */

	UCHAR		IRQ;			/* IRQ value.	*/
	UCHAR		*RegAddr;		/* Memory space Address / IO space Address	*/
	USHORT		RegAddrSz;		/* Size of the register mapping.	*/

	PVOID		AdapterLock;	/* General purpose lock.	*/
	PVOID		TxLock;			/* Lock used for synchronizing transmission.*/
	

	AddrStruct	pDescList;		/* Pointer to Descriptor pool (both Txd,Rxd)*/
	PVOID		pTcbArray;		/* Pointer to TCB pool.	*/
	PVOID		pRcbArray;		/* Pointer to HsmRCB pool.	*/

	volatile	UINT SWIFlag;	/* Flag used for SWI processing. 	*/
	volatile	UINT TxrcmpFlag;/* Flag used for Tx reset processing. 	*/
	volatile	UINT TxEnableFlag;/* Flag used for Tx Idle. 	*/

	PVOID		pCookie;		/* Cookie for General purpose.	*/

	PVOID		pNsmContext;	/* Pointer to NSM context	*/

	UINT		phyAddress;
	UINT		TotTxdPhySz;	/* Total size of the Tx descriptors */
	UCHAR		CurrHoldOff;
#ifdef CHECKSUM
	UINT		ChksumFlags;
#endif
	/* Various Tunable parameters */
	USHORT		UserMediaSpeed;	/* User Set Media Speed (10/100/1000 Mbps)	*/
	UCHAR		UserDuplexMode;	/* User Set Duplex Mode (FULL_DUPLEX / HALF_DUPLEX) */
	USHORT		RxMaxDMASize;	/*	Rx MAX DMA	*/
	USHORT		TxMaxDMASize;	/*	Tx MAX DMA	*/
	ULONG		RxQueueSz[MAXPRI_ADAPTER]; /* The Recieve Descriptors for each priority*/
	ULONG		TxQueueSz[MAXPRI_ADAPTER]; /* The Transmit Descriptors for each priority*/
	UCHAR		NcBit;	/* IEEE Non Compliance Bit	*/
	UCHAR		IntrHoldoff; /* Interruput Holdoff */
	UCHAR		FlowControl;
	UCHAR		NsmPhySleep;	/* Set to 1 if the AUTONEG routine is to be used */
	UCHAR		RxFFLO;
	UCHAR		RxFFHI;
	UCHAR		RxSTLO;
	UCHAR		RxSTHI;
	UCHAR		TxDrth;			/*	Tx Drain Threshold */
	UCHAR		RxDrth;			/*	Rx Drain Threshold */
	UCHAR		TxFlth;			/*	Tx Fill Threshold */
	USHORT		PauseCounterVal; /* Pause Frames Counter Delay */
#ifdef PM_WOL
	UINT		CurrPowerStatus;
	UCHAR		PowerPattern[MAX_POWER_PTRN][MAX_PAT_LEN];	/* Power pattern array	*/
	UCHAR		PatternCnt;		/* Pattern count */
	UCHAR		MaskArray[MAX_POWER_PTRN][MAX_PAT_LEN/8 + 1];	/* Mask array	*/

	UINT		WakePatCount;

	UINT		PatLen[MAX_POWER_PTRN];

	UINT		pmcsr_val;

#endif
#ifdef LINK_AGGR
	/* 
	 * Following are the fields specific to Link Aggregation 
	 */
    USHORT                  Port;
    USHORT                  nFlags;
    FuncPtrStruct           FuncStruct;
    struct LacpRCB          *pLacpRCB;
    struct _AdapterContext  *pAggregatorContext;
    UCHAR					Slot_Number;
    UCHAR					Bus_Number;
	UINT					lacprxFilterFlag;
#endif
#ifdef FWARE_DOWNLOAD
	PVOID		FileHandle;
	UINT		FileLength;
#endif
	USHORT		VLANId;	/* Set to the VLAN ID for this card  it should contain
						 * the VLAN ID in the correct VTCI format, refer to documentation
						 * for the correct VTCI format. */
	UCHAR 		tbi;	/* For the TBI Card */
	
#ifdef ALLOC_PKTSTRUCT
	/*
	 * The following items are for static allocation
	 * of HsmPktStruct for Multiple Sends.
	 */
	CHAR		stacktop;	/* The number of Items in the stack */
	PktStruct	**stackptr;	/* The stack pointer */
	PVOID		ListLock; 	/* The List Lock for the PktStruct */
#endif
	
} AdapterContext, *pAdapterContext;


/*
 * Pause Frames Definitions.
 */
#define PAUSE_FRAMES_DISABLE     0x0
#define TX_PAUSE_FRAMES_ENABLE   0x1
#define RX_PAUSE_FRAMES_ENABLE   0x2
#define PAUSE_FRAMES_ENABLE      TX_PAUSE_FRAMES_ENABLE | RX_PAUSE_FRAMES_ENABLE

/*
 *	Multi List Structure used for Multicast address addition and deletion.
 */

typedef struct _MultiList {

	struct _MultiList	*Next;			/*	Link to next entry	*/
	UCHAR				MulticastAddr[6];	/* Multicast Address	*/

} MultiList;


/* Function prototypes */

extern VOID		HsmTxStart(AdapterContext	*pAdapter, UINT Priority);
extern VOID		HsmRxStart(AdapterContext	*pAdapter, UINT Priority);
extern UCHAR	HsmOpen(AdapterContext *pAdapter);
extern UCHAR	HsmClose(AdapterContext *pAdapter);
extern UCHAR   	HsmReset(AdapterContext *pAdapter, UINT aSynch);
extern VOID   	HsmMaskIntr(AdapterContext *pAdapter, UINT Mask);
extern UCHAR	HsmInitialize(AdapterContext *pAdapter);
extern UCHAR	HsmTxInit(AdapterContext	*pAdapter);
extern CHAR		HsmRxInit(AdapterContext	*pAdapter);
extern VOID		HsmUnInitialize(AdapterContext *pAdapter);
extern VOID		HsmFreeResources(AdapterContext	*pAdapter, UINT	errcode);
extern UCHAR	HsmInitContext(AdapterContext *pAdapter);
extern VOID		HsmInitRegs(AdapterContext	*pAdapter);
extern VOID		HsmCreateMapValue(AdapterContext *pAdapter);
extern UCHAR	HsmIsr(AdapterContext *pAdapter);
extern UCHAR	HsmInterruptPresent(AdapterContext *pAdapter);
extern VOID		HsmGetMacAddress( AdapterContext *pAdapter );
extern UCHAR	HsmSetMacAddress(AdapterContext *pAdapter, UCHAR *addr );
extern UCHAR	HsmGetStatistics(AdapterContext *pAdapter);
extern UCHAR	HsmClearStatistics(AdapterContext *pAdapter);
extern UCHAR	HsmRxFilter(AdapterContext *pAdapter, UINT  RxFilterFlags);
extern UCHAR	HsmMulticastAdd(AdapterContext *pAdapter, 
					MultiList  *pMultiList, UCHAR ReloadFlag);
extern UCHAR	HsmMultiCastDelete( AdapterContext *pAdapter, 
					MultiList *pMultiList);
extern VOID 	ReadMIBCounters(AdapterContext *pAdapter);
extern UCHAR 	GetHardwarePriority(AdapterContext *pAdap, UCHAR OsPriority);
extern UCHAR 	GetOsPriority(AdapterContext *pAdap, UCHAR AdapPriority);
#ifdef LINK_AGGR
extern USHORT	HsmSendPkts(AdapterContext *pAdapter, PktStruct *pPkts, 
					UCHAR Priority,USHORT StartIndex);
#else
extern USHORT	HsmSendPkts(AdapterContext *pAdapter, PktStruct *pPkts, 
					UCHAR Priority);
#endif
extern UCHAR	HsmSendPacket(AdapterContext *pAdapter, PktInfo *pPkt, 
					UCHAR Priority);
extern UCHAR	HsmSetPhyCapabilities(AdapterContext *pAdapter, UINT PhysFlags,UINT SetSpeeed);
/*extern UCHAR	HsmSetPhyCapabilities(AdapterContext *pAdapter, UINT PhysFlags);*/
extern VOID 	HsmTxCompleted(AdapterContext *pAdapter);
extern VOID 	HsmReplenishRcbs(AdapterContext *pAdapter, UCHAR Priority, 
					UINT LoadRxdp);
extern VOID 	HsmRxPackets(AdapterContext *pAdapter);
extern USHORT 	FreeTxDesc(AdapterContext *pAdapter,UCHAR Prio);

extern VOID 	WriteMiiReg(AdapterContext *pAdapter, UINT phyReg, UINT phyData);
extern UINT 	ReadMiiReg(AdapterContext *pAdapter, UINT phyReg);
extern VOID 	WriteMiiPreamble(AdapterContext *pAdapter,UINT * pMear);
extern VOID		WriteMiiIdle(AdapterContext *pAdapter, UINT * pMear);
extern VOID 	ReadEEWord (AdapterContext *, UINT *, UINT, USHORT *);
static VOID 	SetPromiscuousMode(AdapterContext *pAdapter, UCHAR Mode);

#ifdef PM_WOL

VOID HsmDumpPattern(AdapterContext *pAdapter);
UCHAR IsPowerPatternExsts(AdapterContext *pAdapter,UCHAR *PowerPattern, UCHAR *pPatternIdx, UINT PatternLen); 

UCHAR 
	HsmAddWakeupPattern(AdapterContext *pAdapter, UCHAR *PowerPattern, 
			UINT PatternLen, UINT MatchLen, UCHAR *MaskPtrn);
UCHAR 
	HsmEnableWakeupPattern(AdapterContext *pAdapter, UCHAR *PowerPattern, 
			UINT PatternLen);
UCHAR 
	HsmEnableWakeup(AdapterContext *pAdapter, UINT WakeType);

UCHAR 
	HsmDisableWakeup(AdapterContext *pAdapter, UINT WakeType);

UCHAR 
	HsmDisableWakeupPattern(AdapterContext *pAdapter, UCHAR *PowerPattern,
			UINT PatternLen);

UCHAR 
	HsmRemoveWakeupPattern(AdapterContext *pAdapter, UCHAR *PowerPattern,
			UINT	PatternLen, UCHAR *MaskPtrn);

UINT	HsmGetWakeStatus(AdapterContext *pAdapter);

VOID HsmChangeState(AdapterContext *pAdapter, UINT PmcsrVal);

UINT HsmGetLowestPowerState(AdapterContext *pAdapter);
UINT HsmPowerStateSupport(AdapterContext *pAdapter, UINT PowerState);

USHORT AddPattern(AdapterContext *pAdapter, UCHAR PatternIdx, 
			UCHAR *PowerPattern, UINT PatternLen, 
			UINT MatchLen, UCHAR *MaskPtrn);
#endif

#ifdef FWARE_DOWNLOAD

VOID HsmDownLoadFirmwareInit(AdapterContext *pAdapter);
VOID HsmDownLoadFirmwareWORD(AdapterContext *pAdapter, USHORT  frData);
UINT HsmStartFirmWareCode(AdapterContext *pAdapter);
UCHAR HsmVerifyDownLoad(AdapterContext *pAdapter);

#endif

/* Function HsmgetMulticastSize added on 17072000 -*/
extern UINT
HsmGetMulticastSize(
AdapterContext *pAdapter
);

/* Function HsmGetMulticastList added on 17072000 -*/
UINT
extern HsmGetMulticastList(
AdapterContext *pAdapter,
CHAR *Buffer,
UINT Size
);

#ifdef LINK_AGGR
extern void LacpAdapterStatusCheck(AdapterContext *p1);
extern void LacpSetMacAddress(AdapterContext *p1, UCHAR *p2);
extern void LacpMulticastAdd(AdapterContext *p1, MultiList *p2, UINT parm1, UCHAR parm2);
extern void LacpMulticastDelete(AdapterContext *p1, MultiList *p2);
extern void LacpTxCompleted(AdapterContext *p1, HsmTCB *p2);
extern void AggrRxPackets(AdapterContext *p1, HsmRCB *p2);
extern USHORT GetNumberOfLinks(AdapterContext *p1);
extern void LacpSetRxFilter(AdapterContext *p1, UINT parm1);
extern void LacpSetPhyCapabilities(AdapterContext *p1, UINT parm1, UINT parm2);
#endif


#ifdef ALLOC_PKTSTRUCT
extern UCHAR StackInit(pAdapterContext pAdapter);
extern VOID StackFree(pAdapterContext pAdapter);
#endif /* ALLOC_PKTSTRUCT */

VOID
Hsmchksum(
AdapterContext *pAdapter,
UCHAR   *pEtherTcpIpPkt, 
USHORT *ChkSum,
INT	Protocol
);


#endif  /* _HSM_H */

