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

📄 dm9isa.cpp

📁 DM9000芯片所有的资料,包括如何与S3C2440连接的原理图,PCB,还有最新驱动,怎样在驱动里修改参数的PDF文档
💻 CPP
📖 第 1 页 / 共 4 页
字号:
	//[#endif]
#endif

		WNextLine();
		WNextLine();
		
	//[(Since "nResetCounts==0")]-(AS dmfe_open)
	//(+)2008-01-10 Joseph Chang
#if 1
		//#ifdef IMPL_GIGABIT_ETHERNET
		//#endif
		for(int j=0; j<100; j++) //[_Joseph: If still not link, This is to wait max 30ms until link OK!]
		{	
			if ( DeviceReadPhy(0, 0x1)&0x0004 ) //wLinkState =
				break;
			NdisMSleep(uSec300);
		}
		WPrintf(TEXT("Chk_InitialHardware: Link rapid (for 30ms): %d.%d mSec"), (j*300)/1000, (((j*300)+50)/100)%10);
		WNextLine();
		WNextLine();
#endif
	//(-)2008-01-10 Joseph Chang

	if (nResetCounts==0) nTxCnt= nRxCnt= 0;  // Counter

	FUNCTION_LEAVE_MSG();
}

#define ATO_COUNT	1
#define TTL_COUNT	1
/*
void DM9ISA::InitialLinkProg(int n){}
*/

void	DM9ISA::DeviceResetPHYceiver(void)
{
	return;
}

/********************************************************************************
 *
 * Devcie handler routines
 *
 ********************************************************************************/
#ifdef	IMPL_DEVICE_ISR
void	DM9ISA::DeviceIsr(
	U32		uState)
{
	//(+)2008-01-10 Joseph Chang
//#ifdef IMPL_GIGABIT_ETHERNET
//#endif
#if 0
	 if ( uState & MAKE_MASK1(5) ) // MAKE_MASK1(5)=DM9KS_LINK_INTR=0x20
	 {
		for(int i=0; i<500; i++) /*wait link OK, waiting time =0.5s */
		{
			DeviceReadPhy(0, 0x1);
			if ( DeviceReadPhy(0, 0x1)&0x0004 ) //wLinkState =
				break;
			else
			  //for GIGA-RICHARD, WIST-JUDES-RON
				_DeviceWritePhy(0, MIIADDR_SCFG, 0x0);   /* 20.4=0 Auto-MDIX mode */ 
			NdisMSleep(mSec1);
		}
		
		DEBUG_PRINTF(TEXT("JJ_GIGABIT_LINK_CHANGE: Re-Link rapid: %d usec \r\n"), (i*1000));
	 }
#endif
	//(-)2008-01-10 Joseph Chang
}
#endif

#ifdef	IMPL_STORE_AND_INDICATION
void	DM9ISA::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
	
}
#endif

