xarxa_driver/meta.rs
1//! Per-packet metadata.
2//!
3//! A [`PacketMeta`] is a small set of attributes that travels together with a packet
4//! all the way through the stack.
5//!
6//! Every field has a corresponding Cargo feature. When none are enabled `PacketMeta` is zero-sized.
7//!
8//! Use cases:
9//!
10//! * **Tagging.** [`PacketMeta::id`] (`packetmeta-id`) is an opaque number you
11//! can use to correlate packets between the driver and sockets.
12//! * **Receive timestamping.** [`PacketMeta::timestamp`] (`packetmeta-timestamp`)
13//! contains the time the packet was received, measured by the driver's own clock.
14//! * **Transmit timestamping.** [`PacketMeta::request_timestamp`] asks the driver to
15//! timestamp a packet as it goes out. The result comes back through
16//! [`Driver::poll_tx_timestamp`](crate::Driver::poll_tx_timestamp), as a
17//! [`TxTimestamp`] tagged with the packet's `id`.
18
19/// A reading of a device's own clock.
20///
21/// This is *different* from the clock the stack is polled with. Do not mix
22/// `Timestamp` values with readings of that clock.
23///
24/// This is typically a higher-precision clock in the MAC.
25#[cfg(feature = "packetmeta-timestamp")]
26#[cfg_attr(feature = "defmt", derive(defmt::Format))]
27#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy, Default)]
28pub struct Timestamp {
29 /// Whole seconds.
30 pub seconds: u32,
31 /// Fraction of a second, in units of 0.25 nanoseconds.
32 ///
33 /// Always less than `4_000_000_000`, i.e. less than one whole second. The quarter
34 /// nanosecond is the resolution of the sub-second counter in common PTP hardware.
35 pub quarter_nanos: u32,
36}
37
38#[cfg(feature = "packetmeta-timestamp")]
39impl Timestamp {
40 /// Construct a timestamp from whole seconds and nanoseconds.
41 pub const fn from_seconds_and_nanos(seconds: u32, nanos: u32) -> Self {
42 Self {
43 seconds,
44 quarter_nanos: nanos << 2,
45 }
46 }
47
48 /// The fraction of a second, in whole nanoseconds, rounded down.
49 pub const fn nanos(&self) -> u32 {
50 self.quarter_nanos >> 2
51 }
52}
53
54/// Metadata associated with a packet.
55///
56/// This struct is `#[non_exhaustive]`. Start from [`Default`] and set what you
57/// care about:
58///
59/// ```
60/// let mut meta = xarxa_driver::PacketMeta::default();
61/// # #[cfg(feature = "packetmeta-id")] {
62/// meta.id = 15;
63/// # }
64/// ```
65#[cfg_attr(feature = "defmt", derive(defmt::Format))]
66#[derive(Debug, PartialEq, Eq, Hash, Clone, Copy, Default)]
67#[non_exhaustive]
68pub struct PacketMeta {
69 /// An opaque identifier for this packet.
70 ///
71 /// On received packets it is set by the driver. On packets to transmit it is set
72 /// by the application and handed to the driver untouched. It is also used
73 /// to correlates a transmit timestamp back to the packet that produced it, see
74 /// [`Driver::poll_tx_timestamp`](crate::Driver::poll_tx_timestamp).
75 ///
76 /// Defaults to `0`.
77 #[cfg(feature = "packetmeta-id")]
78 pub id: u32,
79
80 /// The time at which this packet was received, as measured by the device.
81 ///
82 /// `None` if the device did not timestamp this packet. Devices commonly timestamp
83 /// only a subset of received packets, e.g. only PTP event messages.
84 ///
85 /// Meaningful on received packets only. It is ignored on packets to transmit.
86 #[cfg(feature = "packetmeta-timestamp")]
87 pub timestamp: Option<Timestamp>,
88
89 /// Request that the device timestamp this packet as it is transmitted.
90 ///
91 /// The timestamp is reported back later, out of band, by
92 /// [`Driver::poll_tx_timestamp`](crate::Driver::poll_tx_timestamp),
93 /// tagged with this packet's [`id`](Self::id).
94 ///
95 /// Meaningful on packets to transmit only, ignored on received packets.
96 ///
97 /// Timestamping is opt-in per packet because hardware typically has only a handful
98 /// of transmit timestamp slots: requesting one for every packet will cause most of
99 /// them to be dropped.
100 #[cfg(feature = "packetmeta-timestamp")]
101 pub request_timestamp: bool,
102}
103
104/// The timestamp of a transmitted packet, reported by
105/// [`Driver::poll_tx_timestamp`](crate::Driver::poll_tx_timestamp).
106#[cfg(feature = "packetmeta-timestamp")]
107#[cfg_attr(feature = "defmt", derive(defmt::Format))]
108#[derive(Debug, PartialEq, Eq, Hash, Clone, Copy)]
109pub struct TxTimestamp {
110 /// The [`PacketMeta::id`] of the packet this timestamp belongs to.
111 pub id: u32,
112
113 /// The time at which the packet was transmitted, as measured by the device.
114 pub timestamp: Timestamp,
115}