📄 dm9isa.cpp
字号:
/******************************************************************************** * * $Id: dm9000.cpp,v 1.8 2004/12/16 06:23:12 hychu Exp $ * * Copyright (c) 2000-2005 Davicom Inc. All rights reserved. * ********************************************************************************///// WSM 2008.5.12 clean it up!#include <Ndis.h>#include "dm9isa.h"#include "common.h"/******************************************************************************* * * ********************************************************************************/ //// WSM 2008.5.13 to chang IoAddress for user/*HKEY hkeyRoot = HKEY_LOCAL_MACHINE; LPCTSTR lpSubkey = _T("Comm\\DM9CE1\\Parms");LPCTSTR lpValueName = _T("IoAddress"); DWORD IoAddressValue = 0;LONG ReadRegistryValue(HKEY hkeyRoot, LPCTSTR lpSubkey, LPCTSTR lpValueName, LPDWORD dwValue){ HKEY hkey; LONG lRet; // Open the registry lRet = RegOpenKeyEx(hkeyRoot, lpSubkey, 0, 0, &hkey); if (lRet == ERROR_SUCCESS) { // Read the value of the last change: DWORD dwData; DWORD dwBufLen = sizeof(DWORD); DWORD dwType = REG_DWORD; // Read Value in the Registry: lRet = RegQueryValueEx(hkey, lpValueName, NULL, &dwType, (LPBYTE) &dwData, &dwBufLen); *dwValue = dwData; // Close RegCloseKey(hkey); } //return lRet; return *dwValue; }//#define IoAddress ReadRegistryValue(hkeyRoot, lpSubkey, lpValueName, &IoAddressValue)const DWORD IoAddress = ReadRegistryValue(hkeyRoot, lpSubkey, lpValueName, &IoAddressValue);*/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, IoAddress, NDIS_STRING_CONST("IoAddress")}, { CID_IO_BASE_ADDRESS, 10000300, NDIS_STRING_CONST("IoAddress")}, //'10000300' no use { CID_IO_RANGE, 0x10, NDIS_STRING_CONST("IoRange")}, { CID_IRQ_NUMBER, 35, NDIS_STRING_CONST("IrqNumber")}, //'35' no use { -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(0x28); val |= DeviceReadPort(0x29)<<8; val |= DeviceReadPort(0x2a)<<16; val |= DeviceReadPort(0x2b)<<24; RETAILMSG(1, (TEXT("\r\ndm9000 init.\r\n"))); RETAILMSG(1, (TEXT("[dm9]: Chip signature is %08X\r\n"), val)); 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 * ********************************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -