NdisMIndicateReceivePacket (Windows CE 5.0)
This function notifies NDIS that an array of received packets is available to be forwarded to the appropriate bound protocol drivers.
[in] Handle originally input to the MiniportInitialize function.
[in] Pointer to an array of packet descriptor pointers, with each descriptor set up by the caller to specify the received data.
[in] Specifies how many pointers are in the array at ReceivePackets. The value must be at least 1.
Drivers of bus master DMA NICs are most likely to show significant gains in performance by making multipacket receive indications with this function. However, drivers that indicate out-of-band data with receive packets, such as packet priority and/or time stamps, can also call this function with a single packet at a time.
When a miniport calls this function, NDIS passes each pointer at ReceivePackets separately, in the miniport-determined order, to the ProtocolReceivePacket function of bound protocols that export this function. To other bound protocols, NDIS passes each packet pointer to the ProtocolReceive function.
If the miniport did not designate its NIC's medium as a type for which the system supplies a filter package in response to the OID_GEN_MEDIA_IN_USE query, NDIS forwards that driver's receive indications to all bound protocol drivers that export a ProtocolReceivePackets function. Otherwise, NDIS automatically applies the appropriate filter library to the miniport's receive indications.
Any caller of this function must first set up the packet array, as follows:
- Each element is the pointer to a packet descriptor, which the caller must allocate from a packet pool. Each packet descriptor can have at most 16 bytes in its ProtocolReserved section.
- All buffer descriptors chained to such a packet descriptor must be allocated from a buffer pool. The miniport must call the NdisAdjustBufferLength function with any buffer descriptor mapping a receive buffer on the NIC that contains less received data than the full range of the receive buffer so that the buffer descriptor maps only the received data for the indication. The NIC driver must readjust the mapping with NdisAdjustBufferLength when it regains ownership of such a buffer descriptor, as well.
- If the miniport indicates time stamps for received packets, it must set the TimeReceived and/or TimeSent members in the NDIS_PACKET_OOB_DATA structure associated with the packet descriptor using the NDIS_SET_PACKET_TIME_RECEIVED and/or NDIS_SET_PACKET_TIME_SENT macros. It can call the NdisGetCurrentSystemTime function once to set the receive time stamp for all packets of a particular packet array.
- The HeaderSize in the out-of-band data block must match the header size of each received packet for the medium. For example, a driver that selects Ethernet as its preferred medium at initialization would initialize the NDIS_PACKET_OOB_DATA structure HeaderSize to 14 when it allocates the packet descriptor.
- If the driver indicates additional out-of-band information with receives, it must set the SizeMediaSpecificInfo to the number of bytes of information supplied in the caller-allocated buffer at MediaSpecificInformation. The miniport can use the NDIS_SET_PACKET_MEDIA_SPECIFIC_INFO macro to set these values. Otherwise, SizeMediaSpecificInfo should be 0, and MediaSpecificInformation should be NULL.
- The miniport can set the Status member of the out-of-band data block to NDIS_STATUS_RESOURCES if it needs to retain ownership of the packet descriptor and buffer descriptors of some elements in a particular indication. Setting this status for a packet implicitly sets the same status for all subsequent packets of the indicated array. Setting NDIS_STATUS_RESOURCES forces NDIS to indicate each such packet, one at a time, to bound protocols' ProtocolReceive functions, thus forcing each protocol to copy the packet data and release each packet to be returned to the miniport.
- A deserialized miniport driver must save the Status member of the out-of-band data block in a local variable before indicating up the packet descriptor. As explained in more detail below, when NdisMIndicateReceivePacket returns, a deserialized miniport driver must check the saved packet Status to determine whether it can immediately reclaim the packet descriptor and the associated buffers.
If a serialized miniport driver does not set a packet's status in Status member of NDIS_PACKET_OOB_DATA to NDIS_STATUS_RESOURCES, the call to NdisMIndicateReceivePacket gives interested protocols exclusive, read-only access to the buffers chained to each packet. The miniport driver regains ownership of the packet descriptor and the associated buffers as follows:
- If the Status in the out-of-band data block is set to NDIS_STATUS_SUCCESS on return from NdisMIndicateReceivePacket, the miniport driver immediately regains ownership of the packet descriptor and all buffers chained to the packet. It can prepare these descriptors for reuse in subsequent receive indications.
- If the Status is set to NDIS_STATUS_PENDING on return from NdisMIndicateReceivePacket, the miniport driver regains ownership of the packet descriptor and all buffers chained to the packet when NDIS subsequently calls the miniport driver's MiniportReturnPacket function. It can then prepare these descriptors for reuse in subsequent receive indications.
A serialized miniport driver should use NDIS_GET_PACKET_STATUS to determine whether it has regained ownership of indicated packets when NdisMIndicateReceivePacket returns control.
A deserialized miniport driver must not examine the Status of indicated packets on return of NdisMIndicateReceivePacket. Instead, a deserialized miniport driver must save a packet's Status in a local variable before indicating up the packet descriptor. When NdisMIndicateReceivePacket returns, the miniport driver should check the saved packet Status. If the miniport driver set the packet's Status to NDIS_STATUS_RESOURCES before indicating up the packet descriptor, it should reclaim the packet descriptor immediately after NdisMIndicateReceivePacket returns, preferably by calling its own MiniportReturnPacket function. In this case, NDIS does not call the miniport driver's MiniportReturnPacket function to return the packet descriptor. If the miniport driver set the packet's Status to 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 MiniportReturnPacket function.
The miniport should use NDIS_GET_PACKET_STATUS to determine whether it has regained ownership of indicated packets when this function returns control. When the miniport regains ownership of an indicated packet descriptor, it prepares the associated out-of-band data block for reuse by passing the pointer returned by NDIS_OOB_DATA_FROM_PACKET to the NdisZeroMemory function. As an alternative, the miniport can simply reset the relevant members at the subsequent receive with the NDIS_SET_PACKET_XXX macros or with the pointer returned by NDIS_OOB_DATA_FROM_PACKET.
A miniport must not pass a packet descriptor pointer to NdisZeroMemory. Doing this destroys the packet descriptor, rendering it unusable for subsequent indications. To clear the associated out-of-band data block, the driver must pass the pointer returned by NDIS_OOB_DATA_FROM_PACKET.
Packet arrays passed to this function can be allocated on the stack.
Any miniport that calls this function must indicate full packets. Consequently, such a driver has no MiniportTransferData function.
OS Versions: Windows CE .NET 4.0 and later.
Link Library: Ndis.dll.
MiniportInitialize | MiniportReturnPacket | MiniportTransferData | NDIS_OOB_DATA_FROM_PACKET | NDIS_PACKET_OOB_DATA | NDIS_SET_PACKET_MEDIA_SPECIFIC_INFO | NDIS_SET_PACKET_TIME_RECEIVED | NDIS_SET_PACKET_TIME_SENT | NdisAdjustBufferLength | NdisAllocatePacket | NdisChainBufferAtBack | NdisChainBufferAtFront | NdisGetCurrentSystemTime | NdisZeroMemory | OID_GEN_MEDIA_IN_USE | ProtocolReceive | ProtocolReceivePacket
Send Feedback on this topic to the authors