//========================================================================
// Class Name	: DM9USB
// Purpose		: 
// Autor		: Richard Chuang
// Email		: 
// Description	: 
// Reference    : 
// Copyright    : Copyright (c) 2000-2007 Davicom Inc.  All rights reserved.
// -----------------------------------------------------------------------
// Version		: 3.0.0.2
// Update       : 2008-01-17
// Modified		: Richard Chung
// Description	: 
// -----------------------------------------------------------------------
// How to use: 
// 
#ifndef	_DAVICOM_DM9USB_H_
#define	_DAVICOM_DM9USB_H_

#include "stdafx.h"
#include "device.h"
#include "driver.h"


#include	<usb100.h>
#include	<usbdi.h>
#include	<usbtypes.h>

//#define	IMPL_STORE_AND_INDICATION

#define DM9601_VID		0x0A46
#define	DM9601_PID		0x9601

#define	DM9601_ADDR_OFFSET		0x00
#define	DM9601_DATA_OFFSET		0x04

#define	USB_BUFFER_SIZE		(DRIVER_BUFFER_SIZE+ETH_CRC_SIZE)

typedef	enum _DM9USB_REGISTER_TYPE_
{
	DM9_NCR = 0,
	DM9_NSR,
	DM9_TXCR,
	DM9_TXSR1,
	DM9_TXSR2,
	DM9_RXCR,
	DM9_RXSR,
	DM9_ROCR,
	DM9_BACKTH, /* 0x08 */
	DM9_PAUSETH,/* 0x09 */
	DM9_FLOW,
	DM9_EPCNTL,	/* 0x0B */
	DM9_EPADDR, /* 0x0C */
	DM9_EPLOW,
	DM9_EPHIGH,
	DM9_WCR,
	
	DM9_PAR0 = 0x10,
	DM9_PAR1,
	DM9_PAR2,
	DM9_PAR3,
	DM9_PAR4,
	DM9_PAR5,

	DM9_MAR0 = 0x16,
	DM9_MAR1,
	DM9_MAR2,
	DM9_MAR3,
	DM9_MAR4,
	DM9_MAR5,
	DM9_MAR6,
	DM9_MAR7,
		
	DM9_GPCR = 0x1E,
	DM9_GPR,
	
	DM9_VIDLOW = 0x28,
	DM9_VIDHIGH,
	DM9_PIDLOW = 0x2A,
	DM9_PIDHIGH,
	DM9_CHIPVER,
	
	DM9_USBADDR = 0xF0,
	DM9_RXCNT,
	DM9_TXCNT,
	DM9_USBCNTL,
} DM9USB_REGISTER_TYPE;
  
#define	DM9_USBSTAT	DM9_TXCNT

/******************************************************************************************
 *
 * Definition of DM9USB
 *
 *******************************************************************************************/
#define	DM9_SETUP_FRAME	0xBadBeef0
#define	DM9_MULTICAST_LIST	64

typedef	struct	_DM9_RX_DESCRIPTOR_
{
	U8		bState;
	U8		bStatus;
	U16		nLength;
} DM9_RX_DESCRIPTOR, *PDM9_RX_DESCRIPTOR;

/*******************************************************************************
 *
 * Device DM9USB characteristics
 *
 * - ISA device, program IO.
 *   Note: The theoretical maximum transfer rate of one ISA is only 8Mbps.
 * - On chip 16K byte memory, 3K for TX and 13K for RX.
 * - MAC is responsible to maintain the buffer chain.
 * - Provide word-level interface for EEPROM and PHY access.
 *
 *******************************************************************************/

class DM9USB : public NIC_DEVICE_OBJECT
{
public:
	//==========================================================================
	// Construction/Destruction
	//==========================================================================

	DM9USB::DM9USB(NIC_DRIVER_OBJECT *pUpper,PVOID pVoid);

	//==========================================================================
	// Member functions
	//==========================================================================
public:
	//--------------------------------------------------------------------------
	// Device control routines
	//--------------------------------------------------------------------------
	virtual void	DeviceStart( void);
	virtual void	DeviceReset( void);
	virtual void 	DeviceEnableInterrupt( void);
	virtual void 	DeviceDisableInterrupt( void);
	virtual U32 	DeviceGetInterruptStatus( void);
	virtual U32 	DeviceSetInterruptStatus( U32);
	virtual U32		DeviceGetReceiveStatus( void);
	virtual	U32		DeviceHardwareStatus(void);
	virtual	void 	DeviceEnableReceive(void);
	virtual	void 	DeviceDisableReceive(void);

protected:
	DWORD		GetChipID(void);				// Get ChipID from Register(abstract function)

