WDI IHV driver interfaces

The WDI IHV miniport is like any other NDIS miniport driver and it would follow the development practices and documentation for any NDIS miniport. A Native WLAN Miniport driver’s responsibilities for the NDIS handlers are split between the MS Component and the WDI IHV driver. The Microsoft WLAN component takes care of the NDIS requirements that are applicable for all Wi-Fi miniports so that every IHV does not have to redo all that work. The mapping of and behavior changes for the NDIS handlers for the Native WLAN IHV miniport when applied to a WDI IHV miniport are described below.

Driver installation

There are no changes to the way the WDI IHV miniport driver is loaded and installed on the system. The INF and install process is similar to that of an IHV Native WLAN miniport driver. Like existing NDIS drivers, when the IHV driver needs to be loaded to work with the IHV's WLAN adapter, the operating system calls the IHV miniport driver's DriverEntry routine.

DriverEntry

The operating system directly calls the WDI IHV miniport driver's DriverEntry routine. The IHV miniport follows most of the guidelines of a regular NDIS miniport's DriverEntry routine. The one exception is that instead of calling NdisMRegisterMiniportDriver, the IHV miniport calls NdisMRegisterWdiMiniportDriver to tell the operating system to enable the Microsoft WLAN component.

The following are the key parameters of NdisMRegisterWdiMiniportDriver.

  • NDIS_MINIPORT_DRIVER_CHARACTERISTICS: This is the original NDIS structure that a Native Wi-Fi miniport uses to register with NDIS. For a WDI model, most of the handler parameters are optional. The only required handlers are MINIPORT_OID_REQUEST_HANDLER and MINIPORT_DRIVER_UNLOAD. MINIPORT_OID_REQUEST_HANDLER is used to pass WDI messages to the IHV driver. If any other handler is specified, the Microsoft WLAN component generally calls the handler after it has performed its own processing for the handler.
  • NDIS_MINIPORT_DRIVER_WDI_CHARACTERISTICS: This is the new set of handlers that a WDI miniport driver must implement. It is used by the IHV driver to register additional handlers for the control path, and the full set of handlers for the data path.

When the IHV miniport calls NdisMRegisterWdiMiniportDriver, the Microsoft WLAN component updates the handlers of NDIS_MINIPORT_DRIVER_CHARACTERISTICS and call NDIS's NdisMRegisterMiniportDriver. The updates are done so that the Microsoft WLAN component can intercept the handlers for which it can provide assistance/simplification to the WDI IHV miniport driver.

Below is the typical flow of the DriverEntry process for the WDI IHV miniport driver

wdi driverentry flow.

For more information about DriverEntry, see DriverEntry of NDIS Miniport Drivers.

MiniportSetOptions

As shown in the above DriverEntry diagram, if the WDI IHV miniport has registered the MiniportSetOptions handler, the operating system calls that function in the context of the miniport driver calling NdisMRegisterWdiMiniportDriver.

If the IHV miniport driver registers any option handlers using NdisSetOptionalHandlers, those handlers may not be serialized through the WDI layer by the Microsoft component. Therefore, the IHV component is responsible for handling any synchronization requirements for those handlers.

MiniportInitializeEx

