1 /* SPDX-License-Identifier: GPL-2.0 */
2 /* Copyright (c) 2019, Vladimir Oltean <olteanv@gmail.com>
3  */
4 #ifndef _SJA1105_PTP_H
5 #define _SJA1105_PTP_H
6 
7 #if IS_ENABLED(CONFIG_NET_DSA_SJA1105_PTP)
8 
9 /* Timestamps are in units of 8 ns clock ticks (equivalent to
10  * a fixed 125 MHz clock).
11  */
12 #define SJA1105_TICK_NS			8
13 
14 static inline s64 ns_to_sja1105_ticks(s64 ns)
15 {
16 	return ns / SJA1105_TICK_NS;
17 }
18 
19 static inline s64 sja1105_ticks_to_ns(s64 ticks)
20 {
21 	return ticks * SJA1105_TICK_NS;
22 }
23 
24 /* Calculate the first base_time in the future that satisfies this
25  * relationship:
26  *
27  * future_base_time = base_time + N x cycle_time >= now, or
28  *
29  *      now - base_time
30  * N >= ---------------
31  *         cycle_time
32  *
33  * Because N is an integer, the ceiling value of the above "a / b" ratio
34  * is in fact precisely the floor value of "(a + b - 1) / b", which is
35  * easier to calculate only having integer division tools.
36  */
37 static inline s64 future_base_time(s64 base_time, s64 cycle_time, s64 now)
38 {
39 	s64 a, b, n;
40 
41 	if (base_time >= now)
42 		return base_time;
43 
44 	a = now - base_time;
45 	b = cycle_time;
46 	n = div_s64(a + b - 1, b);
47 
48 	return base_time + n * cycle_time;
49 }
50 
51 struct sja1105_ptp_cmd {
52 	u64 startptpcp;		/* start toggling PTP_CLK pin */
53 	u64 stopptpcp;		/* stop toggling PTP_CLK pin */
54 	u64 ptpstrtsch;		/* start schedule */
55 	u64 ptpstopsch;		/* stop schedule */
56 	u64 resptp;		/* reset */
57 	u64 corrclk4ts;		/* use the corrected clock for timestamps */
58 	u64 ptpclkadd;		/* enum sja1105_ptp_clk_mode */
59 };
60 
61 struct sja1105_ptp_data {
62 	struct delayed_work extts_work;
63 	struct sk_buff_head skb_rxtstamp_queue;
64 	struct ptp_clock_info caps;
65 	struct ptp_clock *clock;
66 	struct sja1105_ptp_cmd cmd;
67 	/* Serializes all operations on the PTP hardware clock */
68 	struct mutex lock;
69 	u64 ptpsyncts;
70 };
71 
72 int sja1105_ptp_clock_register(struct dsa_switch *ds);
73 
74 void sja1105_ptp_clock_unregister(struct dsa_switch *ds);
75 
76 void sja1105et_ptp_cmd_packing(u8 *buf, struct sja1105_ptp_cmd *cmd,
77 			       enum packing_op op);
78 
79 void sja1105pqrs_ptp_cmd_packing(u8 *buf, struct sja1105_ptp_cmd *cmd,
80 				 enum packing_op op);
81 
82 int sja1105_get_ts_info(struct dsa_switch *ds, int port,
83 			struct ethtool_ts_info *ts);
84 
85 void sja1105_ptp_txtstamp_skb(struct dsa_switch *ds, int slot,
86 			      struct sk_buff *clone);
87 
88 bool sja1105_port_rxtstamp(struct dsa_switch *ds, int port,
89 			   struct sk_buff *skb, unsigned int type);
90 
91 bool sja1105_port_txtstamp(struct dsa_switch *ds, int port,
92 			   struct sk_buff *skb, unsigned int type);
93 
94 int sja1105_hwtstamp_get(struct dsa_switch *ds, int port, struct ifreq *ifr);
95 
96 int sja1105_hwtstamp_set(struct dsa_switch *ds, int port, struct ifreq *ifr);
97 
98 int __sja1105_ptp_gettimex(struct dsa_switch *ds, u64 *ns,
99 			   struct ptp_system_timestamp *sts);
100 
101 int __sja1105_ptp_settime(struct dsa_switch *ds, u64 ns,
102 			  struct ptp_system_timestamp *ptp_sts);
103 
104 int __sja1105_ptp_adjtime(struct dsa_switch *ds, s64 delta);
105 
106 int sja1105_ptp_commit(struct dsa_switch *ds, struct sja1105_ptp_cmd *cmd,
107 		       sja1105_spi_rw_mode_t rw);
108 
109 #else
110 
111 struct sja1105_ptp_cmd;
112 
113 /* Structures cannot be empty in C. Bah!
114  * Keep the mutex as the only element, which is a bit more difficult to
115  * refactor out of sja1105_main.c anyway.
116  */
117 struct sja1105_ptp_data {
118 	struct mutex lock;
119 };
120 
121 static inline int sja1105_ptp_clock_register(struct dsa_switch *ds)
122 {
123 	return 0;
124 }
125 
126 static inline void sja1105_ptp_clock_unregister(struct dsa_switch *ds) { }
127 
128 static inline void sja1105_ptp_txtstamp_skb(struct dsa_switch *ds, int slot,
129 					    struct sk_buff *clone)
130 {
131 }
132 
133 static inline int __sja1105_ptp_gettimex(struct dsa_switch *ds, u64 *ns,
134 					 struct ptp_system_timestamp *sts)
135 {
136 	return 0;
137 }
138 
139 static inline int __sja1105_ptp_settime(struct dsa_switch *ds, u64 ns,
140 					struct ptp_system_timestamp *ptp_sts)
141 {
142 	return 0;
143 }
144 
145 static inline int __sja1105_ptp_adjtime(struct dsa_switch *ds, s64 delta)
146 {
147 	return 0;
148 }
149 
150 static inline int sja1105_ptp_commit(struct dsa_switch *ds,
151 				     struct sja1105_ptp_cmd *cmd,
152 				     sja1105_spi_rw_mode_t rw)
153 {
154 	return 0;
155 }
156 
157 #define sja1105et_ptp_cmd_packing NULL
158 
159 #define sja1105pqrs_ptp_cmd_packing NULL
160 
161 #define sja1105_get_ts_info NULL
162 
163 #define sja1105_port_rxtstamp NULL
164 
165 #define sja1105_port_txtstamp NULL
166 
167 #define sja1105_hwtstamp_get NULL
168 
169 #define sja1105_hwtstamp_set NULL
170 
171 #endif /* IS_ENABLED(CONFIG_NET_DSA_SJA1105_PTP) */
172 
173 #endif /* _SJA1105_PTP_H */
174