	//--------------------------------------------------------------------------
	// overwrite routines with exception
	//--------------------------------------------------------------------------
	virtual void	InitialHardware(int);
	virtual void	InitialChip();	
	virtual WORD	LinkState_Get_BMSR(int i);	
	virtual WORD	LinkState_Get_DSCSR(LPWSTR head, int i);
	virtual WORD	LinkState_Get_DSCSR_EX(LPWSTR head, LPWSTR regname, int i);
	virtual WORD	LinkState_Get_SCFG(LPWSTR head, int i);
	
	virtual void	PrintMessageCtrl(WORD wLinkState);
	virtual BOOL	LinkState_LinkUp(int i);
	virtual int		LnkStat_GetLinkStatus(void);
	virtual	void	DbgDUMP_REGs(TCHAR *CFN);	
	//--------------------------------------------------------------------------
	// Device attributes and characteristics
	//--------------------------------------------------------------------------
	PCONFIG_PARAMETER	GetConfigureParameters(void);
	void				ValidateConfigurations(void);
	void				InitialEepromFieldPosition(void);
	//--------------------------------------------------------------------------
	// Device access routines
	//--------------------------------------------------------------------------
	DWORD	DeviceReadPort(DWORD dwPort);
	DWORD	DeviceWritePort(DWORD dwPort,DWORD dwValue);
	WORD	DeviceReadEeprom(DWORD dwAddress);
	WORD	DeviceWriteEeprom(DWORD dwAddress,WORD wValue);
	WORD	DeviceReadPhy(DWORD dwPhyRegister,DWORD dwOffset);
	WORD	DeviceWritePhy(DWORD dwPhyRegister,DWORD dwOffset,WORD wValue);
	
	// Device link state routines
	virtual WORD	GetLinkState();


	//--------------------------------------------------------------------------
	// Device access routines, new 
	//--------------------------------------------------------------------------
	virtual	DWORD	DeviceReadData(void);
	//virtual U32	DeviceWriteData(U32);
	virtual	PBYTE	DeviceReadData(PBYTE pbtBuffer, int nLength);
	virtual	PBYTE	DeviceWriteData(PBYTE pbtBuffer, int nLength);


	//--------------------------------------------------------------------------
	// There is no hardware control for transmission,
	// so, need to set one flag to control the tx.
	//--------------------------------------------------------------------------
	virtual	void 	DeviceEnableTransmit(void){ m_fTxEnabled=1; };
	virtual	void 	DeviceDisableTransmit(void){ m_fTxEnabled=0; };

	//--------------------------------------------------------------------------
	// Device hanlder routines
	//--------------------------------------------------------------------------
	virtual int		DeviceOnSetupFilter( U32);
	virtual void 	DeviceInterruptEventHandler( U32);
	virtual void 	DeviceResetPHYceiver(void);
	virtual int 	DeviceSend(PCQUEUE_GEN_HEADER);


	//--------------------------------------------------------------------------
	// class specific routines
	//--------------------------------------------------------------------------
	virtual	int		Dm9ValidateTxBuffers(void);
	virtual	int		Dm9LookupRxBuffers(void);
	
#ifdef	IMPL_DEVICE_ISR
	virtual	void	DeviceIsr(U32);
#endif

	//--------------------------------------------------------------------------
	/* USB CHANGED */
	//--------------------------------------------------------------------------
	void	InitialUsbParameters(USB_HANDLE hUsbHandle,LPCUSB_FUNCS lpUsbFuncs,LPCUSB_INTERFACE lpUsbInterface);
	//virtual BOOL	DeviceCheckForHang(void);
	virtual	void	DeviceHalt(void);
	virtual	void	DeviceOnTimer(void);
	

#ifdef	IMPL_STORE_AND_INDICATION
	virtual	void		DeviceOnTimer(void);
	CQueue				m_RQueue;
	CQueue				m_RQStandby;
#endif

	BOOL DeviceQueryTxResources(void);

	//==========================================================================
	// Data Member
	//==========================================================================
protected:

	CMutex				m_mutexTxValidateOut;
	CSpinlock			m_spinAccessToken;
	U32					m_uLastAddressPort;

	BOOL				m_fShutdownPending;
	BOOL				m_fTxSubmitted;
	BOOL				m_fTxPreloaded;	
	int					m_nPreloadedLength;
	int					m_nIoMode;
	int					m_nIoMaxPad;

	USB_HANDLE 			m_hUsbHandle;
	LPCUSB_FUNCS		m_lpUsbFuncs;
	LPCUSB_INTERFACE	m_lpUsbInterface;

	USB_PIPE			m_pipeIn,m_pipeOut;
};

#endif	//	_DAVICOM_DM9USB_H_
