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

📄 dm9isa.cpp

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

#include	"dm9isa.h"
#include	"dm9000.h"
#include	"FUNC03.h"
#include	"FUNC13.h"
#include	"ver.h"

TRegName_ISA REGNameTab[]={
	_T("_0x1f"),
	_T("NCR"),
	_T("GPCR"),
	_T("GPR"),
	_T("NSR"),
	_T("IMR"),
	_T("ISR"),
	_T("RXCR"), // 7.
	_T("CHIPREV"), // 8.
	_T("0x43"), // 9.
	_T("RSRV-x"), // RSRV-1.
	_T("PHYWr-sta-x"), // RSRV-2.
	_T("PHYWr-end-x"), // RSRV-3.
	_T("PHYRd-sta-x"), // RSRV-4.
	_T("PHYRd-end-x"), // RSRV-5.
};

/*******************************************************************************
 *
 * Should put @ Driver.cpp
 *
 ********************************************************************************/
CONFIG_PARAMETER	g_szDm9isaConfigParams[] =
{
	{ 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}
};

DM9ISA::DM9ISA(NIC_DRIVER_OBJECT *pUpper,PVOID pVoid) 
		: NIC_DEVICE_OBJECT(pUpper,pVoid)
{
		m_uLastAddressPort = (U32)-1;
		m_JJ_PrintMessage_control= 0;
}


/*******************************************************************************
 *
 * Device attributes and characteristics
 *
 ********************************************************************************/
PCONFIG_PARAMETER DM9ISA::GetConfigureParameters(void)
{
	return (PCONFIG_PARAMETER)&g_szDm9isaConfigParams[0];
}

void DM9ISA::InitialEepromFieldPosition(void)
{
	m_dwEepromFiledPosition[EID_MAC_ADDRESS] = 0;	// Mac address offset (BYTE)
	m_dwEepromFiledPosition[EID_VENDOR_ID] = 8;		// Vendor ID offset (BYTE)
	m_dwEepromFiledPosition[EID_PRODUCT_ID] = 10;	// Product ID offset (BYTE)
}

DWORD DM9ISA::GetChipID(void) 
{ 
	DWORD	dwChipID;
	
	// ProductID VendorID
	dwChipID = GetProductID()<<16;
	dwChipID |= GetVendorID();

	if (dwChipID == 0)	// Read from Register
	{
		dwChipID  = DeviceReadPort(0x28);
		dwChipID |= DeviceReadPort(0x29)<<8;
		dwChipID |= DeviceReadPort(0x2a)<<16;
		dwChipID |= DeviceReadPort(0x2b)<<24;
	}

	WPrintf(WSTR(" GetChipID:: Chip signature is %08X\r\n"), dwChipID);
	return dwChipID;
}

//DWORD DM9ISA::GetDriverRevision(void) 
//{ 
//	return 0;
//}

//DWORD DM9ISA::GetChipRevision(void) 
//{ 
//	return 0;
//}

void DM9ISA::RegisterIoSpace(void)
{
	if(!m_szConfigures[CID_NEED_IO_SPACE]) return;

	U32 virtAdr= MY_MmMAP_Phys2Virt( m_szConfigures[CID_IO_BASE_ADDRESS] );
	if (virtAdr)
		m_szCurrentSettings[SID_PORT_BASE_ADDRESS]= virtAdr;
	else
		THROW((ERR_STRING("DM9ISA::_RegisterIoSpace - Fails to map io space\r\n")));


	if ( GetDriverChipID() == GetChipID()) // [Eg. 0x90000A46 for 'DM9000']
	{
		WPrintf(WSTR(" Chip Exist:: ")); 
		if (m_pUpper->m_Bag.m_pLowerId==DM9003_CHIP_ID)
			WPrintf(WSTR("DM9003")); 
		else if (m_pUpper->m_Bag.m_pLowerId==DM9013_CHIP_ID)
			WPrintf(WSTR("DM9013")); 
		else
			DbgDumpChip();  
		WNextLine();
	}
	else 
	{
		WPrintf(WSTR("Davicom Detection(Io) - DM9ISA::Register IoSpace - Device mis-match!\r\n"));

		//(+)2008-04-18 Joseph CHANG, Driver Tolerableness
		#if 0
		WPrintf(WSTR("Davicom Detection(Io) - DM9ISA::_RegisterIoSpace - Unknown device.\r\n"));
		THROW((ERR_STRING("DM9ISA::_RegisterIoSpace - Unknown device.\r\n")));
		#endif
		//(-)2008-04-18 Joseph CHANG
	}

	//(+)2008-01-17 Richard Chung
#if 0
	DWORD chip= GetChipRevision();
	if ( GetDriverRevision() == chip)
		DEBUG_PRINTF(_T("'%1X'=='%1X'::Chip Exist! \r\n"), GetDriverRevision(),chip);
	else
	{
		if (GetDriverRevision() == DM9000_REV_E)
		{
			DbgDumpChip(); DEBUG_PRINTF(_T("::Chip Exist! \r\n") );
		}
		else
		{
			DEBUG_PRINTF(_T("'%1X'!='%1X'::Chip Mismatch! \r\n"), GetDriverRevision(),chip);
			THROW((ERR_STRING("DM9ISA::_RegisterIoSpace - Detect Mismatch.\r\n")));
		}
	}
#endif
	//(-)2008-01-17 Richard Chung
}


