WDI IHV 驱动程序接口

WDI IHV 微型端口类似于任何其他 NDIS 微型端口驱动程序,它将遵循任何 NDIS 微型端口的开发实践和文档。 本机 WLAN 微型端口驱动程序对 NDIS 处理程序的责任在 MS 组件和 WDI IHV 驱动程序之间拆分。 Microsoft WLAN 组件负责适用于所有Wi-Fi微型端口的 NDIS 要求,以便每个 IHV 不必重做所有工作。 下面介绍了应用于 WDI IHV 微型端口时本机 WLAN IHV 微型端口的 NDIS 处理程序的映射和行为更改。

驱动程序安装

在系统上加载并安装 WDI IHV 微型端口驱动程序的方式没有更改。 INF 和安装过程类似于 IHV 本机 WLAN 微型端口驱动程序。 与现有的 NDIS 驱动程序一样,当需要加载 IHV 驱动程序才能使用 IHV 的 WLAN 适配器时,操作系统会调用 IHV 微型端口驱动程序的 DriverEntry 例程。

DriverEntry

操作系统直接调用 WDI IHV 微型端口驱动程序的 DriverEntry 例程。 IHV 微型端口遵循常规 NDIS 微型端口的 DriverEntry 例程的大部分准则。 一个例外是,IHV 微型端口调用 NdisMRegisterWdiMiniportDriver,而不是调用 NdisMRegisterMiniportDriver 来告知操作系统启用 Microsoft WLAN 组件。

以下是 NdisMRegisterWdiMiniportDriver 的关键参数。

  • NDIS_MINIPORT_DRIVER_CHARACTERISTICS:这是本机Wi-Fi微型端口用于向 NDIS 注册的原始 NDIS 结构。 对于 WDI 模型,大多数处理程序参数都是可选的。 唯一必需的处理程序是 MINIPORT_OID_REQUEST_HANDLERMINIPORT_DRIVER_UNLOADMINIPORT_OID_REQUEST_HANDLER 用于将 WDI 消息传递给 IHV 驱动程序。 如果指定了任何其他处理程序,Microsoft WLAN 组件通常会在为处理程序执行自己的处理后调用处理程序。
  • NDIS_MINIPORT_DRIVER_WDI_CHARACTERISTICS:这是 WDI 微型端口驱动程序必须实现的新处理程序集。 IHV 驱动程序使用它为控制路径注册其他处理程序,以及数据路径的完整处理程序集。

当 IHV 微型端口调用 NdisMRegisterWdiMiniportDriver 时,Microsoft WLAN 组件将更新 NDIS_MINIPORT_DRIVER_CHARACTERISTICS 的处理程序,并调用 NDIS 的 NdisMRegisterMiniportDriver。 完成更新后,Microsoft WLAN 组件可以截获处理程序,以便它可以为 WDI IHV 微型端口驱动程序提供帮助/简化。

下面是 WDI IHV 微型端口驱动程序的典型 DriverEntry 过程流

wdi driverentry flow.

有关 DriverEntry 的详细信息,请参阅 NDIS 微型端口驱动程序的 DriverEntry

MiniportSetOptions

如上面的 DriverEntry 图中所示,如果 WDI IHV 微型端口已注册 MiniportSetOptions 处理程序,则操作系统会在调用 NdisMRegisterWdiMiniportDriver 的微型端口驱动程序的上下文中调用该函数。

如果 IHV 微型端口驱动程序使用 NdisSetOptionalHandler 注册任何选项处理程序,则 Microsoft 组件可能无法通过 WDI 层序列化这些处理程序。 因此,IHV 组件负责处理这些处理程序的任何同步要求。

MiniportInitializeEx

