📄 dm9isa.cpp
字号:
// 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 + -