int	DM9ISA::DeviceOnSetupFilter(
	U32		uFilter)
{
	int		n;
	U8		sz[8];
	U32		hashval;
	U32		newmode;

	_PSTR(_T("DeviceOnSetupFilter: DeviceOnSetupFilter(0x%08X)-Sta \r\n"), uFilter);

/*
//
// Ndis Packet Filter Bits (OID_GEN_CURRENT_PACKET_FILTER).
//
#define NDIS_PACKET_TYPE_DIRECTED               0x00000001
#define NDIS_PACKET_TYPE_MULTICAST              0x00000002
#define NDIS_PACKET_TYPE_ALL_MULTICAST          0x00000004
#define NDIS_PACKET_TYPE_BROADCAST              0x00000008
#define NDIS_PACKET_TYPE_SOURCE_ROUTING         0x00000010
#define NDIS_PACKET_TYPE_PROMISCUOUS            0x00000020
#define NDIS_PACKET_TYPE_SMT                    0x00000040
#define NDIS_PACKET_TYPE_ALL_LOCAL              0x00000080
#define NDIS_PACKET_TYPE_GROUP                  0x00001000
#define NDIS_PACKET_TYPE_ALL_FUNCTIONAL         0x00002000
#define NDIS_PACKET_TYPE_FUNCTIONAL             0x00004000
#define NDIS_PACKET_TYPE_MAC_FRAME              0x00008000
*/
	
	// 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)) 
	{
// not-occur-until		
		/* 1. set unicast */
		// retrive node address
		GetMacAddress(&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) )
	{
// not-occur-until		
		// add promiscuous<1>
		newmode |= MAKE_MASK(1);
		DeviceWritePort(DM9_RXCR,		m_szCurrentSettings[SID_OP_MODE]=newmode);
		_PSTR(_T("--------------------------------------\r\n"));
		_PSTR(_T("Func=DM9ISA::DeviceOnSetupFilter('NDIS_PACKET_TYPE_PROMISCUOUS')\r\n"));
		_RPT_WREG(RN_RXCR, DM9_RXCR,	m_szCurrentSettings[SID_OP_MODE]);
		_PSTR(_T("--------------------------------------\r\n"));
		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);
	_PSTR(_T("--------------------------------------\r\n"));
//.	_RPT_STR(_T("Func=DM9ISA::DeviceOnSetupFilter('~NDIS_PACKET_TYPE_PROMISCUOUS')\r\n"));
	_RPT_WREG(RN_RXCR, DM9_RXCR,	m_szCurrentSettings[SID_OP_MODE]);
//Ke.	DeviceCheckLink();
	_PSTR(_T("--------------------------------------\r\n"));

	return uFilter;
}


void DM9ISA::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);
	
//JJ-DBG.CPP (migrated to _DeviceSend(-) to test!)
	if (nsr & 0x0c)
	{
	#if 0
		nTxSramReadPoint= (((U16)DeviceReadPort(DM9_TRAH) << 8 ) | (U16)DeviceReadPort(DM9_TRAL));
		
		if (nTxSramReadPoint != nTxMemoryWrAddr) //ERROR;
			NKDbgPrintfW(TEXT("[TxSramReadPoint Err]= ChipWrAdr %d, SramReadPt %d \r\n"), 
				nTxMemoryWrAddr, nTxSramReadPoint);
		else
			WPrintf(TEXT("[TxRamRPoint OK]= ChipWrAdr %d, SramReadPt %d \r\n"), 
				nTxMemoryWrAddr, nTxSramReadPoint);
	#endif
		
		// check TX-END2
		if(nsr & 0x08)
		{
	//JJ-DBG.CPP
			WPutChar('x'); // Interrupt -TX Packet2 Complete
			WPutChar(0x30+m_nTxPendings); 
			m_nTxPendings--;
			DeviceSendCompleted(m_TQWaiting.Dequeue());
		}

		// check TX-END1
		if(nsr & 0x04)
		{
	//JJ-DBG.CPP
			WPutChar('+'); // Interrupt -TX Packet1 Complete
			WPutChar(0x30+m_nTxPendings); 
			m_nTxPendings--;
			DeviceSendCompleted(m_TQWaiting.Dequeue());
		}

	// report tx available now
		NdisMSendResourcesAvailable(m_pUpper->GetNdisMiniportAdapterHandle()); //when if( nsr & 0x0C )
	}
	

}