WDI 模型将 MiniportInitializeEx 行为拆分为多个 WDI 接口调用。

  1. 调用 MiniportWdiAllocateAdapter

    当操作系统找到 IHV 硬件的实例时,这是对 WDI IHV 微型端口驱动程序的第一次调用。 在此调用中,WDI 微型端口执行创建设备 (MiniportAdapterContext) 的软件表示形式所需的操作。 它还确定有关设备的信息以填充 NDIS_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES 结构。 当 Microsoft 组件将 WDI 命令向下发送以执行特定初始化时,设备的实际初始化和Wi-Fi堆栈将完成。

    使用从 WDI IHV 微型端口驱动程序获取的数据,Microsoft 组件调用 NdisMSetMiniportAttributes,并在 NDIS 上设置 NDIS_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES大多数NDIS_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES字段都由 Microsoft 组件填充默认值。 IHV 驱动程序必须填充 MiniportAdapterContextInterfaceType 字段。

    此调用从 IHV 微型端口驱动程序返回后,会通过其 MiniportOidRequest 处理程序开始接收 WDI 命令。 在此调用期间,Microsoft 组件可能无法执行重置/恢复操作,因此此处执行的任何活动应快速可靠。

  2. 调用 MiniportWdiOpenAdapter

    MiniportWdiAllocateAdapter 后,Microsoft 组件调用 MiniportWdiOpenAdapter 以加载固件并初始化硬件。

  3. 使用 MiniportOidRequest 的多个 WDI 命令。

    MiniportWdiOpenAdapter 之后,Microsoft 组件会将以下任务/属性/调用发送到 IHV 微型端口。

    1. 调用 MiniportWdiTalTxRxInitialize 以初始化数据路径和交换处理程序。
    2. 调用 OID_WDI_GET_ADAPTER_CAPABILITIES 以获取适配器的功能。
    3. 调用 OID_WDI_SET_ADAPTER_CONFIGURATION 以配置适配器。
    4. 调用 OID_WDI_TASK_SET_RADIO_STATE 设置初始无线电状态(如果它尚未处于预期状态)。
    5. 调用 MiniportWdiTalTxRxStart 以设置数据路径。
    6. 调用 OID_WDI_TASK_CREATE_PORT 以创建初始端口。

    其他命令也可能作为 Microsoft 组件的 MiniportInitializeEx 处理的一部分发送到 IHV 组件。 但是,在调用 MiniportWdiStartOperation 之前,Microsoft 组件不会关闭需要无线通信的任何任务。 除了始终先发送 OID_WDI_TASK_OPEN, 其他命令/调用的顺序可能会更改。

    使用从 WDI IHV 微型端口驱动程序获取的数据,Microsoft 组件调用 NdisMSetMiniportAttributes,并在 NDIS 上设置 NDIS_MINIPORT_ADAPTER_GENERAL_ATTRIBUTESNDIS_MINIPORT_ADAPTER_NATIVE_802_11_ATTRIBUTES

  4. 调用 MiniportWdiStartOperation

    这是 NDIS_MINIPORT_DRIVER_WDI_CHARACTERISTICS 中的可选 WDI 微型端口处理程序,IHV 驱动程序可用于执行任何其他 MiniportInitializeEx 任务。 IHV 微型端口也可以使用它作为提示,提示 Microsoft 组件已完成初始化微型端口,微型端口可以启动任何所需的后台活动。

    下图显示了 MiniportInitializeEx 流。

    wdi miniport initialization flow.

    如果中间操作失败,Microsoft 组件将撤消以前的操作,并失败微型端口。 例如,如果 OID_WDI_TASK_CREATE_PORT 失败,则会清理数据路径, 发送OID_WDI_TASK_CLOSE ,微型端口会失败。

MiniportHaltEx