The WDI model splits the MiniportInitializeEx behavior into multiple WDI interface calls.

  1. Call MiniportWdiAllocateAdapter.

    When the operating system finds an instance of the IHV hardware, this is the first call into the WDI IHV miniport driver. In this call, the WDI miniport performs the actions that are required to create a software representation (MiniportAdapterContext) of the device. It also determines information about the device to fill in the NDIS_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES structure. The actual initialization of the device and the Wi-Fi stack is done later when the Microsoft component sends WDI commands down to perform specific initializations.

    Using data obtained from the WDI IHV miniport driver, the Microsoft component calls NdisMSetMiniportAttributes and sets the NDIS_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES on NDIS. Most fields of NDIS_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES are filled with defaults by the Microsoft component. The IHV driver must populate the MiniportAdapterContext and InterfaceType fields.

    Once this call returns from the IHV miniport driver, it starts receiving WDI commands via its MiniportOidRequest handler. During this call, the Microsoft component may not be able to perform reset/recovery operations, so any activity performed here should be quick and reliable.

  2. Call MiniportWdiOpenAdapter.

    After MiniportWdiAllocateAdapter, the Microsoft component calls MiniportWdiOpenAdapter to load the firmware and initialize the hardware.

  3. Multiple WDI commands using MiniportOidRequest.

    After MiniportWdiOpenAdapter, the Microsoft component sends the following tasks/properties/calls to the IHV miniport.

    1. Call MiniportWdiTalTxRxInitialize to initialize the data path and exchange handlers.
    2. Call OID_WDI_GET_ADAPTER_CAPABILITIES to get the adapter’s capabilities.
    3. Call OID_WDI_SET_ADAPTER_CONFIGURATION to configure the adapter.
    4. Call OID_WDI_TASK_SET_RADIO_STATE to set the initial radio state if it is not already in the expected state.
    5. Call MiniportWdiTalTxRxStart to set up the data path.
    6. Call OID_WDI_TASK_CREATE_PORT to create the initial port.

    Other commands may also be sent down to the IHV component as part of the MiniportInitializeEx processing of the Microsoft Component. However, until MiniportWdiStartOperation is called, the Microsoft component does not send any tasks down that need over-the-air communication. Except for OID_WDI_TASK_OPEN always being sent first, the order of the other commands/calls may change.

    Using data obtained from the WDI IHV miniport driver, the Microsoft component calls NdisMSetMiniportAttributes and sets NDIS_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES and NDIS_MINIPORT_ADAPTER_NATIVE_802_11_ATTRIBUTES on NDIS.

  4. Call MiniportWdiStartOperation.

    This is an optional WDI miniport handler inside NDIS_MINIPORT_DRIVER_WDI_CHARACTERISTICS that the IHV driver can use to perform any additional MiniportInitializeEx tasks. It can also be used by the IHV miniport as a hint that the Microsoft component has finished initializing the miniport and the miniport can start any needed background activities.

    The diagram below shows the flow of MiniportInitializeEx.

    wdi miniport initialization flow.

    If an intermediate operation fails, the Microsoft component undoes the previous operations and fails the miniport bring up. For example, if OID_WDI_TASK_CREATE_PORT fails, the data path is cleaned up, OID_WDI_TASK_CLOSE is sent, and the miniport fails.

MiniportHaltEx

In a Native Wi-Fi miniport, MiniportHaltEx is used to tell the miniport to stop operations and clean up the adapter instance. In the WDI model, the Microsoft component handles the original MiniportHaltEx call and splits it into multiple WDI interface calls.

  1. Call MiniportWdiStopOperation.

    This is an optional WDI miniport handler inside NDIS_MINIPORT_DRIVER_WDI_CHARACTERISTICS that the IHV driver can use to undo the operations it performed in MiniportWdiStartOperation.

  2. Multiple WDI Commands using MiniportOidRequest.

    After MiniportWdiStopOperation, the Microsoft component sends tasks/properties to the IHV miniport to clean up the current state of the IHV driver. This cleanup may include the following.

    1. Call OID_WDI_TASK_DISCONNECT/OID_WDI_TASK_STOP_AP to tear down any existing connections.
    2. Call OID_WDI_TASK_DELETE_PORT to delete all created ports.
    3. Call MiniportWdiTalTxRxStop to stop the data path.
    4. Call MiniportWdiTalTxRxDeinitialize to deinitialize the data path.
    5. Call to clean up the hardware state. This is sent to the IHV using the MiniportWdiCloseAdapter that has been registered by the IHV driver.
  3. Once all of the above commands are called, the Microsoft component calls MiniportWdiFreeAdapter to have the IHV driver delete any software state it may have.

The diagram below shows the flow of MiniportHaltEx.

wdi miniport halt flow.

The MiniportHaltEx processing is not performed if the device is surprise removed or if the system is being powered off. For surprise removal, refer to the MiniportDevicePnPEventNotify handler behavior. For system shutdown, refer to the MiniportShutdownEx handler behavior.

MiniportDriverUnload

MiniportDriverUnload is the handler that is called before the WDI IHV miniport is unloaded. The WDI IHV miniport driver calls the Microsoft component to deregister itself. The Microsoft component calls NdisMDeregisterMiniportDriver.

The diagram below shows the flow of MiniportDriverUnload.

wdi miniport driver unload flow.

MiniportPause

The NDIS MiniportPause requirements are handled by the Microsoft component. As part of MiniportPause, the Microsoft component stops the data path and waits for it to clean up. The WDI IHV miniport can optionally register for a MiniportWdiPostAdapterPause callback that is called by the Microsoft component after it finishes the data path cleanup.

The diagram below shows the flow of MiniportPause.

