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

📄 dm9isa.cpp

📁 嵌入式wince下的davicom9000a的初始化源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	if(m_szCurrentSettings[SID_OP_MODE] & MAKE_MASK(0)) return;	m_szCurrentSettings[SID_OP_MODE] |= MAKE_MASK(0);			DeviceWritePort(DM9_RXCR,m_szCurrentSettings[SID_OP_MODE]);}void 	C_DM9000::DeviceDisableReceive(void){	// RX enable RXCR<0>	if(!(m_szCurrentSettings[SID_OP_MODE] & MAKE_MASK(0))) return;			m_szCurrentSettings[SID_OP_MODE] &= ~MAKE_MASK(0);			DeviceWritePort(DM9_RXCR,m_szCurrentSettings[SID_OP_MODE]);}U32	C_DM9000::DeviceGetInterruptStatus(void){	// mask for bits	// <3> rx overflow count overflow	// <2> rx overflowf	// <1> tx completed indication	// <0> rx completed indication	return DeviceReadPort(DM9_ISR) & MAKE_MASK4(3,2,1,0);}U32	C_DM9000::DeviceSetInterruptStatus(	U32	uValue){	return DeviceWritePort(DM9_ISR,uValue);}U32	C_DM9000::DeviceGetReceiveStatus(void){	DEBUG_PRINT((		TEXT("nTxPendings=%d, %d"),			m_nTxPendings, m_pUpper->m_TQueue.Size()		));		U32	cr;	cr = DeviceReadPort(DM9_ROCR);		return ((cr>>7)&1)<<31 | (cr&0x7F);}void	C_DM9000::DeviceStart(void){#ifdef	IMPL_FLOW_CONTROL		U32		val;	// check full-duplex mode or not<3>	val = DeviceReadPort(DM9_NCR);	if( val & MAKE_MASK(3))	{		/* full duplex mode */		val = DeviceReadPort(DM9_PAUSETH);		DeviceWritePort(DM9_PAUSETH,(U8)val);				// enable flow control<0>		// enable pause packet<5>		DeviceWritePort(DM9_FLOW,MAKE_MASK2(5,0));	}	else	{		/* non full duplex mode */		val = DeviceReadPort(DM9_BACKTH);		DeviceWritePort(DM9_BACKTH,(U8)val);		// enable back pressure<half dumplex mode)<4,3>		DeviceWritePort(DM9_FLOW,MAKE_MASK2(4,3));	}#endif	// enable interrupt	DeviceEnableInterrupt();	DeviceWritePort(DM9_RXCR,m_szCurrentSettings[SID_OP_MODE]);}void	C_DM9000::DeviceReset(void){	// announce shutdown	m_bShutdown = 1;		// wait until all activities are fi.	m_mutexRxValidate.Lock();	m_mutexTxValidate.Lock();				C_Exception	*pexp;		TRY	{			EDeviceInitialize(++m_nResetCounts);			DeviceOnSetupFilter(0);				FI;	}	CATCH(pexp){		// nothing to do		CLEAN(pexp);	} // of catch	// dequeue for all objects in waiting and standby queue	PCQUEUE_GEN_HEADER	pcurr;	for(;(pcurr=m_TQWaiting.Dequeue());)		DeviceSendCompleted(pcurr);		for(;(pcurr=m_TQStandby.Dequeue());)		DeviceSendCompleted(pcurr);		m_mutexRxValidate.Release();	m_mutexTxValidate.Release();	m_bShutdown = 0;}void	C_DM9000::EDeviceInitialize(	int		nResetCounts){	U32		val;		// reset member varialbes	m_uLastAddressPort = (U32)-1;		DeviceWritePort(0x1f, 0x00);	NdisStallExecution(20);	// software reset the device	DeviceWritePort(DM9_NCR, 0x03);	NdisStallExecution(20);	DeviceWritePort(DM9_NCR, 0x03);	NdisStallExecution(20);	//DeviceWritePort(DM9_NCR, 0x00);		// read the io orgnization	// ISR<7:6> == x1, dword	// ISR<7:6> == 0x, word	// ISR<7:6> == 10, byte mode	val = DeviceReadPort(DM9_ISR);	if(val & MAKE_MASK(6))	{		m_nIoMode = DWORD_MODE;		m_nIoMaxPad = 3;	}	else if(!(val & MAKE_MASK(7)))	{		m_nIoMode = WORD_MODE;		m_nIoMaxPad = 1;	}	else	{		m_nIoMode = BYTE_MODE;		m_nIoMaxPad = 0;	}		// activate internal phy	// select GPIO 0<0>, set it to output	DeviceWritePort(DM9_GPCR, (1<<0));	// output zero to activate internal phy	DeviceWritePort(DM9_GPR,  0x00);		// clear TX status	DeviceWritePort(DM9_NSR, 0x00);			// Enable memory chain	DeviceWritePort(DM9_IMR, (1<<7));	#ifdef	IMPL_STORE_AND_INDICATION	if(nResetCounts) return;		/* init rx buffers */	U32		m,uaddr;	if(!(uaddr = (U32)malloc(sizeof(DATA_BLOCK)*		(m=m_szConfigures[CID_RXBUFFER_NUMBER]*2)))) 		THROW((ERR_STRING("Insufficient memory")));	for(;m--;uaddr+=sizeof(DATA_BLOCK))		m_RQueue.Enqueue((PCQUEUE_GEN_HEADER)uaddr);	/* set indication timer */	DeviceInitializeTimer();	#endif// v3.2.9	m_nMaxTxPending = (DeviceReadPort(DM9_CHIPREV) >= 0x10)?2:1;	m_nTxPendings = 0;}void	C_DM9000::DeviceResetPHYceiver(void){	return;}/******************************************************************************** * * Devcie handler routines * ********************************************************************************/#ifdef	IMPL_DEVICE_ISRvoid	C_DM9000::DeviceIsr(	U32		uState){}#endif#ifdef	IMPL_STORE_AND_INDICATIONvoid	C_DM9000::DeviceOnTimer(void){	int	val = m_RQStandby.Size();		PCQUEUE_GEN_HEADER	pcurr;		for(;(pcurr=m_RQStandby.Dequeue());m_RQueue.Enqueue(pcurr))	{		DeviceReceiveIndication(			0,CQueueGetUserPointer(pcurr),pcurr->nLength);	} // of for RQStandby loop	}#endifint	C_DM9000::DeviceOnSetupFilter(	U32		uFilter){	int		n;	U8		sz[8];	U32		hashval;	U32		newmode;		// save old op mode	newmode = m_szCurrentSettings[SID_OP_MODE];	// clear filter related bits,	// pass all multicast<3> and promiscuous<1>	newmode	&= ~MAKE_MASK2(3,1);	// zero input means one reset request	if(!(m_szCurrentSettings[SID_GEN_CURRENT_PACKET_FILTER]=uFilter)) 	{				/* 1. set unicast */		// retrive node address		DeviceMacAddress(&sz[0]);		// set node address		for(n=0;n<ETH_ADDRESS_LENGTH;n++)			DeviceWritePort(DM9_PAR0+n,(U32)sz[n]);					/* 2. clear multicast list and count */		m_nMulticasts = 0;		memset((void*)&m_szMulticastList,0,sizeof(m_szMulticastList));				/* 3. clear hash table */		// clear hash table		memset((void*)(&sz[0]),0,sizeof(sz));		for(n=0;n<sizeof(sz);n++)			DeviceWritePort(DM9_MAR0+n,(U32)sz[n]);		return uFilter;			}		// if promiscuous mode<1> is requested,	// just set this bit and return	if( (uFilter & NDIS_PACKET_TYPE_PROMISCUOUS) )	{		// add promiscuous<1>		newmode |= MAKE_MASK(1);		DeviceWritePort(DM9_RXCR,m_szCurrentSettings[SID_OP_MODE]=newmode);		return uFilter;	}	// if pass all multicast<3> is requested,	if(uFilter & NDIS_PACKET_TYPE_ALL_MULTICAST) newmode |= MAKE_MASK(3);	// prepare new hash table	memset((void*)(&sz[0]),0,sizeof(sz));		// if broadcast, its hash value is known as 63.	if(uFilter & NDIS_PACKET_TYPE_BROADCAST) sz[7] |= 0x80;	if(uFilter & NDIS_PACKET_TYPE_MULTICAST)		for(n=0;n<m_nMulticasts;n++)		{			hashval = DeviceCalculateCRC32(				&m_szMulticastList[n][0],ETH_ADDRESS_LENGTH,FALSE) & 0x3f;			sz[hashval/8] |= 1 << (hashval%8);		} // of calculate hash table	// submit the new hash table	for(n=0;n<sizeof(sz);n++)		DeviceWritePort(DM9_MAR0+n,(U32)sz[n]);		DeviceWritePort(DM9_RXCR,m_szCurrentSettings[SID_OP_MODE]=newmode);	return uFilter;}void C_DM9000::DeviceInterruptEventHandler(	U32	uValue){	// check RX activities 	if(uValue & 0x01) Dm9LookupRxBuffers();	// return if not TX latch	if(!(uValue & 0x02)) return;	U32	nsr;	nsr = DeviceReadPort(DM9_NSR);		// check TX-END2	if(nsr & 0x08)	{		m_nTxPendings--;		DeviceSendCompleted(m_TQWaiting.Dequeue());	}	// check TX-END1	if(nsr & 0x04)	{		m_nTxPendings--;		DeviceSendCompleted(m_TQWaiting.Dequeue());	}		// report tx available now	if( nsr & 0x0C )		NdisMSendResourcesAvailable(m_pUpper->GetNdisHandle());}U32	C_DM9000::DeviceHardwareStatus(void){	return m_nTxPendings?0:NIC_HW_TX_IDLE;}				int	C_DM9000::DeviceSend(	PCQUEUE_GEN_HEADER	pObject){	PCQUEUE_GEN_HEADER pcurr;	if(pObject) m_TQStandby.Enqueue(pObject);		/* increment counter */	m_nTxPendings++;		/* get first pkt in queue */	m_TQWaiting.Enqueue(pcurr=m_TQStandby.Dequeue());		/* fill data */	DeviceWriteString((PU8)CQueueGetUserPointer(pcurr),pcurr->nLength);		DeviceWritePort(DM9_TXLENH,HIGH_BYTE(pcurr->nLength));	DeviceWritePort(DM9_TXLENL,LOW_BYTE(pcurr->nLength));			// TXCR<0>, issue TX request	DeviceWritePort(DM9_TXCR, MAKE_MASK(0));	return 0;}int	C_DM9000::Dm9LookupRxBuffers(void){	if(!m_mutexRxValidate.TryLock()) return 0;	int		counts=0;	int		errors=0;		U32		desc;	PDM9_RX_DESCRIPTOR	pdesc;#ifdef	IMPL_STORE_AND_INDICATION	PCQUEUE_GEN_HEADER	pcurr;#else	U8		szbuffer[DRIVER_BUFFER_SIZE];#endif			for(pdesc=(PDM9_RX_DESCRIPTOR)&desc;;)	{		CHECK_SHUTDOWN();		// probe first byte		desc = DeviceReadDataWithoutIncrement();			// check if packet available, 01h means available, 00h means no data		if(pdesc->bState != 0x01) break;		// get the data descriptor again		desc = DeviceReadData();		// read out the data to buffer		// Performance issue: maybe we may discard the data		// just add the rx address.		// if the length is greater than buffer size, ...		if((pdesc->nLength > DRIVER_BUFFER_SIZE))		{			DeviceIndication(AID_LARGE_INCOME_PACKET);			break;		}#ifdef	IMPL_STORE_AND_INDICATION		if(!(pcurr=m_RQueue.Dequeue()))		{			RETAILMSG(TRUE,(TEXT("Queue overflow")));			BREAK;			// packet will lost!!			break;		}				DeviceReadString((PU8)CQueueGetUserPointer(pcurr),pcurr->nLength=pdesc->nLength);#else		DeviceReadString((PU8)&szbuffer,pdesc->nLength);#endif				// check status, as specified in DM9_RXSR,		// the following bits are error		// <3> PLE		// <2> AE		// <1> CE		// <0> FOE		if(pdesc->bStatus & MAKE_MASK4(3,2,1,0))		{			errors++;#ifdef	IMPL_STORE_AND_INDICATION			m_RQueue.Enqueue(pcurr);#endif			continue;		} // of error happens		counts++;#ifdef	IMPL_STORE_AND_INDICATION		m_RQStandby.Enqueue(pcurr);#else		DeviceReceiveIndication(			0,			(PVOID)&szbuffer,			pdesc->nLength);#endif	} // of forever read loop	REPORT(TID_GEN_RCV_OK, counts);	REPORT(TID_GEN_RCV_ERROR, errors);	m_mutexRxValidate.Release();#ifdef	IMPL_STORE_AND_INDICATION	if (!m_RQStandby.IsQueueEmpty()) DeviceSetTimer(5);#endif		return counts;}/******************************************************************* * * Hooked function * *******************************************************************//******************************************************************* * * Device Entry * *******************************************************************/extern "C" NIC_DEVICE_OBJECT	*DeviceEntry(	NIC_DRIVER_OBJECT	*pDriverObject,	PVOID				pVoid){		return new C_DM9000(pDriverObject,pVoid);}

⌨️ 快捷键说明

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