sja1105_ptp.h 5.3 KB

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