linux/drivers/net/dsa/sja1105/sja1105_ptp.h
<<
>>
Prefs
   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
  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
  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 */
  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
  51/* This is not a preprocessor macro because the "ns" argument may or may not be
  52 * s64 at caller side. This ensures it is properly type-cast before div_s64.
  53 */
  54static inline s64 ns_to_sja1105_delta(s64 ns)
  55{
  56        return div_s64(ns, 200);
  57}
  58
  59static inline s64 sja1105_delta_to_ns(s64 delta)
  60{
  61        return delta * 200;
  62}
  63
  64struct sja1105_ptp_cmd {
  65        u64 startptpcp;         /* start toggling PTP_CLK pin */
  66        u64 stopptpcp;          /* stop toggling PTP_CLK pin */
  67        u64 ptpstrtsch;         /* start schedule */
  68        u64 ptpstopsch;         /* stop schedule */
  69        u64 resptp;             /* reset */
  70        u64 corrclk4ts;         /* use the corrected clock for timestamps */
  71        u64 ptpclkadd;          /* enum sja1105_ptp_clk_mode */
  72};
  73
  74struct sja1105_ptp_data {
  75        struct delayed_work extts_work;
  76        struct sk_buff_head skb_rxtstamp_queue;
  77        struct ptp_clock_info caps;
  78        struct ptp_clock *clock;
  79        struct sja1105_ptp_cmd cmd;
  80        /* Serializes all operations on the PTP hardware clock */
  81        struct mutex lock;
  82        u64 ptpsyncts;
  83};
  84
  85int sja1105_ptp_clock_register(struct dsa_switch *ds);
  86
  87void sja1105_ptp_clock_unregister(struct dsa_switch *ds);
  88
  89void sja1105et_ptp_cmd_packing(u8 *buf, struct sja1105_ptp_cmd *cmd,
  90                               enum packing_op op);
  91
  92void sja1105pqrs_ptp_cmd_packing(u8 *buf, struct sja1105_ptp_cmd *cmd,
  93                                 enum packing_op op);
  94
  95int sja1105_get_ts_info(struct dsa_switch *ds, int port,
  96                        struct ethtool_ts_info *ts);
  97
  98void sja1105_ptp_txtstamp_skb(struct dsa_switch *ds, int slot,
  99                              struct sk_buff *clone);
 100
 101bool sja1105_port_rxtstamp(struct dsa_switch *ds, int port,
 102                           struct sk_buff *skb, unsigned int type);
 103
 104bool sja1105_port_txtstamp(struct dsa_switch *ds, int port,
 105                           struct sk_buff *skb, unsigned int type);
 106
 107int sja1105_hwtstamp_get(struct dsa_switch *ds, int port, struct ifreq *ifr);
 108
 109int sja1105_hwtstamp_set(struct dsa_switch *ds, int port, struct ifreq *ifr);
 110
 111int __sja1105_ptp_gettimex(struct dsa_switch *ds, u64 *ns,
 112                           struct ptp_system_timestamp *sts);
 113
 114int __sja1105_ptp_settime(struct dsa_switch *ds, u64 ns,
 115                          struct ptp_system_timestamp *ptp_sts);
 116
 117int __sja1105_ptp_adjtime(struct dsa_switch *ds, s64 delta);
 118
 119int sja1105_ptp_commit(struct dsa_switch *ds, struct sja1105_ptp_cmd *cmd,
 120                       sja1105_spi_rw_mode_t rw);
 121
 122#else
 123
 124struct sja1105_ptp_cmd;
 125
 126/* Structures cannot be empty in C. Bah!
 127 * Keep the mutex as the only element, which is a bit more difficult to
 128 * refactor out of sja1105_main.c anyway.
 129 */
 130struct sja1105_ptp_data {
 131        struct mutex lock;
 132};
 133
 134static inline int sja1105_ptp_clock_register(struct dsa_switch *ds)
 135{
 136        return 0;
 137}
 138
 139static inline void sja1105_ptp_clock_unregister(struct dsa_switch *ds) { }
 140
 141static inline void sja1105_ptp_txtstamp_skb(struct dsa_switch *ds, int slot,
 142                                            struct sk_buff *clone)
 143{
 144}
 145
 146static inline int __sja1105_ptp_gettimex(struct dsa_switch *ds, u64 *ns,
 147                                         struct ptp_system_timestamp *sts)
 148{
 149        return 0;
 150}
 151
 152static inline int __sja1105_ptp_settime(struct dsa_switch *ds, u64 ns,
 153                                        struct ptp_system_timestamp *ptp_sts)
 154{
 155        return 0;
 156}
 157
 158static inline int __sja1105_ptp_adjtime(struct dsa_switch *ds, s64 delta)
 159{
 160        return 0;
 161}
 162
 163static inline int sja1105_ptp_commit(struct dsa_switch *ds,
 164                                     struct sja1105_ptp_cmd *cmd,
 165                                     sja1105_spi_rw_mode_t rw)
 166{
 167        return 0;
 168}
 169
 170#define sja1105et_ptp_cmd_packing NULL
 171
 172#define sja1105pqrs_ptp_cmd_packing NULL
 173
 174#define sja1105_get_ts_info NULL
 175
 176#define sja1105_port_rxtstamp NULL
 177
 178#define sja1105_port_txtstamp NULL
 179
 180#define sja1105_hwtstamp_get NULL
 181
 182#define sja1105_hwtstamp_set NULL
 183
 184#endif /* IS_ENABLED(CONFIG_NET_DSA_SJA1105_PTP) */
 185
 186#endif /* _SJA1105_PTP_H */
 187