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