wdi miniport pause flow.

MiniportRestart

The NDIS MiniportRestart requirements are handled by the Microsoft component. As part of MiniportRestart, the Microsoft component undoes the data path pause work that it performed as part of MiniportPause. The WDI IHV miniport can optionally register for a MiniportWdiPostAdapterRestart callback that is called by the Microsoft component after it finishes restarting the data path.

The diagram below shows the flow of MiniportRestart.

wdi miniport restart flow.

MiniportResetEx

MiniportResetEx is not handled by the Microsoft component. The WDI IHV miniport can optionally register for a MiniportResetEx callback that is called by the Microsoft component.

MiniportDevicePnPEventNotify

MiniportDevicePnPEventNotify is used to notify an NDIS driver of PNP events such as a device's surprise removal. When NDIS sends this notification, it is first forwarded to the WDI IHV miniport for processing. After the IHV component has finished processing it, the Microsoft component performs the appropriate processing for this event. The call that is forwarded into the IHV component is not serialized with other tasks and callbacks.

The diagram below shows the flow of MiniportDevicePnPEventNotify.

wdi miniport drive pnp notification flow.

MiniportShutdownEx

MiniportShutdownEx is used to notify an NDIS driver about system shutdown events. When NDIS sends this notification, it is first handled by the Microsoft component. After the Microsoft component finishes processing it, it passes the event to the WDI IHV miniport for processing.

The diagram below shows the flow of MiniportShutdownEx.

wdi miniport shutdown flow.

MiniportOidRequest

The MiniportOidRequest handler is a required handler that the WDI IHV miniport must implement. It is used by the Microsoft component to submit WDI commands to the IHV miniport. It is also used to forward OIDs that the Microsoft component does not handle to the IHV miniport.

The MiniportOidRequest call into the WDI IHV miniport should be considered as the M1 message for a WDI command. The completion of the OID (either via NdisMOidRequestComplete or via a return non-PENDING from MiniportOidRequest) should be considered as the M3 message for a WDI task/command.

For every WDI command, there are two potential fields where an NDIS_STATUS code can be returned for the operation -- the status code from the MiniportOidRequest call (or NdisMOidRequestComplete), and the status code in the WDI_MESSAGE_HEADER field (either on the OID completion or via NdisMIndicateStatusEx). The Microsoft component always looks at the NDIS_STATUS from the OID completion before it looks at the WDI_MESSAGE_HEADERStatus field. The expectations of the IHV component for WDI OID processing are as follows.

  1. WDI OIDs are submitted to the IHV component using an NDIS_OID_REQUESTRequestType of NdisRequestMethod, and the corresponding message and message length are in the DATA.METHOD_INFORMATION.InformationBuffer and DATA.METHOD_INFORMATION.InputBufferLength fields respectively.
  2. The IHV component reports an error in the OID completion if there is an error while processing the command, and sets the Status field of the WDI_MESSAGE_HEADER to non-success if it has a Wi-Fi level failure.
  3. For tasks and properties, the port number for the request is in the WDI_MESSAGE_HEADERPortId field. The PortNumber in the NDIS_OID_REQUEST is always set to 0.
  4. For completion of the OID, it is acceptable for the MiniportOidRequest to return NDIS_STATUS_PENDING and complete the OID later (synchronously or asynchronously) with NdisMOidRequestComplete.
  5. If the IHV component completes the OID with NDIS_STATUS_SUCCESS, it must populate the BytesWritten field of the OID request with the appropriate number of bytes, including space for the WDI_MESSAGE_HEADER.
  6. If the IHV component does not have enough space in the DATA.METHOD_INFORMATION.OutputBufferLength field to fill the response, it completes the OID with NDIS_STATUS_BUFFER_TOO_SHORT and populates the DATA.METHOD_INFORMATION.BytesNeeded field. The Microsoft component may attempt to allocate a buffer of the requested size and submit a new request to the IHV.
  7. If it is a task, the task's M4 (NdisMIndicateStatusEx) must only be indicated if the task was reported as started successfully -- OID completion is successful and the Status in the WDI_MESSAGE_HEADER in OID completion was success.

The diagram below shows an example of an NDIS OID request that maps to a single WDI command. When the OID request is submitted by the operating system, the Microsoft component converts it to a WDI OID request and submits the WDI OID request to the IHV miniport. When the IHV miniport completes the OID, the Microsoft component appropriately completes the original OID request.

