📄 driver.cpp
字号:
// driver.cpp: implementation of the NIC_DRIVER_OBJECT class.//// Copyright (c) 2000-2007 Davicom Inc. All rights reserved.// //////////////////////////////////////////////////////////////////////#include "stdAfx.h"#include "exception.h"#include "mutex.h"#include "queue.h"#include "driver.h"#include "device.h"#include "ver.h" // [package]/**************************************************************************************** * * Driver-wide global data declaration * ****************************************************************************************/NDIS_OID gszNICSupportedOid[] = { OID_GEN_SUPPORTED_LIST, OID_GEN_HARDWARE_STATUS, OID_GEN_MEDIA_SUPPORTED, OID_GEN_MEDIA_IN_USE, OID_GEN_MEDIA_CONNECT_STATUS, OID_GEN_MAXIMUM_SEND_PACKETS, OID_GEN_VENDOR_DRIVER_VERSION, OID_GEN_MAXIMUM_LOOKAHEAD, OID_GEN_MAXIMUM_FRAME_SIZE, OID_GEN_MAXIMUM_TOTAL_SIZE, OID_GEN_MAC_OPTIONS, OID_GEN_PROTOCOL_OPTIONS, OID_GEN_LINK_SPEED, OID_GEN_TRANSMIT_BUFFER_SPACE, OID_GEN_RECEIVE_BUFFER_SPACE, OID_GEN_TRANSMIT_BLOCK_SIZE, OID_GEN_RECEIVE_BLOCK_SIZE, OID_GEN_VENDOR_ID, OID_GEN_VENDOR_DESCRIPTION, OID_GEN_CURRENT_PACKET_FILTER, OID_GEN_CURRENT_LOOKAHEAD, OID_GEN_DRIVER_VERSION, OID_GEN_XMIT_OK, OID_GEN_RCV_OK, OID_GEN_XMIT_ERROR, OID_GEN_RCV_ERROR, OID_GEN_RCV_NO_BUFFER, OID_GEN_RCV_CRC_ERROR, OID_802_3_PERMANENT_ADDRESS, OID_802_3_CURRENT_ADDRESS, OID_802_3_MULTICAST_LIST, OID_802_3_MAXIMUM_LIST_SIZE, OID_802_3_RCV_ERROR_ALIGNMENT, OID_802_3_XMIT_ONE_COLLISION, OID_802_3_XMIT_MORE_COLLISIONS, OID_802_3_XMIT_DEFERRED, OID_802_3_XMIT_MAX_COLLISIONS, OID_802_3_XMIT_UNDERRUN, OID_802_3_XMIT_HEARTBEAT_FAILURE, OID_802_3_XMIT_TIMES_CRS_LOST, OID_802_3_XMIT_LATE_COLLISIONS, };/******************************************************************************************** * * NIC_DRIVER_OBJECT Implementation * ********************************************************************************************/NIC_DRIVER_OBJECT::NIC_DRIVER_OBJECT( NDIS_HANDLE hMiniportAdapter, NDIS_HANDLE hWrapperConfigurationContext){ m_hMiniportAdapter = hMiniportAdapter; m_hWrapperConfiguration = hWrapperConfigurationContext; m_fSystemHang = FALSE; m_fOutOfResources = FALSE; m_pLower = NULL;}NIC_DRIVER_OBJECT::~NIC_DRIVER_OBJECT(){}NDIS_HANDLE NIC_DRIVER_OBJECT::GetNdisMiniportAdapterHandle() { return m_hMiniportAdapter; }NDIS_HANDLE NIC_DRIVER_OBJECT::GetNdisWrapperConfigurationHandle() { return m_hWrapperConfiguration; }U32 NIC_DRIVER_OBJECT::GetRecentInterruptStatus() { return m_uRecentInterruptStatus; }void NIC_DRIVER_OBJECT::DriverStart(void){ m_pLower->DeviceStart();}
//;
extern void MY_DeviceRetriveConfigurations(NIC_DRIVER_OBJECT *pDv, NDIS_HANDLE hConfig);
U32 MY_InitialConfigurations(NIC_DRIVER_OBJECT *pDv, NDIS_HANDLE hWrapperConfiguration) // sub-inline
{
NDIS_STATUS status;
NDIS_HANDLE hConfig;
NdisOpenConfiguration(&status, &hConfig, hWrapperConfiguration);
if(status != NDIS_STATUS_SUCCESS) return 0;
//InitialDefaultSettings();
//InitialEepromFieldPosition();
//=
// device.m_dwEepromFiledPosition[EID_MAC_ADDRESS] = 0; // Mac address offset (BYTE)
// device.m_dwEepromFiledPosition[EID_VENDOR_ID] = 8; // Vendor ID offset (BYTE)
// device.m_dwEepromFiledPosition[EID_PRODUCT_ID] = 10; // Product ID offset (BYTE)
//DeviceRetriveConfigurations(hConfig);
//=
MY_DeviceRetriveConfigurations(pDv, hConfig);
//ValidateConfigurations();
NdisCloseConfiguration(hConfig);
return NULL; //0x90000A46; // temp
}
void MY_DeviceRetriveConfigurations(NIC_DRIVER_OBJECT *pDv, NDIS_HANDLE hConfig)
{
NDIS_STATUS status;
PCONFIG_PARAMETER pconfig;
PNDIS_CONFIGURATION_PARAMETER param;
pconfig= &g_szDm9isaConfigParams[CID_IO_BASE_ADDRESS]; //GetConfigureParameters(); =[6]
NdisReadConfiguration(
&status,
¶m,
hConfig,
&(pconfig->szName),
NdisParameterHexInteger);
if(status == NDIS_STATUS_SUCCESS)
pDv->m_Bag.m_PhysAddress= param->ParameterData.IntegerData;
else
pDv->m_Bag.m_PhysAddress= pconfig->uDefValue;
}
//;Returns the base virtual address that maps the base physical address for the range.
//;If space for mapping the range is insufficient, this function returns NULL.
U32 MY_MmMAP_Phys2Virt(U32 Phys_ADDR) // inline
{
U32 uBase; //(virtAdr;)
PHYSICAL_ADDRESS phyAddr;
phyAddr.HighPart= 0;
phyAddr.LowPart= Phys_ADDR; //_m_szConfigures[_CID_IO_BASE_ADDRESS];
WPrintf(WSTR(" Register IoSpace:: Tries to map io space with 0x%X\r\n"), phyAddr.LowPart);
uBase = (U32)MmMapIoSpace(phyAddr, 16, FALSE); // CEDDK.h
WPrintf(WSTR(" Register IoSpace:: The mapped address is 0x%X\r\n"), uBase);
return uBase;
}
DWORD MY_DeviceWritePort(NIC_DRIVER_OBJECT *pDv, DWORD dwPort, DWORD dwValue){
CSpinlock m_spinAccessToken;
m_spinAccessToken.Lock(); //ENTER_CRITICAL_SECTION
//VALIDATE_ADDR_PORT(dwPort);
//=
NdisRawWritePortUchar(pDv->m_Bag.m_PortBaseAddress+ DM9ISA_ADDR_OFFSET, (U8)dwPort);
NdisRawWritePortUchar(pDv->m_Bag.m_PortBaseAddress + DM9ISA_DATA_OFFSET, (U8)dwValue);
m_spinAccessToken.Release(); //LEAVE_CRITICAL_SECTION
return dwValue;
}
DWORD MY_ISA_DeviceReadPort(NIC_DRIVER_OBJECT *pDv, DWORD dwPort){
WORD wValue;
CSpinlock m_spinAccessToken;
m_spinAccessToken.Lock(); //ENTER_CRITICAL_SECTION
//VALIDATE_ADDR_PORT(dwPort);
//=
NdisRawWritePortUchar(
pDv->m_Bag.m_PortBaseAddress //m_szCurrentSettings[SID_PORT_BASE_ADDRESS]
+ DM9ISA_ADDR_OFFSET, (U8)dwPort);
NdisRawReadPortUchar(
pDv->m_Bag.m_PortBaseAddress //m_szCurrentSettings[SID_PORT_BASE_ADDRESS]
+ DM9ISA_DATA_OFFSET, &wValue);
m_spinAccessToken.Release(); //LEAVE_CRITICAL_SECTION
return (DWORD)wValue;
}
BOOL MY_DevicePolling(
NIC_DRIVER_OBJECT *pDv,
U32 uPort,
U32 uMask, //(1<<0)
U32 uExpected, // 0x00
U32 uInterval, // 20 /* in millisecond */
U32 uRetries) // -1
{
for(;uRetries;uRetries--)
{
if((MY_ISA_DeviceReadPort(pDv, uPort) & uMask) == uExpected) break;
NdisStallExecution(uInterval);
} // of retry loop
return (BOOL)uRetries;
}
WORD MY_DeviceReadEeprom(NIC_DRIVER_OBJECT *pDv, DWORD dwAddress)
{
WORD wHighbyte,wLowbyte;
// assign the register offset
MY_DeviceWritePort(pDv,DM9_EPADDR,dwAddress);
// issue EEPROM read command<2>
MY_DeviceWritePort(pDv,DM9_EPCNTL,(1<<2));
// wait until status bit<0> cleared
// 80 uS, 5 times
if(!MY_DevicePolling(pDv,DM9_EPCNTL,(1<<0),0x00,80,5))
return (WORD)-1;
// stop command
MY_DeviceWritePort(pDv,DM9_EPCNTL,0);
// retrive data
wLowbyte = (WORD)MY_ISA_DeviceReadPort(pDv, DM9_EPLOW);
wHighbyte = (WORD)MY_ISA_DeviceReadPort(pDv, DM9_EPHIGH);
return ((wHighbyte<<8) | wLowbyte);
}
U32 MY_GetChipID(NIC_DRIVER_OBJECT *pDv)
{
DWORD dwEEPromID;
DWORD dwChipID;
// ProductID VendorID
dwEEPromID = MY_DeviceReadEeprom(pDv,10)<<16; //GetProductID()<<16;
dwEEPromID |= MY_DeviceReadEeprom(pDv,8); //GetVendorID();
WPrintf(WSTR(" GetEEPROM:: Chip signature is %08X\r\n"), dwEEPromID);
//if (dwChipID == 0) // Read from Register
//{
dwChipID = MY_ISA_DeviceReadPort(pDv, 0x28);
dwChipID |= MY_ISA_DeviceReadPort(pDv, 0x29)<<8;
dwChipID |= MY_ISA_DeviceReadPort(pDv, 0x2a)<<16;
dwChipID |= MY_ISA_DeviceReadPort(pDv, 0x2b)<<24;
WPrintf(WSTR(" GetChipID:: Chip signature is %08X\r\n"), dwChipID);
//}
if (dwEEPromID && (dwEEPromID!=0xFFFFFFFF))
return dwEEPromID; // Chip signature
return dwChipID; // Chip signature
}
void NIC_DRIVER_OBJECT::MiniportInitialize( OUT PNDIS_STATUS OpenErrorStatus, OUT PUINT SelectedMediaIndex, IN PNDIS_MEDIUM MediaArray, IN UINT MediaArraySize){//. SETFNAME("NIC_DRIVER_OBJECT::MiniportInitialize");//. FUNCTION_ENTER_MSG();
m_uRecentInterruptStatus = 0; if(!m_pLower)
{
WNextLine();
PRINTF(_T("====================[NewOBJ]==================\r\n"));
MY_InitialConfigurations(this, m_hWrapperConfiguration); // To Get
this->m_Bag.m_PortBaseAddress= MY_MmMAP_Phys2Virt(this->m_Bag.m_PhysAddress); //PortBaseAdr<-PhysAdr
this->m_Bag.m_pLowerId= MY_GetChipID(this); // To Get
PRINTF(_T("==============================================\r\n"));
WNextLine();
#if 0
//[Test DM9000_T]
this->m_Bag.m_pLowerId= 0x90030a46;
#endif
m_pLower = DeviceEntry(this,NULL); // Return obj, depend on - 'this->m_Bag.m_pLowerId'
} if(!m_pLower) THROW((ERR_STRING("NIC_DRIVER_OBJECT::MiniportInitialize - Error in creating device\r\n"))); PRINTF(_T("====================[=Init=]==================\r\n")); PRINTF(_T("Davicom Semiconductor, Inc.\r\n"));// PRINTF(_T("Davicom Ethernet Device Driver.\r\n"));//. PRINTF(_T("----------------------------------------------\r\n")); PRINTF(_T("Package Version : %s\r\n"),DAVICOM_NIC_PACKAGE_VERSION);//. PRINTF(_T("Package Release Date : %s\r\n"),DAVICOM_NIC_PACKAGE_RELEASE); PRINTF(_T("Driver Version : %s\r\n"),m_pLower->GetDriverVersion());//. PRINTF(_T("Release Date : %s\r\n"),m_pLower->GetReleaseDate()); PRINTF(_T("==============================================\r\n")); UINT i; // Determinate media type for(i=0; i<MediaArraySize; i++) if(MediaArray[i] == NdisMedium802_3) break; if (i == MediaArraySize) THROW((ERR_STRING("NIC_DRIVER_OBJECT::MiniportInitialize - Unsupported media\r\n"),NDIS_STATUS_UNSUPPORTED_MEDIA)); *SelectedMediaIndex = i; // Read registry configurations m_pLower->InitialConfigurations(m_hWrapperConfiguration);
m_pLower->DeviceRegisterAdapter(); //(+)add by bill, 20070-12-11 m_pLower->DeviceInitializeTimer(); //(-)add by bill, 20070-12-11 /* init tx buffers */ U32 dwNumber,dwAddr; if(!(dwAddr = (U32)malloc(sizeof(DATA_BLOCK)* (dwNumber=m_pLower->m_szConfigures[CID_TXBUFFER_NUMBER]*2)))) THROW((ERR_STRING("NIC_DRIVER_OBJECT::MiniportInitialize - Insufficient memory\r\n"))); for(;dwNumber--;dwAddr+=sizeof(DATA_BLOCK)) m_objTxQueue.Enqueue((PCQUEUE_GEN_HEADER)dwAddr); m_pLower->RegisterConfigurations(); DriverStart();//. FUNCTION_LEAVE_MSG();}PVOID NIC_DRIVER_OBJECT::DriverBindAddress( U32 uPhysicalAddress, U32 uLength){ void *pvoid; // allocate memory for the work space if(!(pvoid = VirtualAlloc( NULL, uLength, MEM_RESERVE, PAGE_NOACCESS))) return NULL; /* binding this virtual addr to physical location */ VirtualCopy( pvoid, (PVOID)uPhysicalAddress, uLength, PAGE_READWRITE | PAGE_NOCACHE); return pvoid;}void NIC_DRIVER_OBJECT::DriverIndication(U32 uIndication){ switch (uIndication) { case NIC_IND_TX_IDLE: if(m_fOutOfResources) { m_fOutOfResources = FALSE; NdisMSendResourcesAvailable(m_hMiniportAdapter); } break; case AID_ERROR: case AID_LARGE_INCOME_PACKET: m_fSystemHang = TRUE; default: break; } // of switch }void NIC_DRIVER_OBJECT::MiniportIsr( OUT PBOOLEAN InterruptRecognized, OUT PBOOLEAN QueueInterrupt) //U32 intstat; { m_pLower->DeviceDisableInterrupt(); U32 intstat= m_uRecentInterruptStatus= m_pLower->DeviceGetInterruptStatus(); /* clear it immediately */ //m_pLower->DeviceSetInterruptStatus( // m_uRecentInterruptStatus = intstat); if(intstat & MAKE_MASK4(3,2,1,0)) { if (intstat & MAKE_MASK2(3,2)) DEBUG_PRINTF(TEXT("[GIGABIT:::Int RxOvrFlw Bit3~Bit2]%02XH\r\n"),intstat); *InterruptRecognized = TRUE; *QueueInterrupt = TRUE; m_pLower->DeviceEnableInterrupt();
return; }// if (intstat & MAKE_MASK2(5,4))// { #ifdef IMPL_DEVICE_ISR //[Link-change::-->do it (==>DM9KS_LINK_INTR)] if (intstat & MAKE_MASK1(5)) { DEBUG_PRINTF(TEXT("[GIGABIT:::Int Bit5]%02XH\r\n"),m_uRecentInterruptStatus); m_pLower->DeviceIsr(intstat); *InterruptRecognized = TRUE; *QueueInterrupt = TRUE; m_pLower->DeviceEnableInterrupt(); return; } if (intstat & MAKE_MASK1(4)) { DEBUG_PRINTF(TEXT("[GIGABIT:::Int Bit4]%02XH\r\n"),m_uRecentInterruptStatus); *InterruptRecognized = TRUE; *QueueInterrupt = TRUE; m_pLower->DeviceEnableInterrupt(); return; } #endif DEBUG_PRINTF(TEXT("[GIGABIT:::Int NoBit]%02XH\r\n"),m_uRecentInterruptStatus); *InterruptRecognized = FALSE; *QueueInterrupt = FALSE; m_pLower->DeviceEnableInterrupt(); return;// }}void NIC_DRIVER_OBJECT::MiniportInterruptHandler(void){ m_pLower->DeviceInterruptEventHandler(m_uRecentInterruptStatus); m_pLower->DeviceEnableInterrupt();}#define HANDLE_QUERY(event,ptr,len) \ case event: if(InfoBufferLength < (*BytesNeeded=len)) \ { status = NDIS_STATUS_INVALID_LENGTH; break; } \ panswer = (void*)(ptr); *BytesWritten = len; break;NDIS_STATUS NIC_DRIVER_OBJECT::MiniportQueryInformation( IN NDIS_OID Oid, IN PVOID InfoBuffer, IN ULONG InfoBufferLength, OUT PULONG BytesWritten, OUT PULONG BytesNeeded){ NDIS_STATUS status = NDIS_STATUS_SUCCESS; PVOID panswer; U8 szbuffer[32]; U32 tmp32; // pass to lower object, to see if it can handle this query, // if it can, return TRUE and set status. if(m_pLower->DeviceQueryInformation( &status, Oid, InfoBuffer, InfoBufferLength, BytesWritten, BytesNeeded)) return status; switch (Oid) { HANDLE_QUERY( OID_GEN_SUPPORTED_LIST, &gszNICSupportedOid,sizeof(gszNICSupportedOid)); HANDLE_QUERY( OID_GEN_HARDWARE_STATUS, &m_pLower->m_szCurrentSettings[SID_HW_STATUS],sizeof(U32));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -