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

📄 func03.cpp

📁 DM9000芯片所有的资料,包括如何与S3C2440连接的原理图,PCB,还有最新驱动,怎样在驱动里修改参数的PDF文档
💻 CPP
字号:
// DM9013.cpp: implementation of the DM9013 class.
//
// Copyright (c) 2000-2007 Davicom Inc.  All rights reserved.
// 
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "FUNC03.h"
#include "FUNC13.h"
#include "ver.h" //[chip]

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

DM9003::DM9003(NIC_DRIVER_OBJECT *pUpper,PVOID pVoid) : DM9000(pUpper,pVoid)
{

}

DM9003::~DM9003()
{

}

DWORD DM9003::GetDriverChipID()
{
	return DM9003_CHIP_ID; 
}

LPCTSTR	DM9003::GetDriverVersion(void)
{
	return DM9003_DRIVER_VERSION;
}


void DM9003::InitialHardware(int nResetCounts)
{
	U32		val;
	
	// reset member varialbes
	m_uLastAddressPort = (U32)-1;
	
	// software reset the device
	DeviceWritePort(DM9_NCR, 0x01);
	NdisStallExecution(20); // 20 us

	// 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;
	}
// v3.2.9
	//m_nMaxTxPending = (DeviceReadPort(DM9_CHIPREV) >= 0x10)?2:1;
	m_nMaxTxPending = 2;
	m_nTxPendings = 0;
	
	// set the clearing method of TX packet complete status
	DeviceWritePort(DM9_NSR, 0x0C); // (1<<5) For DM9013 only
									//   0x00 For DM9003
									//   0x0C For DM9003 (JJ)

	// enable flow control [Extra for DM9003/DM9013]
	// Extra=
	DeviceWritePort(DM9_FCR, 0x20);
	DeviceWritePhy(0,4,(DeviceReadPhy(0,4)|(1<<10)));
	DeviceWritePhy(1,4,(DeviceReadPhy(1,4)|(1<<10)));
	
	// Enable memory chain
	DeviceWritePort(DM9_IMR, (1<<7));
	
	// Switch config
	SwitchConfig();
	
#ifdef	IMPL_STORE_AND_INDICATION

//	..m . ,df; ,. ,. b,. fg,b,.fr n,. n ...

	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("DM9013::InitialHardware - Insufficient memory\r\n")));

	for(;m--;uaddr+=sizeof(DATA_BLOCK))
		m_RQueue.Enqueue((PCQUEUE_GEN_HEADER)uaddr);

	/* set indication timer */
	DeviceInitializeTimer();
#endif

	WNextLine();
	m_CHIPMsgCtrl= FALSE; // TO BE FALSE
	WPrintf(_T("[#03]\r\n"));
	WPrintf(_T("[#03]\r\n"));
	WPrintf(_T("[#03]\r\n"));
	WPrintf(_T("[#03]\r\n"));
	WPrintf(_T("[#03]\r\n"));
	WNextLine();

//////////////
// Per-PHY
//////////////
#if 0
	// REG MIIADDR_SCFG.4= 20.4
	m_auto_mdix_flgb= !(DeviceReadPhy(0, MIIADDR_SCFG)&MAKE_MASK1(4)); // MAKE_MASK1(4)==0x0010
	//...
	
	// REG MIIADDR_SCFG.4= 20.4
	m_auto_mdix_flgb= !(DeviceReadPhy(1, MIIADDR_SCFG)&MAKE_MASK1(4)); // MAKE_MASK1(4)==0x0010
	//...
#endif
#if 1
	#if 0
	//PHY-0
	/* MYLinkProcess= */
	ISA_LinkUp();
	//PHY-1
	/* MYLinkProcess |= */
	ISA_LinkUp();
	#endif
	
	#if 1
		m_n4HangCounts= 3;  // Trick! Especial for DM9003 that not succeed here, but 4Hang DIRECT succesed!
	#else
		/* MYLinkProcess= */
		if (MYLinkProcess)		// Trick!
			m_n4HangCounts= 1;  // to show -> OP_ShowLinkMode() in check 4 hang!
	#endif
