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