在本机Wi-Fi微型端口中, MiniportHaltEx 用于指示微型端口停止操作并清理适配器实例。 在 WDI 模型中,Microsoft 组件处理原始 MiniportHaltEx 调用,并将其拆分为多个 WDI 接口调用。

  1. 调用 MiniportWdiStopOperation

    这是 NDIS_MINIPORT_DRIVER_WDI_CHARACTERISTICS 中的可选 WDI 微型端口处理程序,IHV 驱动程序可用于撤消它在 MiniportWdiStartOperation 中执行的操作。

  2. 使用 MiniportOidRequest 的多个 WDI 命令。

    MiniportWdiStopOperation 之后,Microsoft 组件会将任务/属性发送到 IHV 微型端口,以清理 IHV 驱动程序的当前状态。 此清理可能包括以下内容。

    1. 调用OID_WDI_TASK_DISCONNECT/OID_WDI_TASK_STOP_AP以拆除任何现有连接。
    2. 调用 OID_WDI_TASK_DELETE_PORT 以删除所有创建的端口。
    3. 调用 MiniportWdiTalTxRxStop 以停止数据路径。
    4. 调用 MiniportWdiTalTxRxDeinitialize 以取消初始化数据路径。
    5. 调用以清理硬件状态。 这是使用 IHV 驱动程序注册的 MiniportWdiCloseAdapter 发送到 IHV 的。
  3. 调用上述所有命令后,Microsoft 组件会调用 MiniportWdiFreeAdapter ,使 IHV 驱动程序删除它可能具有的任何软件状态。

下图显示了 MiniportHaltEx 流。

wdi miniport halt flow.

如果设备被意外删除,或者系统正在关闭,则不会执行 MiniportHaltEx 处理。 有关意外删除,请参阅 MiniportDevicePnPEventNotify 处理程序行为。 有关系统关闭,请参阅 MiniportShutdownEx 处理程序行为。

MiniportDriverUnload

MiniportDriverUnload 是在卸载 WDI IHV 微型端口之前调用的处理程序。 WDI IHV 微型端口驱动程序调用 Microsoft 组件以取消注册自身。 Microsoft 组件调用 NdisMDeregisterMiniportDriver

下图显示了 MiniportDriverUnload 流。

wdi miniport driver unload flow.

MiniportPause

NDIS MiniportPause 要求由 Microsoft 组件处理。 作为 MiniportPause 的一部分,Microsoft 组件停止数据路径,并等待数据路径清理。 WDI IHV 微型端口可以选择注册 Microsoft 组件在完成数据路径清理后调用的 MiniportWdiPostAdapterPause 回调。

下图显示了 MiniportPause 流。

wdi miniport pause flow.

MiniportRestart

NDIS MiniportRestart 要求由 Microsoft 组件处理。 作为 MiniportRestart 的一部分,Microsoft 组件撤消作为 MiniportPause 的一部分执行的数据路径暂停工作。 WDI IHV 微型端口可以选择注册 Microsoft 组件在重启数据路径后调用的 MiniportWdiPostAdapterRestart 回调。

下图显示了 MiniportRestart 流。

wdi miniport restart flow.

MiniportResetEx

MiniportResetEx 不由 Microsoft 组件处理。 WDI IHV 微型端口可以选择注册由 Microsoft 组件调用的 MiniportResetEx 回调。

MiniportDevicePnPEventNotify

MiniportDevicePnPEventNotify 用于通知 NDIS 驱动程序 PNP 事件,例如设备的意外删除。 当 NDIS 发送此通知时,它将首先转发到 WDI IHV 微型端口进行处理。 IHV 组件完成处理后,Microsoft 组件会为此事件执行适当的处理。 转发到 IHV 组件的调用不会与其他任务和回调一起序列化。

下图显示了 MiniportDevicePnPEventNotify 的流。

wdi miniport drive pnp notification flow.

MiniportShutdownEx

MiniportShutdownEx 用于通知 NDIS 驱动程序系统关闭事件。 当 NDIS 发送此通知时,它首先由 Microsoft 组件处理。 Microsoft 组件完成处理后,它将事件传递给 WDI IHV 微型端口进行处理。

下图显示了 MiniportShutdownEx 的流。

wdi miniport shutdown flow.

MiniportOidRequest

