windows网络适配器驱动开发-传输和接收队列(上)
NetAdapterCx 驱动程序中的传输和接收队列允许客户端驱动程序在软件中为硬件功能如硬件传输和接收队列建模。 本文介绍如何实现和管理这些队列以优化 NetAdapterCx 中的数据路径性能。当您的客户端驱动程序调用 NET_ADAPTER_DATAPATH_CALLBACKS_INIT通常是从其 EVT_WDF_DRIVER_DEVICE_ADD 事件回调函数时它提供两个队列创建回调函数EVT_NET_ADAPTER_CREATE_TXQUEUE 和 EVT_NET_ADAPTER_CREATE_RXQUEUE。 客户端分别在这些回调中创建传输和接收队列。在转换为低功率状态之前框架会清空队列并在删除适配器之前将其删除。创建数据包队列创建数据包队列传输队列或接收队列时客户端必须提供指向以下三个回调函数的指针EVT_PACKET_QUEUE_ADVANCEEVT_PACKET_QUEUE_SET_NOTIFICATION_ENABLEDEVT_PACKET_QUEUE_CANCELEVT_PACKET_QUEUE_ADVANCE EvtPacketQueueAdvance; void EvtPacketQueueAdvance( [_In_] NETPACKETQUEUE PacketQueue ) {...} /* 在 EVT_NET_ADAPTER_CREATE_TXRXQUEUE 回调中注册此回调函数。 使用 NET_PACKET_QUEUE_CONFIG_INIT初始化结构时设置 NET_PACKET_QUEUE_CONFIG 结构的相应成员然后调用 NetTxRxQueueCreate。 NetAdapterCx 将此回调函数与数据包队列的 EVT_PACKET_QUEUE_CANCEL 和 EVT_PACKET_QUEUE_SET_NOTIFICATION_ENABLED 回调函数序列化。 */ EVT_PACKET_QUEUE_SET_NOTIFICATION_ENABLED EvtPacketQueueSetNotificationEnabled; void EvtPacketQueueSetNotificationEnabled( [_In_] NETPACKETQUEUE PacketQueue, [_In_] BOOLEAN NotificationEnabled ) {...} /* 在 EVT_NET_ADAPTER_CREATE_TXRXQUEUE 回调中注册此回调函数。 使用 NET_PACKET_QUEUE_CONFIG_INIT初始化结构时设置 NET_PACKET_QUEUE_CONFIG 结构的相应成员然后调用 NetTxRxQueueCreate。 NetAdapterCx 序列化此回调函数以及数据包队列的 EVT_PACKET_QUEUE_CANCEL 和 EVT_PACKET_QUEUE_ADVANCE 回调函数。 */ EVT_PACKET_QUEUE_CANCEL EvtPacketQueueCancel; void EvtPacketQueueCancel( [_In_] NETPACKETQUEUE PacketQueue ) {...} /* 在 EVT_NET_ADAPTER_CREATE_TXRXQUEUE 回调中注册此回调函数。 使用 NET_PACKET_QUEUE_CONFIG_INIT初始化结构时设置 NET_PACKET_QUEUE_CONFIG 结构的相应成员然后调用 NetTxRxQueueCreate。 NetAdapterCx 序列化此回调函数以及数据包队列的 EVT_PACKET_QUEUE_ADVANCE 和 EVT_PACKET_QUEUE_ADVANCE 回调函数。 */此外客户端可以在初始化队列配置结构后提供这些可选的回调函数EVT_PACKET_QUEUE_START:这是一个可选的回调。 在 EVT_NET_ADAPTER_CREATE_TXRXQUEUE 回调中注册此回调函数。 使用 NET_PACKET_QUEUE_CONFIG_INIT初始化结构后设置 NET_PACKET_QUEUE_CONFIG 结构的相应成员然后调用 NetTxRxQueueCreate。在此回调中客户端驱动程序通常会配置其硬件对数据包传输或接收所需的信息。 由于此回调不返回值因此不应失败因此客户端驱动程序应在创建队列期间执行资源分配等作。 因此此回调应该是快速执行的轻型函数。客户端驱动程序在 EvtPacketQueueStart 返回后才会收到对 EVT_PACKET_QUEUE_ADVANCE、EVT_PACKET_QUEUE_CANCEL或 EVT_PACKET_QUEUE_SET_NOTIFICATION_ENABLED 的调用。 此外EvtPacketQueueStart 在与 EvtPacketQueueAdvance、EvtPacketQueueCancel、EvtPacketQueueSetNotificationEnabled相同的执行上下文或线程中调用因此客户端驱动程序无需在单个队列实例的这些回调函数之间进行同步。队列启动时NetAdapterCx 保证为所有队列的环形缓冲区 BeginIndex NextIndex 0。 开始后框架不会读取或写入 数据包环缓冲区的 NextIndex因此客户端驱动程序可以根据需要使用它或选择根本不使用它。 BeginIndex 由框架读取但不会在 EvtPacketQueueStart之外修改。EVT_PACKET_QUEUE_STOP:这是一个可选的回调。 在 EVT_NET_ADAPTER_CREATE_TXrxQueueContextQUEUE 回调中注册此回调函数。 使用 NET_PACKET_QUEUE_CONFIG_INIT初始化结构后设置 NET_PACKET_QUEUE_CONFIG 结构的相应成员然后调用 NetTxrxQueueContextQueueCreate。此回调不返回值因此不应失败因此此回调应该是快速执行的轻型函数。EvtPacketQueueStop 返回后客户端驱动程序将不会收到对 EVT_PACKET_QUEUE_ADVANCE、EVT_PACKET_QUEUE_CANCEL或 EVT_PACKET_QUEUE_SET_NOTIFICATION_ENABLED 的调用。 此外EvtPacketQueueStop 在同一执行上下文或线程中调用如 EvtPacketQueueAdvance、EvtPacketQueueCancelEvtPacketQueueSetNotificationEnabled因此客户端驱动程序无需在单个队列实例的这些回调函数之间进行同步。