void DM9ISA::ValidateConfigurations(void)
{
#if 0
	/* not in DM9ISA */ _NDIS_HANDLE hndis = m_pUpper->GetNdisMiniportAdapterHandle();
#endif

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

	// setting for DM9000 series
	// 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] + DM9ISA_ADDR_OFFSET,  \
		(U8) (m_uLastAddressPort=(U32(p))) )


DWORD DM9ISA::DeviceWritePort(DWORD dwPort, DWORD dwValue)
{
	ENTER_CRITICAL_SECTION

#if	1

	VALIDATE_ADDR_PORT(dwPort);
	NdisRawWritePortUchar(m_szCurrentSettings[SID_PORT_BASE_ADDRESS] + DM9ISA_DATA_OFFSET, (U8)dwValue);

#else
#endif

	LEAVE_CRITICAL_SECTION

#if	DAVICOM_DEBUG_MODE
//	if (m_CHIPMsgCtrl) _RPT_WREG(RN_RSV1, dwPort, dwValue);
#else
#endif
	
	return dwValue;
}


DWORD DM9ISA::DeviceReadPort(DWORD dwPort)
{
	WORD wValue;

	ENTER_CRITICAL_SECTION

	VALIDATE_ADDR_PORT(dwPort);

	NdisRawReadPortUchar(m_szCurrentSettings[SID_PORT_BASE_ADDRESS] + DM9ISA_DATA_OFFSET, &wValue);
	
	LEAVE_CRITICAL_SECTION
		
#if	DAVICOM_DEBUG_MODE
//	if (m_CHIPMsgCtrl) _RPT_RREG(RN_RSV1, dwPort, wValue);
#endif
	
	return (DWORD)wValue;
}

WORD DM9ISA::DeviceReadEeprom(DWORD dwAddress)
{
	WORD wHighbyte,wLowbyte;
	
	// assign the register offset
	DeviceWritePort(DM9_EPADDR,dwAddress);
	
	// 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 (WORD)-1;
	
	// stop command
	DeviceWritePort(DM9_EPCNTL,0);

	// retrive data
	wLowbyte  = (WORD)DeviceReadPort(DM9_EPLOW);
	wHighbyte = (WORD)DeviceReadPort(DM9_EPHIGH);
	
//
#if 0
 //(+)20080124 By Joseph
	if (dwAddress<8) // to be shorter
	 DEBUG_PRINTF(TEXT(" ReadSROM %02d: WORD: 0x%04X\r\n"), dwAddress, (wHighbyte<<8) | wLowbyte);
 //(-)20080124 By Joseph
#endif
//
	return ((wHighbyte<<8) | wLowbyte);
}

WORD DM9ISA::DeviceWriteEeprom(DWORD dwAddress, WORD wValue)
{
	// assign the register offset
	DeviceWritePort(DM9_EPADDR,dwAddress);

	// put data
	DeviceWritePort(DM9_EPLOW, LOW_BYTE(wValue));
	DeviceWritePort(DM9_EPHIGH,HIGH_BYTE(wValue));
		
	// 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); // 1 ms
	
	return wValue;
}

WORD DM9ISA::DeviceReadPhy(DWORD dwPhyRegister, DWORD dwOffset)
{
	WORD wHighbyte,wLowbyte;
//.if (m_CHIPMsgCtrl) _RPT_RREG(RN_RSV4, dwOffset, 0xffff);	

	if (m_CHIPMsgCtrl)
	{
		m_CHIPMsgCtrl= FALSE;
		// assign the phy register offset, internal phy(0x40) plus phy offset
		DeviceWritePort(DM9_EPADDR,(0x40|(dwOffset&0x3F)));	// DM9000
		//DeviceWritePort(DM9_EPADDR,((uRegister<<6)|(uOffset&0x3F)));	// DM9013
		
		// 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);

		m_CHIPMsgCtrl= TRUE;
	}
	else
	{
		// assign the phy register offset, internal phy(0x40) plus phy offset
		DeviceWritePort(DM9_EPADDR,(0x40|(dwOffset&0x3F)));	// DM9000
		//DeviceWritePort(DM9_EPADDR,((uRegister<<6)|(uOffset&0x3F)));	// DM9013
		
		// 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);
	}
//.if (m_CHIPMsgCtrl) _RPT_RREG(RN_RSV5, dwOffset, ((wHighbyte<<8) | wLowbyte));
	
	return ((wHighbyte<<8) | wLowbyte);
}

