Sending on a WAN Miniport Driver (Windows Embedded CE 6.0)
An upper-layer driver calls the NdisSend function to send packets to an underlying WAN miniport driver. The NDISWAN intermediate driver then forwards those packets from the upper-layer driver. Before NDISWAN forwards packets, it repackages them. NDISWAN also reformats the structure of packets from NDIS Packet Structure structures into NDIS_WAN_PACKET structures before forwarding.
After NDISWAN forwards packets, NDIS calls the WAN miniport driver's send function. For a standard WAN miniport driver, this send function is MiniportWanSend. MiniportWanSend transmits packets through the NIC onto the wide area network.
Ownership of both the packet descriptor and the packet data is transferred to the WAN miniport driver until the send completes, either synchronously or asynchronously. The WAN miniport driver returns NDIS_STATUS_PENDING from its send function to indicate that it has not finished transmitting the packet. For a standard WAN miniport driver, this completion function is NdisMWanSendComplete.
These completion calls do not necessarily imply that a packet has been transmitted, although, with the exception of intelligent NICs, the packet generally has been transmitted. These calls do, however, indicate that the WAN miniport driver is ready to release ownership of the packet.
If the WAN miniport driver returns a status other than NDIS_STATUS_PENDING, the send operation is considered complete, and ownership of the packet immediately reverts to the caller. In this case, the WAN miniport driver does not call a completion function for that packet.
After the WAN miniport driver receives the packets, it should send the packets to the active connection.
Unlike LAN miniport drivers, the WAN miniport driver cannotreturn a status of NDIS_STATUS_RESOURCES to indicate that it does not have enough resources available to process the transmission of packets. Instead, the WAN miniport driver should queue the send operation internally for a later time and perhaps lower the send-window value on the connection. This send-window value is the number of outstanding packets that the WAN miniport driver can handle per connection and is specified by the miniport driver to an upper-layer driver.
The WAN miniport driver specifies the default number of outstanding packets that it can have per data channel in the MaxTransmit member of the NDIS_WAN_INFO structure. The miniport driver provides this structure when the miniport driver responds to the OID_WAN_GET_INFO request from the protocol driver. However, the miniport driver can manage the send window dynamically and on a per-line basis by calling NdisMIndicateStatus with a line-up indication. In this call, the miniport driver provides a new nonzero value for the SendWindow member of the NDIS_MAC_LINE_UP structure passed in the call. If the miniport driver sets the value of the SendWindow member to 0, NDISWAN uses the default value in MaxTransmit for that line.
The standard WAN miniport driver might need to modify or add to the header as well as add to the end of the packet, for example, to add the FCS. The miniport driver provided appropriate padding at the beginning and end of the packet previously. The WAN miniport driver can alter the data in the packet in any way to send that packet on the WAN medium.
It is also an error for the WAN miniport driver to call the NdisMSendResourcesAvailable function.
Packets that are passed to the WAN miniport driver's send function will contain simple HDLC PPP framing if PPP framing is set. For Serial Line Internet Protocol (SLIP) or Remote Access Service (RAS) framing, packets contain only the data portion with no framing.
A WAN NIC driver must not attempt to provide software loopback or promiscuous-mode loopback. Both of these loopback types are fully supported in the NDISWAN driver.
The following list shows information about the NDIS WAN packet:
The MacReservedx members as well as the WanPacketQueue member of the NDIS_WAN_PACKET structurecan be used by the standard WAN miniport driver.
The available header padding is simply CurrentBuffer-StartBuffer. The available end padding is EndBuffer-(CurrentBuffer+CurrentLength). The header and end padding is guaranteed to be at least the amount requested, but can be more.