Microsoft KB Archive/263131

= INFO: Implementation of 64-Bit Statistics in Network Interface Card (NIC) Drivers =

Article ID: 263131

Article Last Modified on 2/23/2007

-

APPLIES TO


 * Microsoft Windows 2000 Server
 * Microsoft Windows 2000 Advanced Server
 * Microsoft Windows 2000 Professional Edition
 * Microsoft Win32 Device Driver Kit for Windows 2000
 * Microsoft Windows XP Driver Development Kit

-



This article was previously published under Q263131



SUMMARY
Miniport statistics are maintained in 32-bit counters. These counters can overflow very quickly given today's media speeds (for example, it takes about 68 seconds at a sustained throughput of 500 megabits per second [Mpbs] to overflow a 32-bit byte counter). Larger counters are therefore needed. This article shows how to implement 64-bit counters in your driver to resolve this problem (at a sustained throughput of 10 gigabits per second, it takes 467 years to overflow a 64-bit byte counter).



MORE INFORMATION
All Gigabit Ethernet drivers must support 64-bit counters for at least the following object identifiers (OIDs). Microsoft recommends that all 100 Mbps and above network interface card (NIC) drivers should support 64-bit counters. Drivers may support 64-bit counters for other statistics OIDs (for example, OID_GEN_XMIT_ERROR): // Required statistics.
 * 1) define OID_GEN_XMIT_OK                        0x00020101
 * 2) define OID_GEN_RCV_OK                         0x00020102

// Optional statistics.
 * 1) define OID_GEN_DIRECTED_BYTES_XMIT            0x00020201
 * 2) define OID_GEN_DIRECTED_FRAMES_XMIT           0x00020202
 * 3) define OID_GEN_MULTICAST_BYTES_XMIT           0x00020203
 * 4) define OID_GEN_MULTICAST_FRAMES_XMIT          0x00020204
 * 5) define OID_GEN_BROADCAST_BYTES_XMIT           0x00020205
 * 6) define OID_GEN_BROADCAST_FRAMES_XMIT          0x00020206
 * 7) define OID_GEN_DIRECTED_BYTES_RCV             0x00020207
 * 8) define OID_GEN_DIRECTED_FRAMES_RCV            0x00020208
 * 9) define OID_GEN_MULTICAST_BYTES_RCV            0x00020209
 * 10) define OID_GEN_MULTICAST_FRAMES_RCV           0x0002020A
 * 11) define OID_GEN_BROADCAST_BYTES_RCV            0x0002020B
 * 12) define OID_GEN_BROADCAST_FRAMES_RCV           0x0002020C

Implementation
The length of the buffer (InformationBufferLength) that is passed in an NDIS_REQUEST for a statistics OID is used to determine how many bits (64, 128, 256, and so on) are required.

The semantics of fields in NDIS_REQUEST.DATA.QUERY_INFORMATION for statistics is as follows:

On Input to NDIS/Miniport
InformationBufferLength = 4 // or 8 bytes depending on what the requestor needs.

On Completion
BytesWritten = MIN(InformationBufferLength, N) where N is the maximum bytes of statistics implemented by the miniport: BytesNeeded = N A miniport that implements 64-bit counters follows the algorithm above to copy the right amount of data to satisfy the request. A code example follows: // // The driver's adapter structure: // typedef struct _NICDRIVER_ADAPTER {   ...    ULONG64         TransmitsOk; ... } _NICDRIVER_ADAPTER, *PNICDRIVER_ADAPTER;

NDIS_STATUS NicDriverQueryInformation(                    IN NDIS_HANDLE MiniportAdapterContext,                     IN NDIS_OID Oid,                     IN PVOID InformationBuffer,                     IN ULONG InformationBufferLength,                     OUT PULONG BytesWritten,                     OUT PULONG BytesNeeded                     ) {   PNICDRIVER_ADAPTER  pAdapter; PVOID          MoveSource; ULONG          MoveBytes; ULONG          GenericUlong; ULONG64                    GenericLargeCounter; ULONG          MyBytesNeeded; NDIS_STATUS    Status;

pAdapter = (PNICDRIVER_ADAPTER)MiniportAdapterContext; MoveSource = &GenericUlong; MoveBytes = sizeof(GenericUlong); MyBytesNeeded = MoveBytes; Status = NDIS_STATUS_SUCCESS;

switch (Oid) {       case OID_GEN_MAC_OPTIONS: GenericUlong = (ULONG)(NDIS_MAC_OPTION_TRANSFERS_NOT_PEND  |                                                                       NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA  |                            NDIS_MAC_OPTION_NO_LOOPBACK); break;

case OID_GEN_XMIT_OK: //            // Modified code to handle 64-bit statistics: //

GenericLargeCounter = pAdapter->TransmitsOk; MoveSource = &GenericLargeCounter; MyBytesNeeded = sizeof(GenericLargeCounter);

//            // A statistics counter is at least a ULONGs worth. //

if (InformationBufferLength < sizeof(ULONG)) {               // Set up for failure return below. MoveBytes = MyBytesNeeded; break; }           MoveBytes = MIN(InformationBufferLength, MyBytesNeeded); break; // Case statements for other OIDs. }

if (Status == NDIS_STATUS_SUCCESS) {       *BytesNeeded = MyBytesNeeded; if (MoveBytes > InformationBufferLength) {           Status = NDIS_STATUS_BUFFER_TOO_SHORT; }       else {           *BytesWritten = MoveBytes; if (MoveBytes != 0) {               NdisMoveMemory(InformationBuffer, MoveSource, MoveBytes); }       }    }

Keywords: kbinfo kbndis kbnetwork KB263131

-

[mailto:TECHNET@MICROSOFT.COM Send feedback to Microsoft]

© Microsoft Corporation. All rights reserved.