blob: 43480b24f1f03359ad83152f2112b7df7f6380b5 [file] [log] [blame]
Nishad Kamdarb790b552019-10-14 21:51:20 +05301/* SPDX-License-Identifier: GPL-2.0 */
2/* Copyright (c) 2019, Vladimir Oltean <olteanv@gmail.com>
Vladimir Olteanbb77f362019-06-08 15:04:34 +03003 */
4#ifndef _SJA1105_PTP_H
5#define _SJA1105_PTP_H
6
7#if IS_ENABLED(CONFIG_NET_DSA_SJA1105_PTP)
8
Vladimir Oltean2fb079a2019-10-16 21:41:02 +03009/* 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
14static inline s64 ns_to_sja1105_ticks(s64 ns)
15{
16 return ns / SJA1105_TICK_NS;
17}
18
19static inline s64 sja1105_ticks_to_ns(s64 ticks)
20{
21 return ticks * SJA1105_TICK_NS;
22}
23
Vladimir Oltean4bfa1612020-03-24 00:59:22 +020024/* 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 */
37static 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
Vladimir Oltean66427772019-10-12 02:18:16 +030051struct sja1105_ptp_cmd {
Vladimir Oltean747e5eb2020-03-24 00:59:24 +020052 u64 startptpcp; /* start toggling PTP_CLK pin */
53 u64 stopptpcp; /* stop toggling PTP_CLK pin */
Vladimir Oltean86db36a2019-11-12 02:11:54 +020054 u64 ptpstrtsch; /* start schedule */
55 u64 ptpstopsch; /* stop schedule */
Vladimir Oltean66427772019-10-12 02:18:16 +030056 u64 resptp; /* reset */
Vladimir Oltean2fb079a2019-10-16 21:41:02 +030057 u64 corrclk4ts; /* use the corrected clock for timestamps */
58 u64 ptpclkadd; /* enum sja1105_ptp_clk_mode */
Vladimir Oltean66427772019-10-12 02:18:16 +030059};
60
Vladimir Olteana9d6ed72019-10-12 02:18:15 +030061struct sja1105_ptp_data {
Vladimir Oltean747e5eb2020-03-24 00:59:24 +020062 struct delayed_work extts_work;
Vladimir Oltean1e762bd2019-12-27 15:02:29 +020063 struct sk_buff_head skb_rxtstamp_queue;
Vladimir Olteana9d6ed72019-10-12 02:18:15 +030064 struct ptp_clock_info caps;
65 struct ptp_clock *clock;
Vladimir Oltean66427772019-10-12 02:18:16 +030066 struct sja1105_ptp_cmd cmd;
Vladimir Oltean2fb079a2019-10-16 21:41:02 +030067 /* Serializes all operations on the PTP hardware clock */
Vladimir Olteana9d6ed72019-10-12 02:18:15 +030068 struct mutex lock;
Vladimir Oltean747e5eb2020-03-24 00:59:24 +020069 u64 ptpsyncts;
Vladimir Olteana9d6ed72019-10-12 02:18:15 +030070};
71
Vladimir Oltean61c77122019-10-12 02:18:14 +030072int sja1105_ptp_clock_register(struct dsa_switch *ds);
Vladimir Olteanbb77f362019-06-08 15:04:34 +030073
Vladimir Oltean61c77122019-10-12 02:18:14 +030074void sja1105_ptp_clock_unregister(struct dsa_switch *ds);
Vladimir Olteanbb77f362019-06-08 15:04:34 +030075
Vladimir Oltean41603d72019-11-12 02:11:53 +020076void sja1105et_ptp_cmd_packing(u8 *buf, struct sja1105_ptp_cmd *cmd,
77 enum packing_op op);
Vladimir Olteanbb77f362019-06-08 15:04:34 +030078
Vladimir Oltean41603d72019-11-12 02:11:53 +020079void sja1105pqrs_ptp_cmd_packing(u8 *buf, struct sja1105_ptp_cmd *cmd,
80 enum packing_op op);
Vladimir Olteanbb77f362019-06-08 15:04:34 +030081
82int sja1105_get_ts_info(struct dsa_switch *ds, int port,
83 struct ethtool_ts_info *ts);
84
Vladimir Olteana9d6ed72019-10-12 02:18:15 +030085void sja1105_ptp_txtstamp_skb(struct dsa_switch *ds, int slot,
86 struct sk_buff *clone);
Vladimir Oltean47ed9852019-06-08 15:04:35 +030087
Vladimir Olteana9d6ed72019-10-12 02:18:15 +030088bool sja1105_port_rxtstamp(struct dsa_switch *ds, int port,
89 struct sk_buff *skb, unsigned int type);
90
91bool sja1105_port_txtstamp(struct dsa_switch *ds, int port,
92 struct sk_buff *skb, unsigned int type);
93
94int sja1105_hwtstamp_get(struct dsa_switch *ds, int port, struct ifreq *ifr);
95
96int sja1105_hwtstamp_set(struct dsa_switch *ds, int port, struct ifreq *ifr);
97
Vladimir Oltean6cf99c12019-11-09 13:32:23 +020098int __sja1105_ptp_gettimex(struct dsa_switch *ds, u64 *ns,
99 struct ptp_system_timestamp *sts);
100
101int __sja1105_ptp_settime(struct dsa_switch *ds, u64 ns,
102 struct ptp_system_timestamp *ptp_sts);
103
104int __sja1105_ptp_adjtime(struct dsa_switch *ds, s64 delta);
105
Vladimir Oltean86db36a2019-11-12 02:11:54 +0200106int sja1105_ptp_commit(struct dsa_switch *ds, struct sja1105_ptp_cmd *cmd,
107 sja1105_spi_rw_mode_t rw);
108
Vladimir Olteanbb77f362019-06-08 15:04:34 +0300109#else
110
Vladimir Oltean66427772019-10-12 02:18:16 +0300111struct sja1105_ptp_cmd;
112
Vladimir Olteana9d6ed72019-10-12 02:18:15 +0300113/* 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 */
117struct sja1105_ptp_data {
118 struct mutex lock;
119};
120
Vladimir Oltean61c77122019-10-12 02:18:14 +0300121static inline int sja1105_ptp_clock_register(struct dsa_switch *ds)
Vladimir Olteanbb77f362019-06-08 15:04:34 +0300122{
123 return 0;
124}
125
Vladimir Oltean61c77122019-10-12 02:18:14 +0300126static inline void sja1105_ptp_clock_unregister(struct dsa_switch *ds) { }
Vladimir Olteanbb77f362019-06-08 15:04:34 +0300127
Vladimir Olteana9d6ed72019-10-12 02:18:15 +0300128static inline void sja1105_ptp_txtstamp_skb(struct dsa_switch *ds, int slot,
129 struct sk_buff *clone)
Vladimir Oltean47ed9852019-06-08 15:04:35 +0300130{
Vladimir Oltean47ed9852019-06-08 15:04:35 +0300131}
132
Vladimir Oltean6cf99c12019-11-09 13:32:23 +0200133static inline int __sja1105_ptp_gettimex(struct dsa_switch *ds, u64 *ns,
134 struct ptp_system_timestamp *sts)
135{
136 return 0;
137}
138
139static inline int __sja1105_ptp_settime(struct dsa_switch *ds, u64 ns,
140 struct ptp_system_timestamp *ptp_sts)
141{
142 return 0;
143}
144
145static inline int __sja1105_ptp_adjtime(struct dsa_switch *ds, s64 delta)
Vladimir Olteanbb77f362019-06-08 15:04:34 +0300146{
147 return 0;
148}
149
Vladimir Oltean86db36a2019-11-12 02:11:54 +0200150static 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
Vladimir Oltean41603d72019-11-12 02:11:53 +0200157#define sja1105et_ptp_cmd_packing NULL
Vladimir Olteanbb77f362019-06-08 15:04:34 +0300158
Vladimir Oltean41603d72019-11-12 02:11:53 +0200159#define sja1105pqrs_ptp_cmd_packing NULL
Vladimir Olteanbb77f362019-06-08 15:04:34 +0300160
161#define sja1105_get_ts_info NULL
162
Vladimir Olteana9d6ed72019-10-12 02:18:15 +0300163#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
Vladimir Olteanbb77f362019-06-08 15:04:34 +0300171#endif /* IS_ENABLED(CONFIG_NET_DSA_SJA1105_PTP) */
172
173#endif /* _SJA1105_PTP_H */