OSDN Git Service

net: dsa: sja1105: configure the PTP_CLK pin as EXT_TS or PER_OUT
[tomoyo/tomoyo-test1.git] / drivers / net / dsa / sja1105 / sja1105_ptp.h
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 */