xref: /linux/drivers/net/ethernet/intel/idpf/idpf_ptp.h (revision 1b98f357dadd6ea613a435fbaef1a5dd7b35fd21)
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 /* Copyright (C) 2024 Intel Corporation */
3 
4 #ifndef _IDPF_PTP_H
5 #define _IDPF_PTP_H
6 
7 #include <linux/ptp_clock_kernel.h>
8 
9 /**
10  * struct idpf_ptp_cmd - PTP command masks
11  * @exec_cmd_mask: mask to trigger command execution
12  * @shtime_enable_mask: mask to enable shadow time
13  */
14 struct idpf_ptp_cmd {
15 	u32 exec_cmd_mask;
16 	u32 shtime_enable_mask;
17 };
18 
19 /* struct idpf_ptp_dev_clk_regs - PTP device registers
20  * @dev_clk_ns_l: low part of the device clock register
21  * @dev_clk_ns_h: high part of the device clock register
22  * @phy_clk_ns_l: low part of the PHY clock register
23  * @phy_clk_ns_h: high part of the PHY clock register
24  * @incval_l: low part of the increment value register
25  * @incval_h: high part of the increment value register
26  * @shadj_l: low part of the shadow adjust register
27  * @shadj_h: high part of the shadow adjust register
28  * @phy_incval_l: low part of the PHY increment value register
29  * @phy_incval_h: high part of the PHY increment value register
30  * @phy_shadj_l: low part of the PHY shadow adjust register
31  * @phy_shadj_h: high part of the PHY shadow adjust register
32  * @cmd: PTP command register
33  * @phy_cmd: PHY command register
34  * @cmd_sync: PTP command synchronization register
35  */
36 struct idpf_ptp_dev_clk_regs {
37 	/* Main clock */
38 	void __iomem *dev_clk_ns_l;
39 	void __iomem *dev_clk_ns_h;
40 
41 	/* PHY timer */
42 	void __iomem *phy_clk_ns_l;
43 	void __iomem *phy_clk_ns_h;
44 
45 	/* Main timer adjustments */
46 	void __iomem *incval_l;
47 	void __iomem *incval_h;
48 	void __iomem *shadj_l;
49 	void __iomem *shadj_h;
50 
51 	/* PHY timer adjustments */
52 	void __iomem *phy_incval_l;
53 	void __iomem *phy_incval_h;
54 	void __iomem *phy_shadj_l;
55 	void __iomem *phy_shadj_h;
56 
57 	/* Command */
58 	void __iomem *cmd;
59 	void __iomem *phy_cmd;
60 	void __iomem *cmd_sync;
61 };
62 
63 /**
64  * enum idpf_ptp_access - the type of access to PTP operations
65  * @IDPF_PTP_NONE: no access
66  * @IDPF_PTP_DIRECT: direct access through BAR registers
67  * @IDPF_PTP_MAILBOX: access through mailbox messages
68  */
69 enum idpf_ptp_access {
70 	IDPF_PTP_NONE = 0,
71 	IDPF_PTP_DIRECT,
72 	IDPF_PTP_MAILBOX,
73 };
74 
75 /**
76  * struct idpf_ptp_secondary_mbx - PTP secondary mailbox
77  * @peer_mbx_q_id: PTP mailbox queue ID
78  * @peer_id: Peer ID for PTP Device Control daemon
79  * @valid: indicates whether secondary mailblox is supported by the Control
80  *	   Plane
81  */
82 struct idpf_ptp_secondary_mbx {
83 	u16 peer_mbx_q_id;
84 	u16 peer_id;
85 	bool valid:1;
86 };
87 
88 /**
89  * enum idpf_ptp_tx_tstamp_state - Tx timestamp states
90  * @IDPF_PTP_FREE: Tx timestamp index free to use
91  * @IDPF_PTP_REQUEST: Tx timestamp index set to the Tx descriptor
92  * @IDPF_PTP_READ_VALUE: Tx timestamp value ready to be read
93  */
94 enum idpf_ptp_tx_tstamp_state {
95 	IDPF_PTP_FREE,
96 	IDPF_PTP_REQUEST,
97 	IDPF_PTP_READ_VALUE,
98 };
99 
100 /**
101  * struct idpf_ptp_tx_tstamp_status - Parameters to track Tx timestamp
102  * @skb: the pointer to the SKB that received the completion tag
103  * @state: the state of the Tx timestamp
104  */
105 struct idpf_ptp_tx_tstamp_status {
106 	struct sk_buff *skb;
107 	enum idpf_ptp_tx_tstamp_state state;
108 };
109 
110 /**
111  * struct idpf_ptp_tx_tstamp - Parameters for Tx timestamping
112  * @list_member: the list member structure
113  * @tx_latch_reg_offset_l: Tx tstamp latch low register offset
114  * @tx_latch_reg_offset_h: Tx tstamp latch high register offset
115  * @skb: the pointer to the SKB for this timestamp request
116  * @tstamp: the Tx tstamp value
117  * @idx: the index of the Tx tstamp
118  */
119 struct idpf_ptp_tx_tstamp {
120 	struct list_head list_member;
121 	u32 tx_latch_reg_offset_l;
122 	u32 tx_latch_reg_offset_h;
123 	struct sk_buff *skb;
124 	u64 tstamp;
125 	u32 idx;
126 };
127 
128 /**
129  * struct idpf_ptp_vport_tx_tstamp_caps - Tx timestamp capabilities
130  * @vport_id: the vport id
131  * @num_entries: the number of negotiated Tx timestamp entries
132  * @tstamp_ns_lo_bit: first bit for nanosecond part of the timestamp
133  * @latches_lock: the lock to the lists of free/used timestamp indexes
134  * @status_lock: the lock to the status tracker
135  * @access: indicates an access to Tx timestamp
136  * @latches_free: the list of the free Tx timestamps latches
137  * @latches_in_use: the list of the used Tx timestamps latches
138  * @tx_tstamp_status: Tx tstamp status tracker
139  */
140 struct idpf_ptp_vport_tx_tstamp_caps {
141 	u32 vport_id;
142 	u16 num_entries;
143 	u16 tstamp_ns_lo_bit;
144 	spinlock_t latches_lock;
145 	spinlock_t status_lock;
146 	bool access:1;
147 	struct list_head latches_free;
148 	struct list_head latches_in_use;
149 	struct idpf_ptp_tx_tstamp_status tx_tstamp_status[];
150 };
151 
152 /**
153  * struct idpf_ptp - PTP parameters
154  * @info: structure defining PTP hardware capabilities
155  * @clock: pointer to registered PTP clock device
156  * @adapter: back pointer to the adapter
157  * @base_incval: base increment value of the PTP clock
158  * @max_adj: maximum adjustment of the PTP clock
159  * @cmd: HW specific command masks
160  * @cached_phc_time: a cached copy of the PHC time for timestamp extension
161  * @cached_phc_jiffies: jiffies when cached_phc_time was last updated
162  * @dev_clk_regs: the set of registers to access the device clock
163  * @caps: PTP capabilities negotiated with the Control Plane
164  * @get_dev_clk_time_access: access type for getting the device clock time
165  * @set_dev_clk_time_access: access type for setting the device clock time
166  * @adj_dev_clk_time_access: access type for the adjusting the device clock
167  * @tx_tstamp_access: access type for the Tx timestamp value read
168  * @rsv: reserved bits
169  * @secondary_mbx: parameters for using dedicated PTP mailbox
170  * @read_dev_clk_lock: spinlock protecting access to the device clock read
171  *		       operation executed by the HW latch
172  */
173 struct idpf_ptp {
174 	struct ptp_clock_info info;
175 	struct ptp_clock *clock;
176 	struct idpf_adapter *adapter;
177 	u64 base_incval;
178 	u64 max_adj;
179 	struct idpf_ptp_cmd cmd;
180 	u64 cached_phc_time;
181 	unsigned long cached_phc_jiffies;
182 	struct idpf_ptp_dev_clk_regs dev_clk_regs;
183 	u32 caps;
184 	enum idpf_ptp_access get_dev_clk_time_access:2;
185 	enum idpf_ptp_access set_dev_clk_time_access:2;
186 	enum idpf_ptp_access adj_dev_clk_time_access:2;
187 	enum idpf_ptp_access tx_tstamp_access:2;
188 	u8 rsv;
189 	struct idpf_ptp_secondary_mbx secondary_mbx;
190 	spinlock_t read_dev_clk_lock;
191 };
192 
193 /**
194  * idpf_ptp_info_to_adapter - get driver adapter struct from ptp_clock_info
195  * @info: pointer to ptp_clock_info struct
196  *
197  * Return: pointer to the corresponding adapter struct
198  */
199 static inline struct idpf_adapter *
200 idpf_ptp_info_to_adapter(const struct ptp_clock_info *info)
201 {
202 	const struct idpf_ptp *ptp = container_of_const(info, struct idpf_ptp,
203 							info);
204 	return ptp->adapter;
205 }
206 
207 /**
208  * struct idpf_ptp_dev_timers - System time and device time values
209  * @sys_time_ns: system time value expressed in nanoseconds
210  * @dev_clk_time_ns: device clock time value expressed in nanoseconds
211  */
212 struct idpf_ptp_dev_timers {
213 	u64 sys_time_ns;
214 	u64 dev_clk_time_ns;
215 };
216 
217 /**
218  * idpf_ptp_is_vport_tx_tstamp_ena - Verify the Tx timestamping enablement for
219  *				     a given vport.
220  * @vport: Virtual port structure
221  *
222  * Tx timestamp capabilities are negotiated with the Control Plane only if the
223  * device clock value can be read, Tx timestamp access type is different than
224  * NONE, and the PTP clock for the adapter is created. When all those conditions
225  * are satisfied, Tx timestamp feature is enabled and tx_tstamp_caps is
226  * allocated and fulfilled.
227  *
228  * Return: true if the Tx timestamping is enabled, false otherwise.
229  */
230 static inline bool idpf_ptp_is_vport_tx_tstamp_ena(struct idpf_vport *vport)
231 {
232 	if (!vport->tx_tstamp_caps)
233 		return false;
234 	else
235 		return true;
236 }
237 
238 /**
239  * idpf_ptp_is_vport_rx_tstamp_ena - Verify the Rx timestamping enablement for
240  *				     a given vport.
241  * @vport: Virtual port structure
242  *
243  * Rx timestamp feature is enabled if the PTP clock for the adapter is created
244  * and it is possible to read the value of the device clock. The second
245  * assumption comes from the need to extend the Rx timestamp value to 64 bit
246  * based on the current device clock time.
247  *
248  * Return: true if the Rx timestamping is enabled, false otherwise.
249  */
250 static inline bool idpf_ptp_is_vport_rx_tstamp_ena(struct idpf_vport *vport)
251 {
252 	if (!vport->adapter->ptp ||
253 	    vport->adapter->ptp->get_dev_clk_time_access == IDPF_PTP_NONE)
254 		return false;
255 	else
256 		return true;
257 }
258 
259 #if IS_ENABLED(CONFIG_PTP_1588_CLOCK)
260 int idpf_ptp_init(struct idpf_adapter *adapter);
261 void idpf_ptp_release(struct idpf_adapter *adapter);
262 int idpf_ptp_get_caps(struct idpf_adapter *adapter);
263 void idpf_ptp_get_features_access(const struct idpf_adapter *adapter);
264 bool idpf_ptp_get_txq_tstamp_capability(struct idpf_tx_queue *txq);
265 int idpf_ptp_get_dev_clk_time(struct idpf_adapter *adapter,
266 			      struct idpf_ptp_dev_timers *dev_clk_time);
267 int idpf_ptp_set_dev_clk_time(struct idpf_adapter *adapter, u64 time);
268 int idpf_ptp_adj_dev_clk_fine(struct idpf_adapter *adapter, u64 incval);
269 int idpf_ptp_adj_dev_clk_time(struct idpf_adapter *adapter, s64 delta);
270 int idpf_ptp_get_vport_tstamps_caps(struct idpf_vport *vport);
271 int idpf_ptp_get_tx_tstamp(struct idpf_vport *vport);
272 int idpf_ptp_set_timestamp_mode(struct idpf_vport *vport,
273 				struct kernel_hwtstamp_config *config);
274 u64 idpf_ptp_extend_ts(struct idpf_vport *vport, u64 in_tstamp);
275 u64 idpf_ptp_tstamp_extend_32b_to_64b(u64 cached_phc_time, u32 in_timestamp);
276 int idpf_ptp_request_ts(struct idpf_tx_queue *tx_q, struct sk_buff *skb,
277 			u32 *idx);
278 void idpf_tstamp_task(struct work_struct *work);
279 #else /* CONFIG_PTP_1588_CLOCK */
280 static inline int idpf_ptp_init(struct idpf_adapter *adapter)
281 {
282 	return 0;
283 }
284 
285 static inline void idpf_ptp_release(struct idpf_adapter *adapter) { }
286 
287 static inline int idpf_ptp_get_caps(struct idpf_adapter *adapter)
288 {
289 	return -EOPNOTSUPP;
290 }
291 
292 static inline void
293 idpf_ptp_get_features_access(const struct idpf_adapter *adapter) { }
294 
295 static inline bool
296 idpf_ptp_get_txq_tstamp_capability(struct idpf_tx_queue *txq)
297 {
298 	return false;
299 }
300 
301 static inline int
302 idpf_ptp_get_dev_clk_time(struct idpf_adapter *adapter,
303 			  struct idpf_ptp_dev_timers *dev_clk_time)
304 {
305 	return -EOPNOTSUPP;
306 }
307 
308 static inline int idpf_ptp_set_dev_clk_time(struct idpf_adapter *adapter,
309 					    u64 time)
310 {
311 	return -EOPNOTSUPP;
312 }
313 
314 static inline int idpf_ptp_adj_dev_clk_fine(struct idpf_adapter *adapter,
315 					    u64 incval)
316 {
317 	return -EOPNOTSUPP;
318 }
319 
320 static inline int idpf_ptp_adj_dev_clk_time(struct idpf_adapter *adapter,
321 					    s64 delta)
322 {
323 	return -EOPNOTSUPP;
324 }
325 
326 static inline int idpf_ptp_get_vport_tstamps_caps(struct idpf_vport *vport)
327 {
328 	return -EOPNOTSUPP;
329 }
330 
331 static inline int idpf_ptp_get_tx_tstamp(struct idpf_vport *vport)
332 {
333 	return -EOPNOTSUPP;
334 }
335 
336 static inline int
337 idpf_ptp_set_timestamp_mode(struct idpf_vport *vport,
338 			    struct kernel_hwtstamp_config *config)
339 {
340 	return -EOPNOTSUPP;
341 }
342 
343 static inline u64 idpf_ptp_extend_ts(struct idpf_vport *vport, u32 in_tstamp)
344 {
345 	return 0;
346 }
347 
348 static inline u64 idpf_ptp_tstamp_extend_32b_to_64b(u64 cached_phc_time,
349 						    u32 in_timestamp)
350 {
351 	return 0;
352 }
353 
354 static inline int idpf_ptp_request_ts(struct idpf_tx_queue *tx_q,
355 				      struct sk_buff *skb, u32 *idx)
356 {
357 	return -EOPNOTSUPP;
358 }
359 
360 static inline void idpf_tstamp_task(struct work_struct *work) { }
361 #endif /* CONFIG_PTP_1588_CLOCK */
362 #endif /* _IDPF_PTP_H */
363