U32	DM9ISA::DeviceHardwareStatus(void)
{
	return m_nTxPendings?0:NIC_HW_TX_IDLE;
}

				
int	DM9ISA::DeviceSend(
	PCQUEUE_GEN_HEADER	pObject)
{
	PCQUEUE_GEN_HEADER pcurr;

	if(pObject) m_TQStandby.Enqueue(pObject);

	/* increment counter */
//JJ-DBG.CPP (to check)
	m_nTxPendings++;
	
	/* get first pkt in queue */
	m_TQWaiting.Enqueue(pcurr= m_TQStandby.Dequeue());
	
	/* fill data */
	WPutChar('('); // Fill-Data
	WPutChar(0x30+m_nTxPendings); 

	nTxCnt++;
	ISA_TxFIFO_Begin();

	DeviceWriteData((PBYTE)CQueueGetUserPointer(pcurr), pcurr->usLength);
	
	DeviceWritePort(DM9_TXLENH, HIGH_BYTE(pcurr->usLength));
	DeviceWritePort(DM9_TXLENL, LOW_BYTE(pcurr->usLength));
		
	// TXCR<0>, issue TX request
	DeviceWritePort(DM9_TXCR, MAKE_MASK(0));

	ISA_TxFIFO_End();

//JJ-DBG.CPP
#if 1
	WPutChar(')'); // TX-complete



	while (DeviceReadPort(DM9_TXCR) & MAKE_MASK(0)) ;



		//if (nsr & 0x0c)
		//{
			nTxSramReadPoint= (((U16)DeviceReadPort(DM9_TRAH) << 8 ) | (U16)DeviceReadPort(DM9_TRAL));
			
			if (nTxSramReadPoint != nTxMemoryWrAddr) //ERROR;
				//NKDbgPrintfW(TEXT("[TxRamRPt Err]= ChipWAdr %d, RamRPt %d \r\n"), 
				//	nTxMemoryWrAddr, nTxSramReadPoint);
				WPrintf(WSTR("TC=%d %d[%d,%d]\r\n"), nTxCnt, nToWrAddr%100,
					nTxMemoryWrAddr%100, nTxSramReadPoint%100);
			else
				//WPrintf(TEXT("[OK]= ChipWAdr %d, RamRPt %d \r\n"), 
				//	nTxMemoryWrAddr, nTxSramReadPoint);
				WPrintf(WSTR("TC=%d [OK%d,%d]\r\n"), 
					nTxCnt, nTxMemoryWrAddr%100, nTxSramReadPoint%100);
		//}
#endif

	return 0;
} // pcurr


void DM9ISA::ISA_TxFIFO_Begin()
{
//JJ-DBG.CPP	
	nTxMemoryWrAddr= (((U16)DeviceReadPort(DM9_MDWAH) << 8 ) | (U16)DeviceReadPort(DM9_MDWAL));
	nTxSramReadPoint= (((U16)DeviceReadPort(DM9_TRAH) << 8 ) | (U16)DeviceReadPort(DM9_TRAL));
	
	//  [NextLine, Only for DM9003,D9013]
	if (((m_pUpper->m_Bag.m_pLowerId==DM9003_CHIP_ID)||
		(m_pUpper->m_Bag.m_pLowerId==DM9013_CHIP_ID)))
		; //WNextLine();
	else
		WPrintf(TEXT("[TC=%d S%d,%d]"), nTxCnt, nTxMemoryWrAddr%100, nTxSramReadPoint%100); // "\r\n"
}
void DM9ISA::ISA_TxFIFO_End()
{
}

int	DM9ISA::Dm9LookupRxBuffers(void)
{

	if(!m_mutexRxValidate.TryLock()) return 0;

	int		counts=0;
	int		errors=0;
	
	U32		desc;
	PDM9_RX_DESCRIPTOR	pdesc;
	U32		calcRxCnt;

#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();

	//[Extra-for check]
	//if (pdesc->bState != 0x01)
	//	; // na
	//else 
	if (pdesc->nLength > DRIVER_BUFFER_SIZE)
		calcRxCnt= 0xF9F9; // na
	else if (pdesc->bStatus & MAKE_MASK4(3,2,1,0))
		calcRxCnt= 0xF2F2; // na
	else
		calcRxCnt= nRxCnt+1;

	if ((pdesc->bStatus&0xFF)==MAKE_MASK1(6))
		;
	else
		WPrintf(WSTR("#[%02X%02X,L=%X RC=%d] \r\n"), pdesc->bStatus,pdesc->bState,pdesc->nLength,calcRxCnt);

		// 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;
		}		
		DeviceReadData((PBYTE)CQueueGetUserPointer(pcurr),pcurr->nLength=pdesc->nLength);
