1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
//! DPLL (Digital Phase-Locked Loop) Generic Netlink family.
//!
//! DPLL surfaces clock-synchronization hardware to userspace:
//! SyncE, PTP, GNSS-disciplined oscillators. Telco / RAN, time-sync
//! infrastructure, and SmartNIC users (Intel `ice`, Mellanox `mlx5`,
//! NVIDIA BlueField) consume it daily.
//!
//! Available on Linux **kernel 6.7+** (stabilized Nov 2023). 6.8-6.12
//! added attributes strictly appended; the wire format is otherwise
//! frozen.
//!
//! # Status (Plan 156)
//!
//! This module ships in phases — see
//! [`plans/156-0.16-dpll-genl-family-plan.md`](../../../../../../plans/156-0.16-dpll-genl-family-plan.md):
//!
//! | Phase | Ships | Status |
//! |---|---|---|
//! | 1 | Family marker + module scaffold | ✓ |
//! | 2 | Command + attribute + value enums | ✓ |
//! | 3 | Device-side messages + Connection methods | ✓ |
//! | 4 | Pin-side messages + Connection methods | ✓ |
//! | 5 | Multicast monitor + `DpllEvent` stream | — |
//! | 6 | Scaling helpers + recipe + example | ✓ (example + recipe) |
//!
//! # Why DPLL is the macro dogfood
//!
//! Plan 156 is intentionally the **first in-tree user of
//! `nlink-macros`** (Plan 154). The full family — 12 commands,
//! 14 device attrs, 31 pin attrs, 10 value enums — declares in
//! ~130 lines of macro-derived Rust. The hand-written in-tree
//! families (WireGuard, MACsec, Devlink, …) average ~600 lines
//! each for comparable surface area. DPLL is the existence proof
//! that the macros work end-to-end on a real modern kernel
//! feature.
//!
//! # Construction
//!
//! ```ignore
//! use nlink::netlink::{Connection, genl::dpll::Dpll};
//!
//! let conn = Connection::<Dpll>::new_async().await?;
//! // Family ID resolved against the kernel "dpll" registration;
//! // FamilyNotFound on kernels without CONFIG_DPLL.
//! ```
//!
//! Resolution failure is the common case on stock distro kernels
//! that haven't loaded the DPLL driver. Handle via
//! [`Error::is_not_found`](crate::Error::is_not_found):
//!
//! ```ignore
//! match Connection::<Dpll>::new_async().await {
//! Ok(conn) => { /* use it */ }
//! Err(e) if e.is_not_found() => {
//! tracing::warn!("DPLL not available on this kernel; skipping");
//! }
//! Err(e) => return Err(e),
//! }
//! ```
use crategenl_family;
pub use DpllEvent;
pub use ;
pub use ;
/// Divider applied to `DPLL_A_TEMP` (mdegC → degC). Plan 156 §4.5.
pub const DPLL_TEMP_DIVIDER: i32 = 1000;
/// Divider applied to `DPLL_A_PIN_PHASE_OFFSET` (kernel reports
/// attoseconds × 1000; divide for nanoseconds). Plan 156 §4.5.
pub const DPLL_PHASE_OFFSET_DIVIDER: i64 = 1000;
/// Divider applied to `DPLL_A_PIN_MEASURED_FREQUENCY` (mHz × 1000
/// → Hz). Plan 156 §4.5.
pub const DPLL_PIN_MEASURED_FREQUENCY_DIVIDER: u64 = 1000;
/// DPLL Generic Netlink family marker.
///
/// Constructed via [`Connection::<Dpll>::new_async()`][Connection]
/// — the family ID is resolved against the kernel at connection
/// time. Returns
/// [`Error::FamilyNotFound`](crate::Error::FamilyNotFound) on
/// kernels without DPLL support (no CONFIG_DPLL, or driver not
/// loaded).
///
/// [Connection]: crate::netlink::Connection
;