WORD DM9ISA::DeviceWritePhy(DWORD dwPhyRegister, DWORD dwOffset, WORD wValue)
{
#if	DAVICOM_DEBUG_MODE
//	if (m_CHIPMsgCtrl) _RPT_WREG(RN_RSV2, dwOffset, 0xffff);
#endif

	if (m_CHIPMsgCtrl)
	{
		m_CHIPMsgCtrl= FALSE;
		// assign the phy register offset, internal phy(0x40) plus phy offset
		DeviceWritePort(DM9_EPADDR,(0x40|(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);
		m_CHIPMsgCtrl= TRUE;
	}
	else
	{
		// assign the phy register offset, internal phy(0x40) plus phy offset
		DeviceWritePort(DM9_EPADDR,(0x40|(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);
	}

#if	DAVICOM_DEBUG_MODE
//if (m_CHIPMsgCtrl) _RPT_WREG(RN_RSV3, dwOffset, wValue);
#endif
	return wValue;
}

	
DWORD DM9ISA::DeviceReadData(void)
{
	DWORD value;

	return	*(PDWORD)DeviceReadData((PBYTE)&value,sizeof(value));
}
	
DWORD DM9ISA::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] 
				+ DM9ISA_DATA_OFFSET, (PU8)&tmp);
			NdisRawReadPortUchar(
				m_szCurrentSettings[SID_PORT_BASE_ADDRESS] 
				+ DM9ISA_DATA_OFFSET, (PU8)&value);
			value = (value&0x000000FF);
			break;

		case WORD_MODE:
			NdisRawReadPortUshort(
				m_szCurrentSettings[SID_PORT_BASE_ADDRESS] 
				+ DM9ISA_DATA_OFFSET, (PU16)&tmp);
			NdisRawReadPortUshort(
				m_szCurrentSettings[SID_PORT_BASE_ADDRESS] 
				+ DM9ISA_DATA_OFFSET, (PU16)&value);
			value = (value&0x0000FFFF);
			break;
				
		case DWORD_MODE:
			NdisRawReadPortUlong(
				m_szCurrentSettings[SID_PORT_BASE_ADDRESS] 
				+ DM9ISA_DATA_OFFSET, (PU32)&tmp);
			NdisRawReadPortUlong(
				m_szCurrentSettings[SID_PORT_BASE_ADDRESS] 
				+ DM9ISA_DATA_OFFSET, (PU32)&value);
			break;
				
		default:
			break;
	} // of switch

	LEAVE_CRITICAL_SECTION
	
	return value;
}


PBYTE DM9ISA::DeviceReadData(PBYTE pbtBuffer, 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] + DM9ISA_DATA_OFFSET, 
				pbtBuffer,count);
			break;
			
		case WORD_MODE:
			NdisRawReadPortBufferUshort(
				m_szCurrentSettings[SID_PORT_BASE_ADDRESS] + DM9ISA_DATA_OFFSET, 
				(PWORD)pbtBuffer,count);
			break;

		case DWORD_MODE:
			NdisRawReadPortBufferUlong(
				m_szCurrentSettings[SID_PORT_BASE_ADDRESS] + DM9ISA_DATA_OFFSET, 
				(PDWORD)pbtBuffer,count);
			break;
		
		default:
			break;
	} // of switch

	LEAVE_CRITICAL_SECTION
	
	return pbtBuffer;
}


PBYTE DM9ISA::DeviceWriteData(PBYTE pbtBuffer, int nLength)
{
	int		count;
	
	count= (nLength + m_nIoMaxPad) / m_nIoMode;

	ENTER_CRITICAL_SECTION

#if 0
	if (OP_GetMaxTxPending()==1){
		if (nTxMemoryWrAddr != nTxSramReadPoint){
			nTxMemoryWrAddr= nTxSramReadPoint;
			//
			//; Not really require!
			WPrintf(TEXT("[--R%d,%d--]\r\n"), nTxMemoryWrAddr%100, nTxSramReadPoint%100);
			DeviceWritePort(DM9_MDWAH, nTxMemoryWrAddr >> 8);
			DeviceWritePort(DM9_MDWAL, nTxMemoryWrAddr & 0xFF);
		}
	}
#endif

	switch (m_nIoMode){
		case BYTE_MODE:
			nToWrAddr= nTxMemoryWrAddr + count;
			break;
		case WORD_MODE:
			nToWrAddr= nTxMemoryWrAddr + count*2;
			break;
		case DWORD_MODE:
			nToWrAddr= nTxMemoryWrAddr + count*4;
			break;
	}

#if defined(PREEMPTIVE_TX_WRITE) 

	switch (m_nIoMode)
	{
		case BYTE_MODE:
		{

⌨️ 快捷键说明

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