wdi miniport oid request sequence for single wdi command.

If the OriginalOidRequest maps to multiple WDI OidRequests and one of the WDI requests fails, the OriginalOidRequest also fails. If a subset of the intermediate operations already finished, the Microsoft component attempts to undo the operations that support clean up.

The diagram below shows an example of an NDIS OID request that is handled completed by the Microsoft component. When the OID request is submitted by the operating system, the Microsoft component processes and completes the OID. This OID is not passed to the WDI IHV miniport.

wdi miniport oid request sequence for oids handled by microsoft component.

OIDs that are not understood by the Microsoft component are forwarded directly to the IHV component for processing.

wdi miniport oid request sequence for oids not handled by microsoft component.

The behavior of MiniportOidRequest is unchanged for the WDI IHV miniport driver (as compared to a Native Wi-Fi miniport). The calls are serialized and the IHV miniport can either complete it synchronously or asynchronously with a call to NdisMOidRequestComplete.

MiniportCancelOidRequest

This is an optional handler that is used by a WDI IHV miniport that needs to handle OIDs that are not mapped to WDI messages. This handler is not used for any WDI OIDs. WDI OIDs must complete quickly and there is no need for the IHV miniport driver to attempt to cancel a pending OID. Cancellation of WDI tasks is handled using the appropriate cancel task OID request. For unmapped OIDs, the expected behavior is defined by NDIS.

NdisMIndicateStatusEx

NdisMIndicateStatusEx is used by the WDI IHV miniport to send indications to the Microsoft component. The indications may be unsolicited indications such as TKIP MIC failures, or solicited indications for the completion (M4) for a task.

The diagram below shows an example of a WDI indication that has a corresponding NDIS/Native Wi-Fi indication. When the indication is submitted by the IHV miniport to the Microsoft component, the Microsoft component converts it to an existing indication and forwards it to the operating system.

wdi miniport status indication flow.

The diagram below shows an example of a WDI indication that has no corresponding NDIS/Native Wi-Fi indication. This is handled by the Microsoft component.

wdi status indication without direct mapping to ndis.

The diagram below shows an indication that is not recognized by the Microsoft component. The indication is forwarded as-is to the operating system.

wdi status indication not recognized by microsoft component.

The behavior of NdisMIndicateStatusEx is unchanged for the WDI IHV miniport driver (as compared to a Native Wi-Fi miniport).

MiniportDirectOidRequest

This is an optional handler that is registered by a WDI IHV miniport driver if it needs to handle Direct OIDs that are not mapped to WDI messages. All existing Direct OIDs for Wi-Fi Direct are mapped to WDI messages, so this handler is not required to support that functionality. Unsupported Direct OIDs are not serialized by the Microsoft component.

MiniportCancelDirectOidRequest

This is an optional handler that is used by a WDI IHV miniport that needs to handle Direct OIDs that are not mapped to WDI messages. For unmapped OIDs, the expected behavior is defined by NDIS.

MiniportSendNetBufferLists

This handler is not used in a WDI IHV miniport driver and should not be provided. The Microsoft component uses the data path handlers registered through NDIS_MINIPORT_DRIVER_WDI_CHARACTERISTICS to submit send packets to the IHV miniport.

MiniportCancelSend

This handler is not used in a WDI IHV miniport driver and should not be provided.

MiniportReturnNetBufferLists

This handler is not used in a WDI IHV Miniport driver and should not be provided. The Microsoft component uses the data path handlers registered through NDIS_MINIPORT_DRIVER_WDI_CHARACTERISTICS to return received packets to the IHV miniport.

WDI handler: MiniportWdiOpenAdapter

The MiniportWdiOpenAdapter handler is used by the Microsoft component to initiate the Open Task operation on the IHV driver. This call must complete quickly and if the open operation has been successfully started, the IHV must return NDIS_STATUS_SUCCESS on this call and call the OpenAdapterComplete handler that is passed into the NDIS_WDI_INIT_PARAMETERS parameter of MiniportWdiAllocateAdapter.

WDI handler: MiniportWdiCloseAdapter

The MiniportWdiCloseAdapter handler is used by the Microsoft component to initiate the Close Task operation on the IHV driver. This call must complete quickly and if the open operation has been successfully started, the IHV must return NDIS_STATUS_SUCCESS on this call and call the CloseAdapterComplete handler that is passed into the NDIS_WDI_INIT_PARAMETERS parameter of the MiniportWdiAllocateAdapter.