VOID
NdisSend(
OUT PNDIS_STATUS Status,
IN NDIS_HANDLE NdisBindingHandle,
IN PNDIS_PACKET Packet
);
NdisSend forwards a send request to the underlying driver.
The specific NDIS_STATUS_XXX returned for device I/O errors that occur
during a transmit operation depend on the nature of the NIC and the discretion
of the NIC driver writer. For example, a minport might return
NDIS_STATUS_NO_CABLE if its NIC indicates this condition to the driver.
Before calling NdisSend, a protocol driver can call NdisSetPacketFlags to set the flags in the private header (reserved for use by NDIS) of the packet descriptor it allocated. These flags specify caller-determined information about the requested send operation that is not contained in the packet data. The underlying NIC driver’s MiniportSend function is given the send flags as an input parameter. The meaning of the packet flags bits is medium-specific and defined by the pair of collaborating drivers.
However, such a pair of collaborating drivers can use the NDIS_PACKET_OOB_DATA block associated with each packet descriptor to communicate far more information than the packet flags can convey. Before calling NdisSend, a protocol can use the NDIS_SET_PACKET_TIME_TO_SEND and/or NDIS_SET_PACKET_MEDIA_SPECIFIC_INFO macros to set up out-of-band information, if any, relevant to the underlying driver in the NDIS_PACKET_OOB_DATA block associated with the protocol-allocated packet descriptor.
When an underlying driver has insufficient resources to transmit a valid send packet, the driver has two alternatives:
The driver holds the packet queued until resources become available and sends the packet when they are.
The NDIS library holds such a returned packet in an internal queue for resubmission to the miniport. The miniport can indicate its readiness to accept send packets later by calling NdisMSendResourcesAvailable or NdisMSendComplete, whichever call occurs first.
In either of the preceding scenarios, NdisSend returns NDIS_STATUS_PENDING to the caller, and the driver’s ProtocolSendComplete function is called when the packet is transmitted.
As soon as a protocol calls NdisSend, it relinquishes ownership of the packet descriptor at Packet, of all buffers mapped by buffer descriptors it chained to the packet, and of any out-of-band information it supplied with the packet descriptor. The protocol regains ownership of these resources when the packet is completed with a status other than NDIS_STATUS_PENDING or when its ProtocolSendComplete function is called.
When either occurs, the protocol 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 packet to driver-allocated packet pool with NdisFreePacket and, then, reallocating it for another send later.
An NDIS intermediate driver must repackage incoming sends from still higher level protocols in fresh packet descriptors before passing such a send request to the underlying miniport with NdisSend (or NdisSendPackets).
Callers of NdisSend run at IRQL <= DISPATCH_LEVEL.
MiniportSend, NdisAllocateBuffer, NdisAllocatePacket, NdisFreePacket, NdisGetPacketFlags, NdisMSendResourcesAvailable, NDIS_PACKET, NDIS_PACKET_OOB_DATA, NdisReinitializePacket, NdisSendPackets, NdisSetPacketFlags, NDIS_SET_PACKET_MEDIA_SPECIFIC_INFO, NDIS_SET_PACKET_TIME_TO_SEND, NdisUnchainBufferAtBack, NdisUnchainBufferAtFront, ProtocolSendComplete, ProtocolStatus