4.3 Packet Out-Of-Band Data

Every NDIS_PACKET-type descriptor has an associated out-of-band data block in which media-specific and priority information is passed. This substructure is defined as:

typedef struct _NDIS_PACKET_OOB_DATA {
Union {
ULONGLONG TimeToSend;
ULONGLONG TimeSent
}
ULONGLONG TimeReceived;
UINT HeaderSize;
UINT SizeMediaSpecificInformation;
PVOID MediaSpecificInformation
NDIS_STATUS Status;
}; NDIS_PACKET_OOB_DATA, *PNDIS_PACKET_OOB_DATA

A miniport NIC driver that has support for OOB data should use the NDIS macros provided for this purpose. It should never attempt to calculate offsets or otherwise depend on knowing the exact structure of a packet's OOB data.

PNDIS_OOB_DATA_FROM_PACKET( Packet )

Returns a pointer to the NDIS_PACKET_OOB_DATA substructure. This pointer can be used to access members of NDIS_PACKET_OOB_DATA by member name.

NDIS_SET_PACKET_STATUS( Packet, Status )

Sets the Status member.

NDIS_SET_PACKET_TIME_TO_SEND( Packet, TimeToSend )

Sets the TimeToSend member.

NDIS_SET_PACKET_TIME_SENT( Packet, TimeSent )

Sets the TimeSent member.

NDIS_SET_PACKET_TIME_RECEIVED( Packet, TimeReceived )

Sets the TimeReceived member.

NDIS_SET_PACKET_HEADER_SIZE( Packet, HeaderSize )

Sets the HeaderSize member.

NDIS_SET_PACKET_MEDIA_SPECIFIC_INFO( Packet, MediaSpecificInfo, SizeMediaSpecificInfo )

Sets the MediaSpecificInformation and SizeMediaSpecificInformation)

NDIS_GET_PACKET_STATUS( Packet )

Returns the Status member.

NDIS_GET_PACKET_TIME_TO_SEND( Packet )

Returns the TimeToSend member.

NDIS_GET_PACKET_TIME_SENT( Packet )

Returns the TimeSent member.

NDIS_GET_PACKET_TIME_RECEIVED( Packet )

Returns the TimeReceived member.

NDIS_GET_PACKET_HEADER_SIZE( Packet )

Returns the HeaderSize member.

NDIS_GET_PACKET_MEDIA_SPECIFIC_INFO( Packet, pMediaSpecificInfo, pSizeMediaSpecificInfo )

Returns media-specific information in a buffer whose address is provided by the caller and the size in bytes of that information stored in a caller-supplied variable.

OOB Data on a Send

If a miniport supports media specific information and/or priority, when it receives a packet to send it might do one or more of the following:

·Get TimeToSend

·Get SizeMediaSpecificInformation and MediaSpecificInformation

Before returning, MiniportSendPackets sets the Status member for each packet it was passed. It sets Status to something other than NDIS_STATUS_PENDING if it completes the send synchronously. Otherwise, MiniportSendPackets sets the Status member to NDIS_STATUS_PENDING. Later, when the send completes, the status of the send must be returned in the Status parameter to NdisMSendComplete. After MiniportSendPackets returns, the Status member of the OOB data, as well as all other members, are read-only to the NIC driver.

If MiniportSend is called, and the send is synchronous, status is returned as the status of MiniportSend. The OOB data is never used to return the status of a MiniportSend operation.

In summary:

·All but the Status member of the OOB data is read-only to MiniportSendPackets. Status is written to return the status of the send for each packet that is completed synchronously.

·When a packet is sent asynchronously, either by MiniportSend or MiniportSendPackets, the final status of the send is always returned as a parameter to NdisMSendComplete.

·All the OOB data is read-only to MiniportSend. MiniportSend always returns the status of the send as the status of MiniportSend. If the status returned is NDIS_STATUS_PENDING, the status is returned later as a parameter to NdisMSendComplete.

OOB Data on a Receive

If a miniport passes media-specific information and/or priority, it must indicate received data by indicating up an entire packet(s) with NdisMIndicateReceivePacket. Before indicating the packet, the miniport must write the Status member of the OOB. The miniport must always set the Status member, either to NDIS_STATUS_RESOURCES, if it doesn't want the higher layer driver(s) to keep the packet, otherwise to NDIS_STATUS_SUCCESS.

In addition, the miniport might write one or more of the following:

·Set TimeSent if it can be determined, for instance by an ATM NIC driver.

·Set TimeReceived.

·Set HeaderSize. Typically, a miniport only needs to set this once per packet descriptor when the packet descriptor is initialized.

·Set the pointer to MediaSpecificInformation and the SizeMediaSpecificInfo.

When NdisMIndicateReceivePacket returns, the OOB data is read-only to the miniport. The miniport should read the Status member to determine which packets are now available for reuse because they have already been consumed by higher layer(s). Such packets will have a status other than NDIS_STATUS_PENDING. Any packet with a Status of NDIS_STATUS_PENDING is owned by a higher layer driver(s), is currently unavailable to the miniport, and will be returned later to the miniport at its MiniportReturnPacket function.

If the miniport writes a status of NDIS_STATUS_RESOURCES in any packet in the array of packets that it indicates up, that packet and any packet(s) following it in the array will be returned to the miniport when NdisMIndicateReceivePacket returns.