📄 driver.cpp
字号:
/********************************************************************************
*
* $Id: driver.cpp,v 1.1.1.1 2007/04/16 03:45:52 bill Exp $
*
* File: Main.cpp
*
* Copyright (c) 2000-2002 Davicom Inc. All rights reserved.
*
********************************************************************************/
#include "common.h"
#include "driver.h"
#include "device.h"
/****************************************************************************************
*
* 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
*
********************************************************************************************/
void NIC_DRIVER_OBJECT::DriverStart(void)
{
m_pLower->DeviceStart();
}
void NIC_DRIVER_OBJECT::EDriverInitialize(
OUT PNDIS_STATUS OpenErrorStatus,
OUT PUINT SelectedMediaIndex,
IN PNDIS_MEDIUM MediaArray,
IN UINT MediaArraySize)
{
m_uRecentInterruptStatus = 0;
if(!m_pLower)
m_pLower = DeviceEntry(this,NULL);
if(!m_pLower)
THROW((ERR_STRING("Error in creating device")));
UINT i;
NDIS_STATUS status;
NDIS_HANDLE hconfig;
// Determinate media type
for(i=0; i<MediaArraySize; i++)
if(MediaArray[i] == NdisMedium802_3) break;
if (i == MediaArraySize)
THROW((ERR_STRING("Unsupported media"),NDIS_STATUS_UNSUPPORTED_MEDIA));
*SelectedMediaIndex = i;
// Read registry configurations
NdisOpenConfiguration(
&status,
&hconfig,
m_NdisWrapper);
if(status != NDIS_STATUS_SUCCESS)
THROW((ERR_STRING("Error in opening configuration"),status));
C_Exception *pexp;
TRY
{
m_pLower->DeviceSetDefaultSettings();
m_pLower->DeviceSetEepromFormat();
m_pLower->DeviceRetriveConfigurations(hconfig);
m_pLower->EDeviceValidateConfigurations();
FI;
}
CATCH(pexp)
{
pexp->PrintErrorMessage();
CLEAN(pexp);
NdisCloseConfiguration(hconfig);
THROW((ERR_STRING("*** Error in retriving configurations.\n")));
}
NdisCloseConfiguration(hconfig);
m_pLower->DeviceRegisterAdapter();
/* init tx buffers */
U32 m,uaddr;
if(!(uaddr = (U32)malloc(sizeof(DATA_BLOCK)*
(m=m_pLower->m_szConfigures[CID_TXBUFFER_NUMBER]*2))))
THROW((ERR_STRING("Insufficient memory")));
for(;m--;uaddr+=sizeof(DATA_BLOCK))
m_TQueue.Enqueue((PCQUEUE_GEN_HEADER)uaddr);
TRY
{
m_pLower->EDeviceRegisterIoSpace();
m_pLower->EDeviceLoadEeprom();
m_pLower->EDeviceInitialize(m_pLower->m_nResetCounts=0);
m_pLower->EDeviceRegisterInterrupt();
FI;
}
CATCH(pexp)
{
pexp->PrintErrorMessage();
CLEAN(pexp);
THROW((ERR_STRING("Device error")));
}
m_pLower->DeviceOnSetupFilter(0);
}
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_bOutofResources)
{
m_bOutofResources = 0;
NdisMSendResourcesAvailable(m_NdisHandle);
}
break;
case AID_ERROR:
case AID_LARGE_INCOME_PACKET:
m_bSystemHang = 1;
default:
break;
} // of switch
}
void NIC_DRIVER_OBJECT::DriverIsr(
OUT PBOOLEAN InterruptRecognized,
OUT PBOOLEAN QueueInterrupt)
{
m_pLower->DeviceDisableInterrupt();
U32 intstat;
if(!(intstat = m_pLower->DeviceGetInterruptStatus()))
{
*InterruptRecognized =
*QueueInterrupt = FALSE;
m_pLower->DeviceEnableInterrupt();
return;
}
/* clear it immediately */
m_pLower->DeviceSetInterruptStatus(
m_uRecentInterruptStatus = intstat);
*InterruptRecognized = TRUE;
*QueueInterrupt = TRUE;
#ifdef IMPL_DEVICE_ISR
m_pLower->DeviceIsr(intstat);
#endif
}
void NIC_DRIVER_OBJECT::DriverInterruptHandler(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::DriverQueryInformation(
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));
HANDLE_QUERY( OID_GEN_MEDIA_IN_USE,
&m_pLower->m_szCurrentSettings[SID_MEDIA_IN_USE],sizeof(U32));
HANDLE_QUERY( OID_GEN_MEDIA_SUPPORTED,
&m_pLower->m_szCurrentSettings[SID_MEDIA_SUPPORTED],sizeof(U32));
HANDLE_QUERY( OID_GEN_MEDIA_CONNECT_STATUS,
&m_pLower->m_szCurrentSettings[SID_MEDIA_CONNECTION_STATUS],sizeof(U32));
HANDLE_QUERY( OID_GEN_MAXIMUM_LOOKAHEAD,
&m_pLower->m_szCurrentSettings[SID_MAXIMUM_LOOKAHEAD],sizeof(U32));
HANDLE_QUERY( OID_GEN_MAXIMUM_FRAME_SIZE,
&m_pLower->m_szCurrentSettings[SID_MAXIMUM_FRAME_SIZE],sizeof(U32));
HANDLE_QUERY( OID_GEN_MAXIMUM_TOTAL_SIZE,
&m_pLower->m_szCurrentSettings[SID_MAXIMUM_TOTAL_SIZE],sizeof(U32));
HANDLE_QUERY( OID_GEN_MAXIMUM_SEND_PACKETS,
&m_pLower->m_szCurrentSettings[SID_MAXIMUM_SEND_PACKETS],sizeof(U32));
HANDLE_QUERY( OID_GEN_LINK_SPEED,
&m_pLower->m_szCurrentSettings[SID_LINK_SPEED],sizeof(U32));
HANDLE_QUERY( OID_GEN_XMIT_OK,
&m_pLower->m_szStatistics[TID_GEN_XMIT_OK],sizeof(U32));
HANDLE_QUERY( OID_GEN_RCV_OK,
&m_pLower->m_szStatistics[TID_GEN_RCV_OK],sizeof(U32));
HANDLE_QUERY( OID_GEN_XMIT_ERROR,
&m_pLower->m_szStatistics[TID_GEN_XMIT_ERROR],sizeof(U32));
HANDLE_QUERY( OID_GEN_RCV_ERROR,
&m_pLower->m_szStatistics[TID_GEN_RCV_ERROR],sizeof(U32));
HANDLE_QUERY( OID_GEN_RCV_NO_BUFFER,
&m_pLower->m_szStatistics[TID_GEN_RCV_NO_BUFFER],sizeof(U32));
HANDLE_QUERY( OID_GEN_RCV_CRC_ERROR,
&m_pLower->m_szStatistics[TID_GEN_RCV_CRC_ERROR],sizeof(U32));
HANDLE_QUERY( OID_802_3_RCV_ERROR_ALIGNMENT,
&m_pLower->m_szStatistics[TID_802_3_RCV_ERROR_ALIGNMENT],sizeof(U32));
HANDLE_QUERY( OID_802_3_RCV_OVERRUN,
&m_pLower->m_szStatistics[TID_802_3_RCV_OVERRUN],sizeof(U32));
HANDLE_QUERY( OID_802_3_XMIT_ONE_COLLISION,
&m_pLower->m_szStatistics[TID_802_3_XMIT_ONE_COLLISION],sizeof(U32));
HANDLE_QUERY( OID_802_3_XMIT_MORE_COLLISIONS,
&m_pLower->m_szStatistics[TID_802_3_XMIT_MORE_COLLISIONS],sizeof(U32));
HANDLE_QUERY( OID_802_3_XMIT_DEFERRED,
&m_pLower->m_szStatistics[TID_802_3_XMIT_DEFERRED],sizeof(U32));
HANDLE_QUERY( OID_802_3_XMIT_MAX_COLLISIONS,
&m_pLower->m_szStatistics[TID_802_3_XMIT_MAX_COLLISIONS],sizeof(U32));
HANDLE_QUERY( OID_802_3_XMIT_UNDERRUN,
&m_pLower->m_szStatistics[TID_802_3_XMIT_UNDERRUN],sizeof(U32));
HANDLE_QUERY( OID_802_3_XMIT_HEARTBEAT_FAILURE,
&m_pLower->m_szStatistics[TID_802_3_XMIT_HEARTBEAT_FAILURE],sizeof(U32));
HANDLE_QUERY( OID_802_3_XMIT_TIMES_CRS_LOST,
&m_pLower->m_szStatistics[TID_802_3_XMIT_TIMES_CRS_LOST],sizeof(U32));
HANDLE_QUERY( OID_802_3_XMIT_LATE_COLLISIONS,
&m_pLower->m_szStatistics[TID_802_3_XMIT_LATE_COLLISIONS],sizeof(U32));
HANDLE_QUERY( OID_GEN_MAC_OPTIONS,
&m_pLower->m_szCurrentSettings[SID_GEN_MAC_OPTIONS],sizeof(U32));
HANDLE_QUERY( OID_802_3_PERMANENT_ADDRESS,
m_pLower->DeviceMacAddress(&szbuffer[0]),ETH_ADDRESS_LENGTH);
HANDLE_QUERY( OID_802_3_CURRENT_ADDRESS,
m_pLower->DeviceMacAddress(&szbuffer[0]),ETH_ADDRESS_LENGTH);
HANDLE_QUERY( OID_802_3_MAXIMUM_LIST_SIZE,
&m_pLower->m_szCurrentSettings[SID_802_3_MAXIMUM_LIST_SIZE],sizeof(U32));
HANDLE_QUERY( OID_802_3_MULTICAST_LIST,
&m_pLower->m_szMulticastList[0][0],
m_pLower->m_nMulticasts*ETH_ADDRESS_LENGTH);
HANDLE_QUERY( OID_GEN_CURRENT_PACKET_FILTER,
&m_pLower->m_szCurrentSettings[SID_GEN_CURRENT_PACKET_FILTER],sizeof(U32));
HANDLE_QUERY( OID_GEN_TRANSMIT_BUFFER_SPACE,
&m_pLower->m_szCurrentSettings[SID_GEN_TRANSMIT_BUFFER_SPACE],sizeof(U32));
HANDLE_QUERY( OID_GEN_RECEIVE_BUFFER_SPACE,
&m_pLower->m_szCurrentSettings[SID_GEN_RECEIVE_BUFFER_SPACE],sizeof(U32));
HANDLE_QUERY( OID_GEN_TRANSMIT_BLOCK_SIZE,
&m_pLower->m_szCurrentSettings[SID_GEN_TRANSMIT_BLOCK_SIZE],sizeof(U32));
HANDLE_QUERY( OID_GEN_RECEIVE_BLOCK_SIZE,
&m_pLower->m_szCurrentSettings[SID_GEN_RECEIVE_BLOCK_SIZE],sizeof(U32));
HANDLE_QUERY( OID_GEN_VENDOR_ID,
(tmp32=(U32)m_pLower->DeviceVendorID(),&tmp32),sizeof(U32));
HANDLE_QUERY( OID_GEN_VENDOR_DESCRIPTION,
VENDOR_DESC,strlen(VENDOR_DESC));
HANDLE_QUERY( OID_GEN_CURRENT_LOOKAHEAD,
&m_pLower->m_szCurrentSettings[SID_GEN_CURRENT_LOOKAHEAD],sizeof(U32));
HANDLE_QUERY( OID_GEN_DRIVER_VERSION,
&m_pLower->m_szCurrentSettings[SID_GEN_DRIVER_VERSION],sizeof(U32));
HANDLE_QUERY( OID_GEN_VENDOR_DRIVER_VERSION,
&m_pLower->m_szCurrentSettings[SID_GEN_VENDOR_DRIVER_VERSION],sizeof(U32));
HANDLE_QUERY( OID_GEN_PROTOCOL_OPTIONS,
&m_pLower->m_szCurrentSettings[SID_GEN_PROTOCOL_OPTIONS],sizeof(U32));
default:
status = NDIS_STATUS_INVALID_OID;
break;
} // of switch
if(status == NDIS_STATUS_SUCCESS)
{
NdisMoveMemory(InfoBuffer,panswer,*BytesWritten);
}
return status;
}
#define HANDLE_SET(event,len) \
case event: if(InfoBufferLength < (*BytesNeeded=len)) \
{ status = NDIS_STATUS_INVALID_LENGTH; break; } \
*BytesRead = len; HANDLE_SET_##event(); break;
#define HANDLE_SET_OID_GEN_CURRENT_PACKET_FILTER() \
m_pLower->DeviceOnSetupFilter(*(U32*)InfoBuffer)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -