NDIS_PACKET_OOB_DATA structure
Note NDIS 5. x has been deprecated and is superseded by NDIS 6. x. For new NDIS driver development, see Network Drivers Starting with Windows Vista. For information about porting NDIS 5. x drivers to NDIS 6. x, see Porting NDIS 5.x Drivers to NDIS 6.0.
The NDIS_PACKET_OOB_DATA structure specifies out-of-band information associated with a packet descriptor, used by drivers whose media supplies, requires, or accepts out-of-band information, such as information for an ATM NIC, and by drivers that support multipacket receives and/or sends.
Syntax
typedef struct _NDIS_PACKET_OOB_DATA {
union {
ULONGLONG TimeToSend;
ULONGLONG TimeSent;
};
ULONGLONG TimeReceived;
UINT HeaderSize;
UINT SizeMediaSpecificInfo;
PVOID MediaSpecificInformation;
NDIS_STATUS Status;
} NDIS_PACKET_OOB_DATA, *PNDIS_PACKET_OOB_DATA;
Members
TimeToSend
Specifies the time, in system time units, at which a given packet should be transmitted over the network.Protocols can set this timestamp before passing an array of packet descriptor pointers to NdisSendPackets or a packet descriptor pointer to NdisSend.
The MiniportSendPackets or MiniportSend functions of underlying drivers can retrieve the value of this timestamp to determine when the given packet(s) should be transmitted over the network. Usually, only the lowest-level underlying driver retrieves this timestamp.
TimeSent
Specifies the time, in system time units, at which a received packet was transmitted over the network from a remote node.NIC drivers and, possibly, intermediate drivers that export only a set of MiniportXxx functions set this timestamp before indicating receive packet(s).
The ProtocolReceivePacket functions of drivers bound above such a miniport driver can retrieve the value of this timestamp to determine when any particular packet was transmitted from the remote node. If the ProtocolReceive function is given an indication and the underlying driver sets this timestamp, ProtocolReceive can call NdisGetReceivedPacket and NDIS_GET_ORIGINAL_PACKET to retrieve the packet that contains this timestamp.
TimeReceived
Specifies the time, in system time units, at which a given packet from a remote node on the network was received on the NIC.NIC drivers and, possibly, intermediate drivers that export only a set of MiniportXxx functions set this timestamp before calling NdisMIndicateReceivePacket with a packet array, which can have one or more pointers to packet descriptors.
The ProtocolReceivePacket functions of drivers bound above any such miniport driver can retrieve the value of this timestamp to determine when the given packet(s) were received. If the ProtocolReceive function is given an indication and the underlying driver sets this timestamp, ProtocolReceive can call NdisGetReceivedPacket and NDIS_GET_ORIGINAL_PACKET to retrieve the packet that contains this timestamp.
HeaderSize
Specifies the size in bytes of the medium-specific header contained in the buffer mapped by the initial buffer descriptor chained to the packet descriptor.Lower-level drivers set this member for subsequent receive indication(s) according to the medium each driver's MiniportInitialize function elected to support.
The ProtocolReceivePacket functions of drivers bound above such a miniport driver can retrieve the value of this member to determine how to process the medium-specific net packet.
SizeMediaSpecificInfo
Specifies the size in bytes of the buffer at MediaSpecificInformation.A driver must set this member if it supplies out-of-band information with a packet to be sent or indicated.
MediaSpecificInformation
Specifies the address of a driver-allocated buffer. This buffer contains any out-of-band data, such as information for an ATM NIC, that accompanies the net packet specified with the packet descriptor. The out-of-band data has been set up either by the allocating protocol for a send or by the allocating miniport driver for a receive indication.Either type of driver can retrieve the address of the out-of-band data buffer and its size to determine how to process or interpret the send or receive specified with the incoming packet descriptor. If the ProtocolReceive function is given an indication and the underlying driver supplies this information, ProtocolReceive can call NdisGetReceivedPacket and NDIS_GET_ORIGINAL_PACKET to retrieve the packet that contains the virtual range of this buffer.
Status
Specifies the current status of the packet descriptor and the ownership of all driver-allocated resources specified with the packet descriptor.Only lower-level drivers and NDIS set this member.
In the Receive Path
A miniport driver can set this member before it calls NdisMIndicateReceivePacket to indicate how soon it needs to regain ownership of its allocated resources specified in the associated packet descriptor(s). A serialized can retrieve this value on return from NdisMIndicateReceivePacket to determine whether the resources specified with the packet descriptor for its indication can be prepared for reuse immediately. A deserialized or connection-oriented miniport, however, does not have to check this value on return from NdisMCoIndicateReceivePacket.
In the Send Path
A serialized miniport driver can set this member in its MiniportSendPackets function to complete an incoming send immediately, to notify NDIS that it will complete the request asynchronously, or to request that NDIS requeue some or all of the incoming packet array and resubmit those packet descriptor(s) to MiniportSendPackets later.
A protocol cannot retrieve this value to determine the completion status of a send on return from its call to NdisSendPackets or NdisSend.
A deserialized or connection-oriented miniport driver cannot complete a multipacket send synchronously or request (by setting the Status member) that NDIS requeue some or all of an incoming packet array. Instead, a deserialized or connection-oriented miniport driver must queue internally the entire incoming packet array if it cannot send the data immediately and must always complete a multipacket send asynchronously with NdisMSendComplete(or NdisMCoSendComplete) for each packet in the array.
Using Timestamps
All timestamps set in the NDIS_PACKET_OOB_DATA blocks associated with packet descriptors are expressed in system time units as the number of 100-nanosecond intervals since 12:00 a.m., January 1, 1601.
NDIS drivers can call NdisGetCurrentSystemTimewhen they set these timestamps with the NDIS_SET_PACKET_TIME_XXX macros. Still higher-level drivers or system components can convert these timestamps into locale-specific values more meaningful to the end user.
Supplying Out-of-Band Information with Packets
Any out-of-band information specified in the SizeMediaSpecificInfoand MediaSpecificInformationmembers is medium-type-specific. For example, some types of media require protocols to specify a packet priority for each packet they send and require NIC drivers to specify a packet priority with each receive packet they indicate. Such a NIC driver must call NdisMIndicateReceivePacketor NdisMCoIndicateReceivePacketto fulfill the requirements of these types of media.
While NDIS provides support for a range of priority values from zero through seven, some media support only two levels of priority. For these types of media, NDIS drivers should map values zero through three to the medium-specific normal priority value (usually zero for such media types) and values four through seven to the medium-specific, high-priority value (usually one for such media types).
The structure of individual records within the buffer at MediaSpecificInformationis defined as follows:
typedef struct MediaSpecificInformation {
UINT NextEntryOffset;
NDIS_CLASS_ID ClassId;
UINT Size;
UCHAR ClassInformation[1];
} MEDIA_SPECIFIC_INFORMATION;
The members of this structure contain the following information:
NextEntryOffset
Specifies the byte offset to this member in the next record, if any. Zero indicates this is the last record in the buffer; the values of all remaining members in the last record are also zero. The value of this member must be quad-aligned.ClassId
Specifies the type of the record. Possible values are one of the following:NdisClass802_3Priority
This value is no longer used. Per-packet priority is a member of the array that is contained in a NDIS_PACKET_EXTENSION structure. Drivers should use the NDIS_PER_PACKET_INFO_FROM_PACKET macro to access packet priority from a packet descriptor. Alternatively, drivers can use the NDIS_PACKET_EXTENSION_FROM_PACKET macro to access packet priority from a packet descriptor.NdisClassWirelessWanMbxMailbox
The underlying NIC driver examines the ULONG-sized record at ClassInformation to determine whether the mailbox flag should be set for the associated packet. (1 = set mailbox flag, 0 = do not set mailbox flag)NdisClassIrdaPacketInfo
An underlying IrDA NIC driver examines the NDIS_IRDA_PACKET_INFO structure at ClassInformation to determine the number of extra Beginning of Frame (BOF) flags that it must add to a frame to be transmitted and the minimum time (in microseconds) that it must wait after receiving a transmission before its NIC can start transmitting.The NDIS_IRDA_PACKET_INFO structure is defined as follows:
typedef struct _NDIS_IRDA_PACKET_INFO { UINT ExtraBOFs UNIT MinTurnAroundTime; } NDIS_IRDA_PACKET_INFO, *PNDIS_IRDA_PACKET_INFO;
NdisClassAtmAALInfo
Before sending a packet to an underlying NDIS driver for an ATM NIC, a protocol driver sets the appropriate information in the ATM_AAL_OOB_INFO structure at ClassInformation.The ATM_AAL_OOB_INFO structure is defined as follows:
typedef struct _ATM_AAL_OOB_INFO { ATM_AAL_TYPE AalType; union { struct _ATM_AAL5_INFO { BOOLEAN CellLossPriority; UCHAR UserToUserIndication; UCHAR CommonPartIndicator; } ATM_AAL5_INFO; struct _ATM_AAL0_INFO { BOOLEAN CellLossPriority; UCHAR PayLoadTypeIdentifier; } ATM_AAL0_INFO; }; } ATM_AAL_OOB_INFO, *PATM_AAL_OOB_INFO;
When sending an AAL5 packet, the protocol sets the members of the ATM_AAL5_INFO structure ( CellLossPriority, UserToUserIndication, and CommonPartIndicator) to the values to which the miniport driver should set the corresponding fields of the ATM packet header. When sending an AAL0 packet, the protocol sets the members of the ATM_AAL0_INFO structure ( CellLossPriority and CommonPartIndicator) to the values to which the miniport driver should set the corresponding fields of the ATM cell header.
The underlying driver examines the ATM_AAL_OOB_INFO structure to obtain values for fields in the AAL5 packet header or the AAL0 cell header.
Size
Specifies the number of bytes in the ClassInformation array, including any padding necessary to align the NextEntryOffset of the next record on a four-byte boundary.ClassInformation
Specifies the out-of-band information for this record.
The NDIS_CLASS_ID type is an NDIS-defined enumeration. Most common classifications for records will be specified as system-defined values. However, a range of values in this enumeration will be available for vendor-defined experimental classes.
Setting Status Before Making Receive Indications
Only lower-level NDIS drivers use the Statusmember of this structure for receive indications. Before such a driver calls NdisMIndicateReceivePacket, it sets the Statuswith NDIS_SET_PACKET_STATUSfor one or more packet descriptors in the array to be indicated to either of the following values:
NDIS_STATUS_SUCCESS
Tells NDIS that the driver is relinquishing ownership of the packet about to be indicated with NdisMIndicateReceivePacket or NdisMCoIndicateReceivePacket until the packet descriptor is returned to its MiniportReturnPacket function.Protocols that receive the indication can use the packet descriptor, along with all buffers mapped by buffer descriptors chained to the packet descriptor and any out-of-band information supplied with the packet, to copy the indicated net packet data or, possibly, to forward the indicated data to interested clients.
NDIS_STATUS_RESOURCES
Tells NDIS that the driver is retaining ownership of the packet about to be indicated with NdisMCoIndicateReceivePacket. This packet will be indicated to the ProtocolReceive or ProtocolCoReceivePacket functions of bound protocols.Setting this status forces bound protocols to return ownership of each such packet descriptor, of any medium-specific buffer in the out-of-band data block for each packet descriptor, and of the memory mapped by each packet descriptor's respective chained buffer descriptors to the indicating driver more quickly. The protocols must wait for a call to their ProtocolReceiveComplete functions to begin postprocessing the data they copied from indication(s) and forwarding the data to clients.
An indicating driver can set this status if it is running low on packet pool or buffer pool. An indicating NIC driver can set this status if it is running low on NIC receive buffers due to high network traffic. A bus-master DMA NIC driver might call NdisMAllocateSharedMemoryAsync in these circumstances to get additional NIC receive buffer space.
A deserialized or connection-oriented miniport driver must save the Statusmember of the out-of-band data block in a local variable before indicating up the packet descriptor. As explained in more detail below, when NdisMIndicateReceivePacketreturns, a deserialized miniport driver must check the saved packet Statusto determine whether it can immediately reclaim the packet descriptor and the associated buffers.
Getting Status on Return from NdisMIndicateReceivePacket
After a serialized driver has set the Statusfor some number of packet descriptors and called NdisMIndicateReceivePacketwith the array of pointers to the packet descriptors, it must use the NDIS_GET_PACKET_STATUSmacro when NdisMIndicateReceivePacketreturns control to retrieve the Statusset by NDIS.
The returned Statusin the NDIS_PACKET_OOB_DATA block associated with each packet descriptor that the serialized driver indicated with NDIS_STATUS_SUCCESS determines what the indicating driver does next, as follows:
NDIS_STATUS_SUCCESS
If this is set on return from a miniport's call to NdisMIndicateReceivePacket, the miniport driver regains ownership of the following:The packet descriptor
The associated out-of-band data block associated with the packet descriptor and of any media-specific information buffer specified in this block
All buffers mapped by buffer descriptors chained to the packet descriptor
NDIS guarantees that any packet descriptors for which the indicating driver set NDIS_STATUS_RESOURCES, as already described, will be returned from its call to NdisMIndicateReceivePacket with NDIS_STATUS_SUCCESS.
The driver can prepare these descriptors, the out-of-band block, and media-specific information buffer, if any, for reuse in subsequent receive indications immediately.
NDIS_STATUS_PENDING
If this is set on return from NdisMIndicateReceivePacket, protocols retain ownership of the packet descriptor, of its associated out-of-band data block and of any buffer specified in this block, and of all buffers mapped by buffer descriptors chained to the packet descriptor until the packet descriptor is returned to the indicating driver's MiniportReturnPacket function.
A deserialized or connection-oriented miniport driver must not examine the Statusof indicated packets on return of NdisMIndicateReceivePacket. Instead, a deserialized miniport driver must save a packet's Statusin a local variable before indicating up the packet descriptor. When NdisMIndicateReceivePacketreturns, the miniport driver should check the saved packet Status. If the miniport driver set the packet's Statusto NDIS_STATUS_RESOURCES before indicating up the packet descriptor, it should reclaim the packet descriptor immediately after NdisMIndicateReceivePacketreturns, preferably by calling its own MiniportReturnPacketfunction. In this case, NDIS does not call the miniport driver's MiniportReturnPacketfunction to return the packet descriptor. If the miniport driver set the packet's Statusto NDIS_STATUS_SUCCESS before indicating up the packet descriptor, the miniport driver must not reclaim the packet descriptor until NDIS subsequently returns the packet descriptor to the miniport driver's MiniportReturnPacketfunction.
Setting Status in MiniportSendPackets
Only underlying serialized NDIS drivers with MiniportSendPacketsfunctions can use the Statusmember of this structure for packet descriptors specifying sends. Such a driver's MiniportSendPacketsfunction sets the Statusmember in the out-of-band data blocks associated with the packet descriptors in the input array as follows:
If the driver will complete the send operation asynchronously, MiniportSendPackets sets NDIS_STATUS_PENDING in the Status member for the given packet descriptor.
If the driver cannot process all sends in a given packet array due to current resource constraints, MiniportSendPackets sets NDIS_STATUS_RESOURCES in the Status member for one packet descriptor.
NDIS queues these packet descriptors internally in the same order for resubmission to MiniportSendPackets when the driver calls NdisMSendResourcesAvailable or NdisMSendComplete, whichever occurs first. NDIS reflects this miniport-set status value to protocols as NDIS_STATUS_PENDING.
If MiniportSendPackets will complete a given send request before it returns control, it must set the Status member for the given packet descriptor to a driver-determined status value so that NDIS can reflect this status back to the protocol that initiated the send.
Otherwise, such a driver supplies the completion status for each packet when it calls NdisMSendCompletewith the packet descriptor. Drivers that have MiniportSendinstead of MiniportSendPacketsfunctions return the status for each incoming send packet, so such a driver never sets the Statusmember of the out-of-band data block for a packet descriptor specifying a send.
Protocols cannot determine the completion status for a protocol-allocated packet descriptor from the Statusmember of the associated OOB block on return from NdisSendPacketsor NdisSend. This value can change dynamically as NDIS submits, requeues, and resubmits send packet(s) to underlying drivers' MiniportSendPacketsand/or MiniportSendfunctions.
A protocol cannot use any NDIS_GET_PACKET_XXX macro nor the NDIS_OOB_DATA_FROM_PACKET macro to access the OOB data block for such a protocol-allocated packet descriptor until its ProtocolSendCompletefunction is called with the packet descriptor.
Remarks
Every packet descriptor allocated with NdisAllocatePacket has an associated NDIS_PACKET_OOB_DATA block. Only drivers that support multipacket sends and/or receives and drivers that supply out-of-band information, such as packet priority, with each network packet to be transferred use the OOB block. Nevertheless, every NDIS driver that allocates packet descriptors for transfers between bound drivers must allocate those packet descriptors with NdisAllocatePacket from the packet pool that each such NDIS driver usually allocates when it initializes.
In general, drivers of high-capacity bus-master DMA NICs are most likely to support multipacket receives and sends because such a NIC driver makes the greatest performance gains by supporting multipacket transfers. Any protocol that binds itself to (or above) such an underlying NIC driver also should support multipacket sends and receives for maximum performance.
If such a protocol also binds itself above another NIC driver without multipacket transfer support, NDIS handles multipacket sends and single-packet receives in a manner transparent to both drivers by always calling the protocol's ProtocolReceive function and by calling that NIC driver's MiniportSend function with a single packet per call. Similarly, if a protocol that does not support multipacket transfers binds itself above a NIC driver that does, NDIS handles multipacket receive indications and single packet sends in a manner transparent to both drivers, although the MiniportSendPackets function of the underlying NIC driver is given only a single send request per call to NdisSend from such a protocol.
Requirements
Header |
Ndis.h (include Ndis.h) |
See also
NDIS_GET_PACKET_MEDIA_SPECIFIC_INFO
NDIS_SET_PACKET_MEDIA_SPECIFIC_INFO