Attaching timestamps to packets

After the miniport driver reports which timestamping capabilities are present and currently enabled, the driver can attach the relevant timestamps to packets using the NET_BUFFER_LIST (NBL) structure.

For more information on reporting the NIC's hardware timestamping capabilities and the miniport driver's software timestamping capabilities to the operating system, see Reporting timestamping capabilities and current configuration.

Hardware timestamps

The PtpV2OverUdpIPv4EventMsgReceiveHw, PtpV2OverUdpIPv4AllMsgReceiveHw, PtpV2OverUdpIPv4EventMsgTransmitHw, PtpV2OverUdpIPv4AllMsgTransmitHw, PtpV2OverUdpIPv6EventMsgReceiveHw, PtpV2OverUdpIPv6AllMsgReceiveHw, PtpV2OverUdpIPv6EventMsgTransmitHw, PtpV2OverUdpIPv6AllMsgTransmitHw, AllReceiveHw, AllTransmitHw and TaggedTransmitHw flags in the NDIS_TIMESTAMP_CAPABILITY_FLAGS structure indicate which hardware timestamps the miniport driver supports.

The timestamp that the NIC hardware generates on reception or transmission of a packet is represented by a 64-bit integer value. This should be the raw value of the NIC hardware's clock at the point the timestamp is captured. The timestamp is stored in the NBL structure's NetBufferListInfo array.

Miniport drivers can use the NET_BUFFER_LIST_TIMESTAMP structure to set the timestamp in the NBL's NetBufferListInfo field. The driver fills the Timestamp field of the NET_BUFFER_LIST_TIMESTAMP structure with the timestamp generated by the hardware and calls the NdisSetNblTimestampInfo utility function, passing in the structure.

Miniport drivers can use NdisGetNblTimestampInfo and NdisCopyNblTimestampInfo to retrieve and copy timestamps.

If a particular hardware timestamp setting is enabled but a timestamp that corresponds to that capability isn't generated, the miniport should set the timestamp it attaches to the NBL to zero.

Note

When recognizing PTP version 2 packets to generate hardware timestamps, the implementation should not restrict timestamp generation to packets that use the multicast addresses (both IPv4 and IPv6) that are specified by the PTP specification. The implementation should try to recognize PTP packets in other ways, for example using the UDP header or the PTP payload. This is so timestamps are still generated in scenarios where a PTP implementation might not use the multicast addresses specified in the PTP specification, for example where unicast addresses are used.

Receive side timestamping

The hardware should obtain the timestamp as close as possible to the point when the hardware receives the frame from the medium. This guideline is specified by the IEEE 1588 standard.

When a packet is received, the miniport driver must:

  1. Correct the timestamp for any delays that exist between when the hardware captured the timestamp and when the hardware actually received the frame.

  2. Attach the timestamp generated in hardware to the NBL. The timestamp corresponds to the frame (NET_BUFFER structure) contained in the NBL.

  3. Call NdisMIndicateReceiveNetBufferLists to indicate the NBL to NDIS.

Note that in the receive direction, miniport drivers for Ethernet hardware are required to indicate only one NET_BUFFER per NBL.

Transmit side timestamping

The hardware should obtain the timestamp as close as possible to the point when the hardware transmits the frame to the medium. This guideline is specified by the IEEE 1588 standard.

When a packet is transmitted, the miniport driver must:

  1. Correct the timestamp for any delays that exist between when the hardware captured the timestamp and when the hardware actually transmitted the frame.

  2. Attach the timestamp generated in hardware to the NBL. If the NBL contains multiple NET_BUFFERs, the hardware timestamp corresponding to the first NET_BUFFER in the NBL should be attached to the NBL.

  3. Call NdisMSendNetBufferListsComplete to send complete the NBL to NDIS.

Miniports and NIC hardware that report that the TaggedTransmitHw capability flag is supported and currently enabled should check if the NDIS_NBL_FLAGS_CAPTURE_TIMESTAMP_ON_TRANSMIT flag is set in the NblFlags field of an NBL that is given to the miniport for transmission. If this flag is set, this indicates that a transmit time timestamp is needed for that NBL and a transmit time hardware timestamp should be generated for the NBL.

Software timestamps

The AllReceiveSw, AllTransmitSw and TaggedTransmitSw flags in the NDIS_TIMESTAMP_CAPABILITY_FLAGS structure indicate if the miniport supports generating software timestamps.

Software timestamps are also represented as 64-bit integer values and are stored in the same slot in the NetBufferListInfo array of the NET_BUFFER (NBL) structure as the hardware timestamps.

If software timestamping capabilities are present and enabled then the miniport driver sets the timestamp in the NBL using the performance counter value (QPC). The miniport driver must:

  1. Call KeQueryPerformanceCounter to obtain the QPC.

  2. Fill the Timestamp field of the NET_BUFFER_LIST_TIMESTAMP structure with the QPC.

  3. Set the timestamp in the NBL by calling NdisSetNblTimestampInfo and passing in the NET_BUFFER_LIST_TIMESTAMP.

On receive the miniport driver should capture the QPC as early as possible but no earlier than when the packet arrived.

On transmit the miniport driver should capture the QPC as late as possible before the packet is given to the hardware for transmission.

The TaggedTransmitSw flag is analogous to the TaggedTransmitHw flag but corresponds to software timestamps. If the capability is supported and enabled then the miniport should check the NDIS_NBL_FLAGS_CAPTURE_TIMESTAMP_ON_TRANSMIT flag in the NblFlags field of the NBL. If this flag is set, the miniport should generate a transmit time software timestamp for the NBL.