#else
		DeviceReadData((PBYTE)&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

		nRxCnt++;
		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;

}


BOOL DM9ISA::DeviceQueryTxResources(void)
{
#ifdef _DEBUG
	SETFNAME("DM9ISA::DeviceQueryTxResources()");
	FUNCTION_ENTER_MSG();
	if (m_nTxPendings < m_nMaxTxPending)
	{
		FUNCTION_LEAVE_MSG();
		return TRUE;
	}
	else
	{
		FUNCTION_LEAVE_MSG();
		return FALSE;
	}
#else
	return (m_nTxPendings < m_nMaxTxPending);
#endif
}

void DM9ISA::DeviceHalt(void)
{
	// nothing to do 
}

//[Sample Program:]
//#if DBG
//    NdisGetCurrentSystemTime(&TS);
//    NdisGetCurrentSystemTime(&TE);
//    TD.QuadPart = TE.QuadPart - TS.QuadPart;
//    TD.QuadPart /= 10000; DBGPRINT(MP_WARN, ("Init time = %d ms\n", TD.LowPart)); // Convert to ms 
//#endif   

int DM9ISA::LnkStat_WaitLinkUp(void)
// check if link established
{
	BOOL Result;
	LARGE_INTEGER TS, TE, TD; 
	WORD cnt= 0;
	int msResult= 0;
	TD.QuadPart= 0;
	NdisGetCurrentSystemTime(&TS); //then = GetTimes();
	while (! (Result=(DeviceReadPort(DM9_NSR) & MAKE_MASK(6))) ){
		cnt++;
		NdisMSleep(mSec1); //NdisMSleep(mSec100); [* Wait 1ms *] [* Wait 100ms *]

		NdisGetCurrentSystemTime(&TE);
		TD.QuadPart = TE.QuadPart - TS.QuadPart;
		TD.QuadPart /= 10000;   // Convert to ms
		if (TD.QuadPart>2000)	/* 2sec */
			break;
	}

	if (Result){
		msResult= (int) TD.QuadPart;

		WPrintf(_T(" [%dms].LnkUp"), TD.QuadPart);
		WNextLine();
	}
	return msResult;
}
 
int	DM9ISA::OP_GetMaxTxPending()
{
	return m_nMaxTxPending;
}

void DM9ISA::OP_SetLinkMode(int linkMode)
{
	WORD wData = 0;
	LARGE_INTEGER   TS, TE, TD;

	wData= DEV_LSMode(linkMode);

	DeviceWritePort(0x1f, 0x01); //DM9_GPR (NetWriteReg(pNic, DM9_GPR, bGEPIO0); /* Power Down PHY */)

	/* check if link terminated */
#if 1
	TD.QuadPart= 0;
	NdisGetCurrentSystemTime(&TS); //then = GetTimes();
	while (1){ 
		NdisGetCurrentSystemTime(&TE);
		TD.QuadPart = TE.QuadPart - TS.QuadPart;
		TD.QuadPart /= 10000;   
		if (TD.QuadPart>15)	/* 15ms*/
			break;
	}
#endif
//.	_PSTR(_T("[%s]----------------[%dms] \r\n"),LinkNameTbl[linkMode], TD.QuadPart);

#ifdef IMPL_TST_FORCE_100H
	DeviceWritePhy(0, 0, PARAM_100H/*PARAM_10H*/);
#else
	DeviceWritePhy(0, 0, wData); // (NetWritePHY(pNic, MIIADDR_CONTROL, wData);	/* link mode */)
#endif

	DeviceWritePort(0x1f, 0x00); //DM9_GPR (NetWriteReg(pNic, DM9_GPR, 0); /* Enable PHY */)

	NdisMSleep(mSec10); //[* 10msec *]
}

BOOL DM9ISA::OP_ShowLinkMode()
{
	WORD rData, monitor;
	LPWSTR a,b,c,d;
	//Show_A.N.
	rData= DeviceReadPhy(0, MIIADDR_SPSTAT); //* 17.[15:12]=

⌨️ 快捷键说明

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