NdisSendPackets

VOID
NdisSendPackets(
IN NDIS_HANDLE NdisBindingHandle,
IN PPNDIS_PACKET PacketArray,
IN UINT NumberOfPackets
);

NdisSendPackets forwards a multipacket send request, possibly with associated out-of-band information, to the underlying driver.

Parameters

NdisBindingHandle

Specifies the handle returned by NdisOpenAdapter that identifies the target NIC or the virtual adapter of the next-lower driver to which the caller is bound.

PacketArray

Points to an array of pointers to packet descriptors. Each packet descriptor in the array has chained buffer descriptors mapping buffers containing the data that the underlying NIC driver should transmit over the wire. Each packet descriptor also has an associated NDIS_PACKET_OOB_DATA block, which the caller has already set up with any timestamp and/or medium-specific out-of-band information, such as packet priority, relevant to the underlying driver.

NumberOfPackets

Specifies the number of pointers in the packet array.

Comments

Each element in the given array is a pointer to an NDIS_PACKET-type descriptor, and each packet descriptor can have caller-set TimeToSend and/or MediaSpecificInformation and MediaSpecificSize values in its associated NDIS_PACKET_OOB_DATA block. The caller must allocate each such packet descriptor with NdisAllocatePacket.

A protocol can set up this timestamp with the NDIS_SET_PACKET_TIME_TO_SEND and any out-of-band information that accompanies the send request with NDIS_SET_PACKET_MEDIA_SPECIFIC_INFO before it calls NdisSendPackets. The underlying driver retrieves this information with the reciprocal NDIS_GET_PACKET_XXX macros.

If necessary, a protocol also can call NdisSetPacketFlags to set the packet descriptor's flags with information for the underlying driver.

If the underlying NIC driver does not export a MiniportSendPackets handler, the NDIS library makes a sequence of calls, one for each packet in the supplied array, to that driver's MiniportSend function. NDIS submits packets individually to an underlying driver's MiniportSend function in the same order as they arrive in the supplied array.

NDIS submits packet arrays to an underlying driver's MiniportSendPackets function in the same order as they are passed to NdisSendPackets, but the underlying driver can return a subset of packets in any incoming array to NDIS by setting NDIS_STATUS_RESOURCES in the out-of-band data block for a single array element. When this occurs, NDIS queues that packet and all subsequent packets in the array for resubmission to the MiniportSendPackets function later.

In other words, NDIS always preserves the protocol-determined order of send packets, whether passed in calls to NdisSend or NdisSendPackets, and sees that they are given to the underlying driver in FIFO order. Before a protocol driver calls NdisSendPackets with an array of packet descriptor pointers, the protocol must ensure that the array of pointers has been set up in the same order as the packets should be sent over the wire.

The caller of NdisSendPackets should test the returned status for each packet in such an array individually when its ProtocolSendComplete function is called with the completion Status. While NDIS submits packets for transmission in the FIFO order determined by the sending protocol, underlying drivers can complete such sends in random order.

As soon as a protocol calls NdisSendPackets, it relinquishes ownership of the following:

·All packet descriptors at PacketArray

·All buffers mapped by the buffer descriptors chained to those packet descriptors

·All out-of-band data blocks associated with the packet descriptors, including any medium-specific buffers specified in the out-of-band data blocks

The protocol regains ownership of these resources, one packet at a time, as its ProtocolSendComplete function is called with each packet descriptor in the array given to NdisSendPackets.

When a packet descriptor is returned to ProtocolSendComplete, it can call NdisReinitializePacket to prepare the packet for reuse after saving the buffer descriptors chained to the packet descriptor with calls to an NdisUnchainBufferAtXxx function. Reusing such a packet descriptor yields better performance than returning the descriptor to driver-allocated packet pool with NdisFreePacket and, then, reallocating it for another send later.

ProtocolSendComplete also can prepare the out-of-band block associated with the given packet descriptor for reuse if the protocol supplies any out-of-band information. Alternatively, the protocol can explicitly reinitialize the members it uses when setting up the packet descriptor for a subsequent send.

An NDIS intermediate driver must repackage each incoming send from still higher level protocols in fresh packet descriptors before passing such a send request to the underlying miniport with NdisSendPackets (or NdisSend).

Callers of NdisSendPackets run at IRQL <= DISPATCH_LEVEL.

See Also

MiniportSend, MiniportSendPackets, NdisAllocateBuffer, NdisAllocatePacket, NdisFreePacket, NDIS_PACKET, NDIS_PACKET_OOB_DATA, NdisReinitializePacket, NdisSetPacketFlags, NDIS_SET_PACKET_MEDIA_SPECIFIC_INFO, NDIS_SET_PACKET_TIME_TO_SEND, NdisUnchainBufferAtBack, NdisUnchainBufferAtFront, ProtocolSendComplete