将时间戳附加到数据包

在微型端口驱动程序报告哪些时间戳功能存在且当前已启用后,驱动程序可以使用 NET_BUFFER_LIST (NBL) 结构将相关时间戳附加到数据包。

有关向操作系统报告 NIC 的硬件时间戳功能和微型端口驱动程序的软件时间戳功能的详细信息,请参阅 报告时间戳功能和当前配置

硬件时间戳

NDIS_TIMESTAMP_CAPABILITY_FLAGSPtpV2OverUdpIPv4EventMsgReceiveHw结构中的 、PtpV2OverUdpIPv4AllMsgReceiveHwPtpV2OverUdpIPv4EventMsgTransmitHwPtpV2OverUdpIPv4AllMsgTransmitHwPtpV2OverUdpIPv6EventMsgTransmitHwPtpV2OverUdpIPv6EventMsgReceiveHwPtpV2OverUdpIPv6AllMsgReceiveHwPtpV2OverUdpIPv6AllMsgTransmitHwAllReceiveHwAllTransmitHwTaggedTransmitHw 标志指示微型端口驱动程序支持的硬件时间戳。

NIC 硬件在接收或传输数据包时生成的时间戳由 64 位整数值表示。 这应该是捕获时间戳时 NIC 硬件时钟的原始值。 时间戳存储在 NBL 结构的 NetBufferListInfo 数组中。

微型端口驱动程序可以使用 NET_BUFFER_LIST_TIMESTAMP 结构在 NBL 的 NetBufferListInfo 字段中设置时间戳。 驱动程序使用硬件生成的 时间戳 填充 NET_BUFFER_LIST_TIMESTAMP 结构的 Timestamp 字段,并调用 NdisSetNblTimestampInfo 实用工具函数,传入 结构。

微型端口驱动程序可以使用 NdisGetNblTimestampInfoNdisCopyNblTimestampInfo 来检索和复制时间戳。

如果启用了特定硬件时间戳设置,但未生成与该功能对应的时间戳,则微型端口应将其附加到 NBL 的时间戳设置为

注意

识别 PTP 版本 2 数据包以生成硬件时间戳时,实现不应将时间戳生成限制为使用多播地址 (PTP 规范指定的 IPv4 和 IPv6) 的数据包。 实现应尝试以其他方式识别 PTP 数据包,例如使用 UDP 标头或 PTP 有效负载。 因此,在 PTP 实现可能不使用 PTP 规范中指定的多播地址(例如使用单播地址)的情况下,仍会生成时间戳。

接收方时间戳

硬件应获取尽可能接近硬件从介质接收帧的时间戳。 此准则由 IEEE 1588 标准指定。

收到数据包时,微型端口驱动程序必须:

  1. 更正时间戳,以查找硬件捕获时间戳和硬件实际收到帧之间的任何延迟。

  2. 将硬件中生成的时间戳附加到 NBL。 时间戳对应于 NBL 中包含的帧 (NET_BUFFER 结构) 。

  3. 调用 NdisMIndicateReceiveNetBufferLists 以向 NDIS 指示 NBL。

请注意,在接收方向,以太网硬件的微型端口驱动程序只需要指示每个 NBL 一个 NET_BUFFER

传输端时间戳

硬件应获取尽可能接近硬件将帧传输到介质的点的时间戳。 此准则由 IEEE 1588 标准指定。

传输数据包时,微型端口驱动程序必须:

  1. 更正时间戳,以查找硬件捕获时间戳和硬件实际传输帧之间的任何延迟。

  2. 将硬件中生成的时间戳附加到 NBL。 如果 NBL 包含多个 NET_BUFFER,则对应于 NBL 中第一 个NET_BUFFER 的硬件时间戳应附加到 NBL。

  3. 调用 NdisMSendNetBufferListsComplete 将完成 NBL 发送到 NDIS。

如果在 NBL 的 NBL 的 NblFlags 字段中设置了标志(该标志用于传输)中,则NDIS_NBL_FLAGS_CAPTURE_TIMESTAMP_ON_TRANSMIT报告TaggedTransmitHw功能标志受支持且当前已启用的微型端口和 NIC 硬件应检查。 如果设置了此标志,则表示该 NBL 需要传输时间时间戳,并且应为 NBL 生成传输时间硬件时间戳。

软件时间戳

AllReceiveSwNDIS_TIMESTAMP_CAPABILITY_FLAGS 结构中的 、 AllTransmitSwTaggedTransmitSw 标志指示微型端口是否支持生成软件时间戳。

软件时间戳也表示为 64 位整数值,并存储在NET_BUFFERNetBufferListInfo 数组中的同一槽中, (NBL) 结构与硬件时间戳相同。

如果存在并启用了软件时间戳功能,则微型端口驱动程序使用性能计数器值 (QPC) 设置 NBL 中的时间戳。 微型端口驱动程序必须:

  1. 调用 KeQueryPerformanceCounter 以获取 QPC。

  2. 使用 QPC 填充 NET_BUFFER_LIST_TIMESTAMP 结构的 Timestamp 字段。

  3. 通过调用 NdisSetNblTimestampInfo 并传入 NET_BUFFER_LIST_TIMESTAMP,在 NBL 中设置时间戳。

接收时,微型端口驱动程序应尽早捕获 QPC,但不得早于数据包到达时捕获。

传输时,微型端口驱动程序应在将数据包提供给硬件进行传输之前尽可能晚地捕获 QPC。

标志 TaggedTransmitSw 类似于 标志, TaggedTransmitHw 但对应于软件时间戳。 如果支持并启用了该功能,则微型端口应在 NBL 的 NblFlags 字段中检查NDIS_NBL_FLAGS_CAPTURE_TIMESTAMP_ON_TRANSMIT标志。 如果设置了此标志,微型端口应生成 NBL 的传输时间软件时间戳。