#endif

	WNextLine();
	WNextLine();

	//(+)2008-01-10 Joseph Chang
	int j;
	//PHY-0
	for(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(WSTR("PHY0: Link rapid (for 30ms): %d.%d mSec \r\n"), (j*300)/1000, (((j*300)+50)/100)%10);
	//PHY-1
	for(j=0; j<100; j++) { //[_Joseph: If still not link, This is to wait max 30ms until link OK!]	
		if ( DeviceReadPhy(1, 0x1)&0x0004 ) //wLinkState =
			break;
		NdisMSleep(uSec300);
	}
	WPrintf(WSTR("PHY1: Link rapid (for 30ms): %d.%d mSec \r\n"), (j*300)/1000, (((j*300)+50)/100)%10);
	WNextLine();
	WNextLine();
	//(-)2008-01-10 Joseph Chang

	//(+)2008-04-22 Joseph Chang
#if 0
	// Ray+
	DeviceWritePort(DM9_PIndex, 0); //P0
	DeviceWritePort(DM9_VLAN_TAGL, 2); // -----> see VLAN Mapping Table 0xb2

	DeviceWritePort(DM9_PIndex, 1); //P1
	DeviceWritePort(DM9_VLAN_TAGL, 2); // -----> see VLAN Mapping Table 0xb2, too

	DeviceWritePort(DM9_PIndex, 3); //Processor
	DeviceWritePort(DM9_VLAN_TAGL, 1); // -------> see VLAN Mapping Table 0xb1
	
	DeviceWritePort(0xb1, 0x03); // Mapping to port 1 & port 0 (i.e. Mapping Table 0xb1)
	DeviceWritePort(0xb2, 0x08); // Mapping to processor (i.e. Mapping Table 0xb2)

	WPrintf(WSTR("[TEST].[TEST].[TEST] DM9003: Test VLAN! \r\n"));
#endif
	//(-)2008-04-22 Joseph Chang

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

void DM9003::SwitchConfig()
{
	/* switch control */
#if 0
	SwitchVlanSetup(1); /* 0:port-base, 1:Tag-base */
#endif
#if 0
	SwitchQosSetup(0); /* 0:port, 1:Tag, 2:TOS */
#endif
#if 0
	/* Bandwidth control 
	 Device_BW_control(db,port_no, bw_type, bit7-4, bit3-0) 
	 bw_type(reg61H.[3]): 0:control with Ingress and Egress separately
		              1:control with Ingress or Egress
	 bit7-4 and bit 3-0:refer to reg66H and reg67H
	 If bw_type=1, bit7-4 must be "0".
	*/
	SwitchBandwidthControl(1,0,0,2); 
	SwitchBandwidthControl(0,0,2,0); 
#endif
}

WORD DM9003::DeviceReadPhy(DWORD dwRegister, DWORD dwOffset)
{
	WORD wHighbyte,wLowbyte;
	
	// assign the phy register offset, internal phy(0x40) plus phy offset
	//---DM9000---
	//DeviceWritePort(DM9_EPADDR,(0x40|(dwOffset&0x3F)));
	//---DM9013 ---
	DeviceWritePort(DM9_EPADDR,((dwRegister<<6)|(dwOffset&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
	wLowbyte  = (WORD)DeviceReadPort(DM9_EPLOW);
	wHighbyte = (WORD)DeviceReadPort(DM9_EPHIGH);
	
	return ((wHighbyte<<8) | wLowbyte);
}

WORD DM9003::DeviceWritePhy(DWORD dwRegister, DWORD dwOffset, WORD wValue)
{
	// assign the phy register offset, internal phy(0x40) plus phy offset
	//---DM9000---
	//DeviceWritePort(DM9_EPADDR,(0x40|(dwOffset&0x3F)));
	//---DM9013---
	DeviceWritePort(DM9_EPADDR,((dwRegister<<6)|(dwOffset&0x3F)));

	// put data
	DeviceWritePort(DM9_EPLOW, LOW_BYTE(wValue));
	DeviceWritePort(DM9_EPHIGH,HIGH_BYTE(wValue));

	// 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 wValue;
}


/*******************************************************************
 *
 * dm9003/dm9013 over-write function (new)
 *
 *******************************************************************/
WORD DM9003::DeviceCheckLink(void)
{
	WORD wLinkState=0;
	//#ifdef TARGET_DM9013
	WORD /*wPHY0,*/ wPHY1;
	//#endif

	WPrintf(WSTR(" +"));  // dbg

	wLinkState = DeviceReadPhy(0, 0x1);
	wLinkState = DeviceReadPhy(0, 0x1);

	//#ifdef TARGET_DM9013
	wPHY1 = DeviceReadPhy(1, 0x1);
	wPHY1 = DeviceReadPhy(1, 0x1);
	wLinkState |= wPHY1;
	//#endif

	SetConnectionStatus((wLinkState&0x4)?TRUE:FALSE); //(true);
	//DEBUG_PRINTF(TEXT("[DM9ISA]Link=%d\r\n"), (wLinkState&0x4));
	return wLinkState;
}

// <== DM9013 only ? For a notice!
//void DM9013::DeviceInterruptEventHandler(U32 uValue)
//{
//  DeviceWritePort(DM9_NSR, nsr); //clear <== DM9013 add
//}

int	DM9003::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
//#endif
	U8 szbuffer[DRIVER_BUFFER_SIZE];
		
	for(pdesc=(PDM9_RX_DESCRIPTOR)&desc;;) // of forever read loop
	{
		CHECK_SHUTDOWN();

		desc= DeviceReadDataWithoutIncrement(); // probe first byte
	
		if(pdesc->bState != 0x01) break; // check if packet available, or no data

		desc = DeviceReadData(); // get the data descriptor again

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

		if ((pdesc->bStatus&0xF2)==MAKE_MASK1(6)) 
			; // multi-cast(bit[6]).. && no bit[7],bit[5],bit[4], & "bit[1] CE"
		else // ~bit[6] || ( bit[7] | bit[5] | bit[4] | bit[1] CE)
			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
//#endif
		DeviceReadData((PBYTE)&szbuffer,pdesc->nLength);
		
		// check status, as specified in DM9_RXSR,
		// the following bits are error
		// bit[1] CE
		// Not Error: {bit[3:2] from which port (00: P0, 01: P1, 10: P2, 11: na), bit[0] reserved}
		if(pdesc->bStatus & MAKE_MASK2(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
//#endif
		DeviceReceiveIndication(0, (PVOID)&szbuffer, pdesc->nLength);
	} 

	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;
}

⌨️ 快捷键说明

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