Sending Protocol Driver-Originated Packets (Windows Embedded CE 6.0)
1/6/2010
A protocol driver can transmit a single packet by calling NdisSend, passing a pointer to a packet descriptor with chained buffer descriptors mapping the buffered data to be sent. Alternatively, a protocol driver can transmit several packets using NdisSendPackets, passing in a pointer to an array of pointers to one or more packet descriptors.
In general, a protocol driver developer should choose whether to call NdisSend or NdisSendPackets based on the driver's requirements and on the characteristics of the underlying NIC driver.
When it has bound itself to an underlying NIC driver, a connectionless protocol driver should call NdisRequest with an OID_GEN_MAXIMUM_SEND_PACKETS query to determine the maximum number of send packets that the underlying driver will accept in a packet array. If the NIC driver supports only single-packet sends, either at its MiniportSend or its MiniportSendPackets function, the return value will be one or NDIS_STATUS_NOT_SUPPORTED. Either of these returns implies the protocol driver is likely to call NdisSend rather than NdisSendPackets. If the underlying driver returns a value greater than one, both drivers' performances will improve if the protocol driver sends an array of packets with NdisSendPackets. If OOB information is passed between the protocol driver and the NIC driver, either NDIS function can be called, because the underlying driver can read the OOB data using NDIS-supplied macros.
When a protocol driver calls NdisSend, it relinquishes ownership of the given packet resources until the send completes, either synchronously or asynchronously. If the status returned by NdisSend is something other than NDIS_STATUS_PENDING, the send completes synchronously and ownership of the protocol-allocated packet resources reverts to the protocol driver. If the status returned by NdisSend is NDIS_STATUS_PENDING, when the send subsequently completes, the final status of the send and the protocol-allocated packet descriptor will be passed in to the ProtocolSendComplete function.
When a protocol driver transmits one or more packets by calling NdisSendPackets, send operations are always asynchronous. The protocol driver relinquishes ownership of the packet resources that it allocated until each packet descriptor and the final status of the send for that packet is returned to ProtocolSendComplete.
Consequently, a protocol driver never reads the Status member in the OOB block associated with a packet descriptor on return from NdisSend(Packets). The protocol cannot learn the status of its send request in this manner because this member is in use by NDIS to track the progress of an in-transition send request and is volatile until the packet descriptor is returned to ProtocolSendComplete. A protocol driver always obtains the status of a transmit request either by examining the value returned by NdisSend or from the Status parameter passed to ProtocolSendComplete.
If a protocol driver requests the transmission of an array of packets of different priorities by arranging the packets it receives from clients before transmitting them, the protocol should place the highest priority packets at the beginning of the array. NDIS always preserves the ordering of packets in any array passed to NdisSendPackets, even if NDIS queues some of the packets internally.
NDIS does not attempt to examine and make queuing decisions based on the OOB data associated with the packet descriptors given to NdisSendPackets or to NdisSend. Unless a protocol driver has special knowledge of how the underlying NIC driver handles packet priorities or the TimeToSend timestamps, the protocol should assume that the underlying NIC driver transmits all packets in the order in which it receives them, preserving the as-received order. Consequently, a protocol should order the packet arrays it sends according to the order in which those packets should be transmitted over the network.
See Also
Reference
MiniportSend
MiniportSendPackets
NdisRequest
NdisSend
NdisSendPackets
OID_GEN_MAXIMUM_SEND_PACKETS
ProtocolSendComplete