⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dm9isa.cpp

📁 网络控制器dm9000的wince5.0驱动源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/******************************************************************************** *  * $Id: dm9000.cpp,v 1.8 2004/12/16 06:23:12 hychu Exp $ * * Copyright (c) 2000-2005 Davicom Inc.  All rights reserved. * ********************************************************************************/#include	"dm9isa.h"/******************************************************************************* * * * ********************************************************************************/CONFIG_PARAMETER	g_szDm9ConfigParams[] ={	{ CID_CONNECTION_TYPE, -1, NDIS_STRING_CONST("ConnectionType") },	{ CID_SLOT_NUMBER, -1, NDIS_STRING_CONST("SlotNumber")},	{ CID_BUFFER_PHYSICAL_ADDRESS, 0, NDIS_STRING_CONST("BufferPhysicalAddress")},	{ CID_TXBUFFER_NUMBER, 0x20, NDIS_STRING_CONST("XmitBuffer")},	{ CID_RXBUFFER_NUMBER, 0x10, NDIS_STRING_CONST("RecvBuffer")},	{ CID_ADAPTER_NUMBER, 0, NDIS_STRING_CONST("AdapterNumber")},	{ CID_IO_BASE_ADDRESS, 0x300, NDIS_STRING_CONST("IoAddress")},	{ CID_IO_RANGE, 0x10, NDIS_STRING_CONST("IoRange")},	{ CID_IRQ_NUMBER, 3, NDIS_STRING_CONST("IrqNumber")},	{ -1,-1,NULL}};/******************************************************************************* * * Device attributes and characteristics * ********************************************************************************/PCONFIG_PARAMETER	C_DM9000::DeviceConfigureParameters(void){	return (PCONFIG_PARAMETER)&g_szDm9ConfigParams[0];}void	C_DM9000::DeviceSetEepromFormat(void){	m_szEepromFormat[EID_MAC_ADDRESS] = 0;	m_szEepromFormat[EID_VENDOR_ID] = 8;	m_szEepromFormat[EID_PRODUCT_ID] = 10;}void	C_DM9000::EDeviceRegisterIoSpace(void){	NIC_DEVICE_OBJECT::EDeviceRegisterIoSpace();		U32	val;		val  = DeviceReadPort(0x2a);	val |= DeviceReadPort(0x2b)<<8;	val |= DeviceReadPort(0x28)<<16;	val |= DeviceReadPort(0x29)<<24;	DEBUG_PRINT((		TEXT("[dm9: Chip signature is %08X\r\n"), val		));	if( (DeviceReadPort(DM9_VIDL) != LOW_BYTE(DM9000_VID)) ||		(DeviceReadPort(DM9_VIDH) != HIGH_BYTE(DM9000_VID)) ||		(DeviceReadPort(DM9_PIDL) != LOW_BYTE(DM9000_PID)) ||		(DeviceReadPort(DM9_PIDH) != HIGH_BYTE(DM9000_PID)) )		THROW((ERR_STRING("Unknown device")));}void	C_DM9000::EDeviceValidateConfigurations(void){	NDIS_HANDLE		hndis = m_pUpper->GetNdisHandle();	// validate slot number	if( 		(m_szConfigures[CID_IO_BASE_ADDRESS] == -1) ||		(m_szConfigures[CID_IRQ_NUMBER] == -1) ) 		THROW(());	m_szCurrentSettings[SID_GEN_TRANSMIT_BUFFER_SPACE] = 		m_szConfigures[CID_TXBUFFER_NUMBER]		* ETH_MAX_FRAME_SIZE;	m_szCurrentSettings[SID_GEN_RECEIVE_BUFFER_SPACE] = 		m_szConfigures[CID_RXBUFFER_NUMBER]		* ETH_MAX_FRAME_SIZE;	m_szConfigures[CID_CHECK_FOR_HANG_PERIOD] = 3;	m_szConfigures[CID_IRQ_GEN_TYPE] = NdisInterruptLatched;	m_szConfigures[CID_IRQ_SHARED] = TRUE;	m_szConfigures[CID_IRQ_LEVEL] = 0x0F;	m_szConfigures[CID_INTERFACE_TYPE] = NdisInterfaceIsa;	m_szConfigures[CID_BUS_MASTER] = FALSE;	// set receive mode	// <5> discard long packet	// <4> discard CRC error packet	// <0> rx enable	m_szCurrentSettings[SID_OP_MODE] = MAKE_MASK3(5,4,0);	m_szCurrentSettings[SID_802_3_MAXIMUM_LIST_SIZE] = DM9_MULTICAST_LIST;}/******************************************************************************* * * Device access routines * ********************************************************************************/#define	ENTER_CRITICAL_SECTION	m_spinAccessToken.Lock();#define	LEAVE_CRITICAL_SECTION	m_spinAccessToken.Release();#define	VALIDATE_ADDR_PORT(p) \	if(m_uLastAddressPort != (p)) \		NdisRawWritePortUchar( \		m_szCurrentSettings[SID_PORT_BASE_ADDRESS] + DM9000_ADDR_OFFSET,  \		(U8) (m_uLastAddressPort=(U32(p))) )U32	C_DM9000::DeviceWritePort(	U32		uPort,	U32		uValue){	ENTER_CRITICAL_SECTION	VALIDATE_ADDR_PORT(uPort);	NdisRawWritePortUchar(		m_szCurrentSettings[SID_PORT_BASE_ADDRESS] + DM9000_DATA_OFFSET, 		(U8)uValue);	LEAVE_CRITICAL_SECTION		return uValue;}U32	C_DM9000::DeviceReadPort(	U32		uPort){	U16		val;	ENTER_CRITICAL_SECTION	VALIDATE_ADDR_PORT(uPort);	NdisRawReadPortUchar(		m_szCurrentSettings[SID_PORT_BASE_ADDRESS] + DM9000_DATA_OFFSET, &val);		LEAVE_CRITICAL_SECTION		return (U32)val;}U16	C_DM9000::DeviceReadEeprom(	U32		uWordAddress){	U16		highbyte,lowbyte;		// assign the register offset	DeviceWritePort(DM9_EPADDR,uWordAddress);		// issue EEPROM read command<2>	DeviceWritePort(DM9_EPCNTL,(1<<2));		// wait until status bit<0> cleared	// 80 uS, 5 times	if(!DevicePolling(DM9_EPCNTL,(1<<0),0x00,80,5))		return (U16)-1;		// stop command	DeviceWritePort(DM9_EPCNTL,0);	// retrive data	lowbyte  = (U16)DeviceReadPort(DM9_EPLOW);	highbyte = (U16)DeviceReadPort(DM9_EPHIGH);		return ((highbyte<<8) | lowbyte);}U16	C_DM9000::DeviceWriteEeprom(	U32		uWordAddress,	U16		uValue){	// assign the register offset	DeviceWritePort(DM9_EPADDR,uWordAddress);	// put data	DeviceWritePort(DM9_EPLOW, LOW_BYTE(uValue));	DeviceWritePort(DM9_EPHIGH,HIGH_BYTE(uValue));			// issue EEPROM write enable<4> and write command<1>	DeviceWritePort(DM9_EPCNTL,MAKE_MASK2(4,1));		// wait until status bit<0> cleared	DevicePolling(DM9_EPCNTL,MAKE_MASK(0),0x00);		// stop command	DeviceWritePort(DM9_EPCNTL,0);	// extra delay	NdisStallExecution(1000);		return uValue;}U16	C_DM9000::DeviceReadPhy(	U32		uRegister,	U32		uOffset){	U16		highbyte,lowbyte;		// assign the phy register offset, internal phy(0x40) plus phy offset	DeviceWritePort(DM9_EPADDR,(0x40|(uOffset&0x3F)));		// issue PHY select<3> and PHY read command<2>	DeviceWritePort(DM9_EPCNTL,((1<<3)|(1<<2)) );		// wait until status bit<0> cleared	DevicePolling(DM9_EPCNTL,(1<<0),0x00);		// stop command	DeviceWritePort(DM9_EPCNTL,0);	// retrive data	lowbyte  = (U16)DeviceReadPort(DM9_EPLOW);	highbyte = (U16)DeviceReadPort(DM9_EPHIGH);		return ((highbyte<<8) | lowbyte);}U16	C_DM9000::DeviceWritePhy(	U32		uRegister,	U32		uOffset,	U16		uValue){	// assign the phy register offset, internal phy(0x40) plus phy offset	DeviceWritePort(DM9_EPADDR,(0x40|(uOffset&0x3F)));	// put data	DeviceWritePort(DM9_EPLOW, LOW_BYTE(uValue));	DeviceWritePort(DM9_EPHIGH,HIGH_BYTE(uValue));	// issue PHY select<3> and write command<1>			DeviceWritePort(DM9_EPCNTL,((1<<3)|(1<<1)) );		// wait until status bit<0> cleared	DevicePolling(DM9_EPCNTL,(1<<0),0x00);		// stop command	DeviceWritePort(DM9_EPCNTL,0);	return uValue;}	U32		C_DM9000::DeviceReadData(void){	U32		value;	return	*(PU32)DeviceReadString((PU8)&value,sizeof(value));}	U32		C_DM9000::DeviceReadDataWithoutIncrement(void){	U32		value,tmp;	ENTER_CRITICAL_SECTION	VALIDATE_ADDR_PORT(DM9_MRCMDX);	switch (m_nIoMode)	{		case BYTE_MODE:			NdisRawReadPortUchar(				m_szCurrentSettings[SID_PORT_BASE_ADDRESS] 				+ DM9000_DATA_OFFSET, (PU8)&tmp);			NdisRawReadPortUchar(				m_szCurrentSettings[SID_PORT_BASE_ADDRESS] 				+ DM9000_DATA_OFFSET, (PU8)&value);			value = (value&0x000000FF);			break;		case WORD_MODE:			NdisRawReadPortUshort(				m_szCurrentSettings[SID_PORT_BASE_ADDRESS] 				+ DM9000_DATA_OFFSET, (PU16)&tmp);			NdisRawReadPortUshort(				m_szCurrentSettings[SID_PORT_BASE_ADDRESS] 				+ DM9000_DATA_OFFSET, (PU16)&value);			value = (value&0x0000FFFF);			break;						case DWORD_MODE:			NdisRawReadPortUlong(				m_szCurrentSettings[SID_PORT_BASE_ADDRESS] 				+ DM9000_DATA_OFFSET, (PU32)&tmp);			NdisRawReadPortUlong(				m_szCurrentSettings[SID_PORT_BASE_ADDRESS] 				+ DM9000_DATA_OFFSET, (PU32)&value);			break;						default:			break;	} // of switch	LEAVE_CRITICAL_SECTION		return value;}PU8		C_DM9000::DeviceReadString(	PU8		ptrBuffer,	int		nLength){	int		count;		count = (nLength + m_nIoMaxPad) / m_nIoMode;	// select port to be read from	ENTER_CRITICAL_SECTION	VALIDATE_ADDR_PORT(DM9_MRCMD);	switch (m_nIoMode)	{		case BYTE_MODE:			NdisRawReadPortBufferUchar(				m_szCurrentSettings[SID_PORT_BASE_ADDRESS] + DM9000_DATA_OFFSET, 				ptrBuffer,count);			break;					case WORD_MODE:			NdisRawReadPortBufferUshort(				m_szCurrentSettings[SID_PORT_BASE_ADDRESS] + DM9000_DATA_OFFSET, 				(PU16)ptrBuffer,count);			break;		case DWORD_MODE:			NdisRawReadPortBufferUlong(				m_szCurrentSettings[SID_PORT_BASE_ADDRESS] + DM9000_DATA_OFFSET, 				(PU32)ptrBuffer,count);			break;				default:			break;	} // of switch	LEAVE_CRITICAL_SECTION		return ptrBuffer;}PU8		C_DM9000::DeviceWriteString(	PU8		ptrBuffer,	int		nLength){	int		count;		count = (nLength + m_nIoMaxPad) / m_nIoMode;#if defined(PREEMPTIVE_TX_WRITE) 	switch (m_nIoMode)	{		case BYTE_MODE:		{			PU8	pcurr=(PU8)ptrBuffer;			for(;count--;pcurr++)			{				ENTER_CRITICAL_SECTION				VALIDATE_ADDR_PORT(DM9_MWCMD);				NdisRawWritePortUchar(					m_szCurrentSettings[SID_PORT_BASE_ADDRESS] 					+ DM9000_DATA_OFFSET, *pcurr);								LEAVE_CRITICAL_SECTION			}		}			break;					case WORD_MODE:		{			PU16	pcurr=(PU16)ptrBuffer;						for(;count--;pcurr++)			{				ENTER_CRITICAL_SECTION				VALIDATE_ADDR_PORT(DM9_MWCMD);				NdisRawWritePortUshort(					m_szCurrentSettings[SID_PORT_BASE_ADDRESS] 					+ DM9000_DATA_OFFSET, *pcurr);				LEAVE_CRITICAL_SECTION			}		}			break;		case DWORD_MODE:		{			PU32	pcurr=(PU32)ptrBuffer;			for(;count--;pcurr++)			{				ENTER_CRITICAL_SECTION				VALIDATE_ADDR_PORT(DM9_MWCMD);				NdisRawWritePortUlong(					m_szCurrentSettings[SID_PORT_BASE_ADDRESS] 					+ DM9000_DATA_OFFSET, *pcurr);								LEAVE_CRITICAL_SECTION			}		}			break;				default:			break;	} // of switch	#else // !PREEMPTIVE_TX_WRITE	// select port to be read from	ENTER_CRITICAL_SECTION	VALIDATE_ADDR_PORT(DM9_MWCMD);	switch (m_nIoMode)	{		case BYTE_MODE:			NdisRawWritePortBufferUchar(				m_szCurrentSettings[SID_PORT_BASE_ADDRESS] + DM9000_DATA_OFFSET, 				ptrBuffer,count);			break;					case WORD_MODE:			NdisRawWritePortBufferUshort(				m_szCurrentSettings[SID_PORT_BASE_ADDRESS] + DM9000_DATA_OFFSET, 				(PU16)ptrBuffer,count);			break;		case DWORD_MODE:			NdisRawWritePortBufferUlong(				m_szCurrentSettings[SID_PORT_BASE_ADDRESS] + DM9000_DATA_OFFSET, 				(PU32)ptrBuffer,count);			break;				default:			break;	} // of switch		LEAVE_CRITICAL_SECTION#endif	return ptrBuffer;}/******************************************************************************** * * Devcie control routines * ********************************************************************************/void	C_DM9000::DeviceEnableInterrupt(void){	// bits to turn on interrupt latch	// <7> buffer chain enable	// <3> rx overflow count overflow	// <2> rx overflow	// <1> tx completed indication	// <0> rx completed indication	DeviceWritePort(DM9_IMR,((1<<7)|(1<<3)|(1<<2)|(1<<1)|(1<<0)));}void	C_DM9000::DeviceDisableInterrupt(void){	// <7> buffer chain enable	DeviceWritePort(DM9_IMR,(1<<7));}void 	C_DM9000::DeviceEnableReceive(void){	// RX enable RXCR<0>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -