From 2cc81267e3b7e1deef0af95fd7f9857e54a73e5d Mon Sep 17 00:00:00 2001 From: Filip Navara Date: Wed, 13 Oct 2004 18:50:09 +0000 Subject: [PATCH] - Handle all required OID requests. - Fix handling of OID_GEN_MAXIMUM_FRAME_SIZE and OID_GEN_DRIVER_VERSION. - Generate error statistics. svn path=/trunk/; revision=11288 --- reactos/drivers/net/dd/pcnet/Makefile | 4 +- reactos/drivers/net/dd/pcnet/pcnet.c | 32 +++++++++-- reactos/drivers/net/dd/pcnet/pcnet.h | 33 ++++++++++++ reactos/drivers/net/dd/pcnet/requests.c | 72 +++++++++++++++++++++++-- 4 files changed, 132 insertions(+), 9 deletions(-) diff --git a/reactos/drivers/net/dd/pcnet/Makefile b/reactos/drivers/net/dd/pcnet/Makefile index 77d6a4eee27..7c50b48e389 100644 --- a/reactos/drivers/net/dd/pcnet/Makefile +++ b/reactos/drivers/net/dd/pcnet/Makefile @@ -6,7 +6,9 @@ TARGET_NAME = pcnet # - must define NDIS50 to get the right characteristics struct # - must define anonymous unions to make physical addresses work right # -TARGET_CFLAGS = -I. -DDBG=0 -Wall -Werror -DNDIS50 -DANONYMOUSUNIONS +TARGET_CFLAGS = -I. -Wall -Werror -DNDIS50 -DANONYMOUSUNIONS + +# TARGET_CFLAGS += -I$(W32API_PATH)/include/ddk -D__USE_W32API TARGET_OBJECTS = pcnet.o requests.o TARGET_DDKLIBS = ndis.a diff --git a/reactos/drivers/net/dd/pcnet/pcnet.c b/reactos/drivers/net/dd/pcnet/pcnet.c index 8a8685265e1..ff15fafdc43 100644 --- a/reactos/drivers/net/dd/pcnet/pcnet.c +++ b/reactos/drivers/net/dd/pcnet/pcnet.c @@ -83,7 +83,9 @@ MiniportHandleInterrupt( ErrorHandled = TRUE; #endif - PCNET_DbgPrint(("error: %x\n", Data & (CSR0_MERR|CSR0_BABL|CSR0_CERR|CSR0_MISS))); + PCNET_DbgPrint(("error: %x\n", Data & (CSR0_MERR|CSR0_BABL|CSR0_CERR|CSR0_MISS))) + if (Data & CSR0_CERR) + Adapter->Statistics.XmtCollisions++; } else if(Data & CSR0_IDON) { @@ -128,6 +130,14 @@ MiniportHandleInterrupt( if(Descriptor->FLAGS & RD_ERR) { PCNET_DbgPrint(("receive descriptor error: 0x%x\n", Descriptor->FLAGS)); + if (Descriptor->FLAGS & RD_BUFF) + Adapter->Statistics.RcvBufferErrors++; + if (Descriptor->FLAGS & RD_CRC) + Adapter->Statistics.RcvCrcErrors++; + if (Descriptor->FLAGS & RD_OFLO) + Adapter->Statistics.RcvOverflowErrors++; + if (Descriptor->FLAGS & RD_FRAM) + Adapter->Statistics.RcvFramingErrors++; break; } @@ -153,6 +163,8 @@ MiniportHandleInterrupt( Adapter->CurrentReceiveDescriptorIndex++; Adapter->CurrentReceiveDescriptorIndex %= NUMBER_OF_BUFFERS; + + Adapter->Statistics.RcvGoodFrames++; } } else if(Data & CSR0_TINT) @@ -189,11 +201,25 @@ MiniportHandleInterrupt( if (Descriptor->FLAGS & TD1_ERR) { PCNET_DbgPrint(("major error: %x\n", Descriptor->FLAGS2)); + if (Descriptor->FLAGS2 & TD2_RTRY) + Adapter->Statistics.XmtRetryErrors++; + if (Descriptor->FLAGS2 & TD2_LCAR) + Adapter->Statistics.XmtLossesOfCarrier++; + if (Descriptor->FLAGS2 & TD2_LCOL) + Adapter->Statistics.XmtLateCollisions++; + if (Descriptor->FLAGS2 & TD2_EXDEF) + Adapter->Statistics.XmtExcessiveDefferals++; + if (Descriptor->FLAGS2 & TD2_UFLO) + Adapter->Statistics.XmtBufferUnderflows++; + if (Descriptor->FLAGS2 & TD2_BUFF) + Adapter->Statistics.XmtBufferErrors++; break; } Adapter->CurrentTransmitStartIndex++; Adapter->CurrentTransmitStartIndex %= NUMBER_OF_BUFFERS; + + Adapter->Statistics.XmtGoodFrames++; } NdisMSendResourcesAvailable(Adapter->MiniportAdapterHandle); } @@ -1040,8 +1066,8 @@ DriverEntry( NDIS_STATUS Status; RtlZeroMemory(&Characteristics, sizeof(Characteristics)); - Characteristics.MajorNdisVersion = 5; - Characteristics.MinorNdisVersion = 0; + Characteristics.MajorNdisVersion = NDIS_MAJOR_VERSION; + Characteristics.MinorNdisVersion = NDIS_MINOR_VERSION; Characteristics.HaltHandler = MiniportHalt; Characteristics.HandleInterruptHandler = MiniportHandleInterrupt; Characteristics.InitializeHandler = MiniportInitialize; diff --git a/reactos/drivers/net/dd/pcnet/pcnet.h b/reactos/drivers/net/dd/pcnet/pcnet.h index 4100ef494c5..589c000384c 100644 --- a/reactos/drivers/net/dd/pcnet/pcnet.h +++ b/reactos/drivers/net/dd/pcnet/pcnet.h @@ -28,6 +28,37 @@ #ifndef _PCNET_H_ #define _PCNET_H_ +/* FIXME: We should use a general way to do this for all drivers. */ +#ifdef __GNUC__ +#define memcpy(a,b,c) __builtin_memcpy(a,b,c) +#define memset(a,b,c) __builtin_memset(a,b,c) +#undef RtlFillMemory +#define RtlFillMemory(a,b,c) __builtin_memset(a,b,c) +#undef RtlZeroMemory +#define RtlZeroMemory(a,b) __builtin_memset(a,0,b) +#endif + +#define NDIS_MAJOR_VERSION 5 +#define NDIS_MINOR_VERSION 0 + +/* statistics struct */ +typedef struct _ADAPTER_STATS +{ + ULONG XmtGoodFrames; + ULONG XmtRetryErrors; + ULONG XmtLossesOfCarrier; + ULONG XmtCollisions; + ULONG XmtLateCollisions; + ULONG XmtExcessiveDefferals; + ULONG XmtBufferUnderflows; + ULONG XmtBufferErrors; + ULONG RcvGoodFrames; + ULONG RcvBufferErrors; + ULONG RcvCrcErrors; + ULONG RcvOverflowErrors; + ULONG RcvFramingErrors; +} ADAPTER_STATS, *PADAPTER_STATS; + /* adapter struct */ typedef struct _ADAPTER { @@ -69,6 +100,8 @@ typedef struct _ADAPTER ULONG ReceiveBufferLength; PCHAR ReceiveBufferPtrVirt; PCHAR ReceiveBufferPtrPhys; + + ADAPTER_STATS Statistics; } ADAPTER, *PADAPTER; /* forward declarations */ diff --git a/reactos/drivers/net/dd/pcnet/requests.c b/reactos/drivers/net/dd/pcnet/requests.c index bb2477eaa21..21e4d3b368e 100644 --- a/reactos/drivers/net/dd/pcnet/requests.c +++ b/reactos/drivers/net/dd/pcnet/requests.c @@ -56,11 +56,19 @@ static ULONG MiniportOIDList[] = OID_GEN_MAC_OPTIONS, OID_GEN_MEDIA_CONNECT_STATUS, OID_GEN_MAXIMUM_SEND_PACKETS, + OID_GEN_XMIT_OK, + OID_GEN_RCV_OK, + OID_GEN_XMIT_ERROR, + OID_GEN_RCV_ERROR, + OID_GEN_RCV_NO_BUFFER, OID_802_3_PERMANENT_ADDRESS, OID_802_3_CURRENT_ADDRESS, OID_802_3_MULTICAST_LIST, OID_802_3_MAXIMUM_LIST_SIZE, - OID_802_3_MAC_OPTIONS + OID_802_3_MAC_OPTIONS, + OID_802_3_RCV_ERROR_ALIGNMENT, + OID_802_3_XMIT_ONE_COLLISION, + OID_802_3_XMIT_MORE_COLLISIONS }; @@ -140,8 +148,12 @@ MiniportQueryInformation( case OID_GEN_MAXIMUM_FRAME_SIZE: { - /* XXX I'm not sure this is correct */ - GenericULONG = 1514; + /* + * The value returned by this OID must be equal to + * OID_GEN_MAXIMUM_TOTAL_SIZE - sizeof(ETHERNET_HEADER) + * where sizeof(ETHERNET_HEADER) is 14. + */ + GenericULONG = 1500; break; } @@ -206,12 +218,17 @@ MiniportQueryInformation( case OID_GEN_DRIVER_VERSION: { - GenericULONG = 1; + /* NDIS version used by the driver. */ + static const USHORT DriverVersion = + (NDIS_MAJOR_VERSION << 8) + NDIS_MINOR_VERSION; + CopyFrom = (PVOID)&DriverVersion; + CopySize = sizeof(DriverVersion); break; } case OID_GEN_MAXIMUM_TOTAL_SIZE: { + /* See comment in OID_GEN_MAXIMUM_FRAME_SIZE. */ GenericULONG = 1514; break; } @@ -275,6 +292,51 @@ MiniportQueryInformation( break; } + case OID_GEN_XMIT_OK: + GenericULONG = Adapter->Statistics.XmtGoodFrames; + break; + + case OID_GEN_RCV_OK: + GenericULONG = Adapter->Statistics.RcvGoodFrames; + break; + + case OID_GEN_XMIT_ERROR: + GenericULONG = Adapter->Statistics.XmtRetryErrors + + Adapter->Statistics.XmtLossesOfCarrier + + Adapter->Statistics.XmtCollisions + + Adapter->Statistics.XmtLateCollisions + + Adapter->Statistics.XmtExcessiveDefferals + + Adapter->Statistics.XmtBufferUnderflows + + Adapter->Statistics.XmtBufferErrors; + break; + + case OID_GEN_RCV_ERROR: + GenericULONG = Adapter->Statistics.RcvBufferErrors + + Adapter->Statistics.RcvCrcErrors + + Adapter->Statistics.RcvOverflowErrors + + Adapter->Statistics.RcvFramingErrors; + break; + + case OID_GEN_RCV_NO_BUFFER: + /* FIXME: Is this correct? */ + GenericULONG = Adapter->Statistics.RcvBufferErrors; + break; + + case OID_802_3_RCV_ERROR_ALIGNMENT: + /* XXX Implement me */ + GenericULONG = 0; + break; + + case OID_802_3_XMIT_ONE_COLLISION: + /* FIXME: Is this correct? */ + GenericULONG = Adapter->Statistics.XmtCollisions; + break; + + case OID_802_3_XMIT_MORE_COLLISIONS: + /* FIXME: Is this correct? */ + GenericULONG = Adapter->Statistics.XmtLateCollisions; + break; + default: { PCNET_DbgPrint(("Unknown OID\n")); @@ -295,7 +357,7 @@ MiniportQueryInformation( { NdisMoveMemory(InformationBuffer, CopyFrom, CopySize); *BytesWritten = CopySize; - *BytesNeeded = 0; + *BytesNeeded = CopySize; } }