MiniportOidRequest 处理程序是 WDI IHV 微型端口必须实现的必需处理程序。 Microsoft 组件使用它将 WDI 命令提交到 IHV 微型端口。 它还用于转发 Microsoft 组件不处理 IHV 微型端口的 OID。

对 WDI IHV 微型端口的 MiniportOidRequest 调用应被视为 WDI 命令的 M1 消息。 通过 NdisMOidRequestComplete 或通过 从 MiniportOidRequest) 返回非 PENDING 完成 OID (应被视为 WDI 任务/命令的 M3 消息。

对于每个 WDI 命令,都有两个可能字段,NDIS_STATUS代码可以返回操作 -- MiniportOidRequest 调用的状态代码 (或 NdisMOidRequestComplete) , WDI_MESSAGE_HEADER 字段中的状态代码 (OID 完成或通过 NdisMIndicateStatusEx) 。 在查看WDI_MESSAGE_HEADERStatus字段之前,Microsoft 组件始终会从 OID 完成查看 NDIS_STATUS 。 对 WDI OID 处理的 IHV 组件的期望如下所示。

  1. WDI OID 使用 NdisRequestMethodNDIS_OID_REQUESTRequestType 提交到 IHV 组件,相应的消息和消息长度在 DATA 中。METHOD_INFORMATION。InformationBufferDATA。METHOD_INFORMATION。InputBufferLength 字段分别。
  2. 如果处理命令时出错,则 IHV 组件在 OID 完成中报告错误,并将 WDI_MESSAGE_HEADER 的状态字段设置为非成功(如果Wi-Fi级别失败)。
  3. 对于任务和属性,请求的端口号位于 WDI_MESSAGE_HEADERPortId 字段中。 NDIS_OID_REQUEST中的 PortNumber 始终设置为 0。
  4. 对于 OID 的完成, MiniportOidRequest 可以返回NDIS_STATUS_PENDING并 (稍后使用 NdisMOidRequestComplete 同步或异步) 完成 OID。
  5. 如果 IHV 组件使用NDIS_STATUS_SUCCESS完成 OID,则必须使用适当的字节数填充 OID 请求的 BytesWritten 字段,包括 WDI_MESSAGE_HEADER的空间。
  6. 如果 IHV 组件在 DATA 中没有足够的空间 。METHOD_INFORMATION。OutputBufferLength 字段以填充响应,它将使用NDIS_STATUS_BUFFER_TOO_SHORT完成 OID 并填充 DATA。METHOD_INFORMATION。BytesNeeded 字段。 Microsoft 组件可能会尝试分配请求大小的缓冲区,并将新请求提交到 IHV。
  7. 如果任务是任务,则任务的 M4 (NdisMIndicateStatusEx) 仅当任务报告为成功时才会指示 -- OID 完成成功且 OID 完成WDI_MESSAGE_HEADER中的状态是成功的。

下图显示了映射到单个 WDI 命令的 NDIS OID 请求示例。 操作系统提交 OID 请求时,Microsoft 组件将其转换为 WDI OID 请求,并将 WDI OID 请求提交到 IHV 微型端口。 当 IHV 微型端口完成 OID 时,Microsoft 组件会适当地完成原始 OID 请求。

wdi miniport oid request sequence for single wdi command.

如果 OriginalOidRequest 映射到多个 WDI OidRequest,并且其中一个 WDI 请求失败,OriginalOidRequest 也会失败。 如果中间操作的子集已完成,Microsoft 组件将尝试撤消支持清理的操作。

下图显示了由 Microsoft 组件处理的 NDIS OID 请求示例。 操作系统提交 OID 请求时,Microsoft 组件将处理并完成 OID。 此 OID 未传递到 WDI IHV 微型端口。

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

Microsoft 组件无法理解的 OID 将直接转发到 IHV 组件进行处理。

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

与本机Wi-Fi微型端口) 相比,WDI IHV 微型端口驱动程序 (MiniportOidRequest 的行为保持不变。 调用已序列化,IHV 微型端口可以通过对 NdisMOidRequestComplete 的调用以同步方式或异步完成它。

MiniportCancelOidRequest

这是 WDI IHV 微型端口使用的可选处理程序,它需要处理未映射到 WDI 消息的 OID。 此处理程序不用于任何 WDI OID。 WDI OID 必须快速完成,无需 IHV 微型端口驱动程序尝试取消挂起的 OID。 使用适当的取消任务 OID 请求来处理 WDI 任务取消。 对于未映射的 OID,预期行为由 NDIS 定义。

NdisMIndicateStatusEx

WDI IHV 微型端口使用 NdisMIndicateStatusEx 向 Microsoft 组件发送指示。 这些指示可能是未经请求的指示,如 TKIP MIC 故障,或请求指示任务完成 (M4) 。

下图显示了具有相应 NDIS/Native Wi-Fi指示的 WDI 指示示例。 当 IHV 微型端口将指示提交到 Microsoft 组件时,Microsoft 组件会将其转换为现有指示并将其转发到操作系统。

wdi miniport status indication flow.

下图显示了 WDI 指示的示例,该指示没有相应的 NDIS/Native Wi-Fi指示。 这是由 Microsoft 组件处理的。

wdi status indication without direct mapping to ndis.

下图显示了 Microsoft 组件无法识别的指示。 指示按原样转发到操作系统。

wdi status indication not recognized by microsoft component.

与本机Wi-Fi微型端口) 相比,WDI IHV 微型端口驱动程序 (NdisMIndicateStatusEx 的行为保持不变。

MiniportDirectOidRequest

如果 WDI IHV 微型端口驱动程序需要处理未映射到 WDI 消息的 Direct OID,则这是由 WDI IHV 微型端口驱动程序注册的可选处理程序。 Wi-Fi Direct 的所有现有 Direct OID 都映射到 WDI 消息,因此不需要此处理程序来支持该功能。 不支持的 Direct OID 不由 Microsoft 组件序列化。

MiniportCancelDirectOidRequest

这是 WDI IHV 微型端口使用的可选处理程序,它需要处理未映射到 WDI 消息的 Direct OID。 对于未映射的 OID,预期行为由 NDIS 定义。

MiniportSendNetBufferLists

此处理程序不在 WDI IHV 微型端口驱动程序中使用,不应提供。 Microsoft 组件使用通过 NDIS_MINIPORT_DRIVER_WDI_CHARACTERISTICS 注册的数据路径处理程序将数据包提交到 IHV 微型端口。

MiniportCancelSend

此处理程序不在 WDI IHV 微型端口驱动程序中使用,不应提供。

MiniportReturnNetBufferLists

此处理程序不在 WDI IHV 微型端口驱动程序中使用,不应提供。 Microsoft 组件使用通过 NDIS_MINIPORT_DRIVER_WDI_CHARACTERISTICS 注册的数据路径处理程序将收到的数据包返回到 IHV 微型端口。

WDI 处理程序:MiniportWdiOpenAdapter

Microsoft 组件使用 MiniportWdiOpenAdapter 处理程序在 IHV 驱动程序上启动 Open Task 操作。 此调用必须快速完成,如果已成功启动打开操作,IHV 必须在此调用上返回NDIS_STATUS_SUCCESS,并调用传递到 MiniportWdiAllocateAdapterNDIS_WDI_INIT_PARAMETERS 参数的OpenAdapterComplete 处理程序。

WDI 处理程序:MiniportWdiCloseAdapter

Microsoft 组件使用 MiniportWdiCloseAdapter 处理程序在 IHV 驱动程序上启动 Close Task 操作。 此调用必须快速完成,如果已成功启动打开操作,IHV 必须在此调用上返回NDIS_STATUS_SUCCESS,并调用传递到 MiniportWdiAllocateAdapterAdapterNDIS_WDI_INIT_PARAMETERS 参数的CloseAdapterComplete 处理程序。