brintos

brintos / linux-shallow public Read only

0
0
Text · 5.3 KiB · 8add2bd Raw
208 lines · c
1/* SPDX-License-Identifier: GPL-2.0 */2/* Copyright (c) 2019, Vladimir Oltean <olteanv@gmail.com>3 */4#ifndef _SJA1105_PTP_H5#define _SJA1105_PTP_H6 7#include <linux/timer.h>8 9#if IS_ENABLED(CONFIG_NET_DSA_SJA1105_PTP)10 11/* Timestamps are in units of 8 ns clock ticks (equivalent to12 * a fixed 125 MHz clock).13 */14#define SJA1105_TICK_NS			815 16static inline s64 ns_to_sja1105_ticks(s64 ns)17{18	return ns / SJA1105_TICK_NS;19}20 21static inline s64 sja1105_ticks_to_ns(s64 ticks)22{23	return ticks * SJA1105_TICK_NS;24}25 26/* Calculate the first base_time in the future that satisfies this27 * relationship:28 *29 * future_base_time = base_time + N x cycle_time >= now, or30 *31 *      now - base_time32 * N >= ---------------33 *         cycle_time34 *35 * Because N is an integer, the ceiling value of the above "a / b" ratio36 * is in fact precisely the floor value of "(a + b - 1) / b", which is37 * easier to calculate only having integer division tools.38 */39static inline s64 future_base_time(s64 base_time, s64 cycle_time, s64 now)40{41	s64 a, b, n;42 43	if (base_time >= now)44		return base_time;45 46	a = now - base_time;47	b = cycle_time;48	n = div_s64(a + b - 1, b);49 50	return base_time + n * cycle_time;51}52 53/* This is not a preprocessor macro because the "ns" argument may or may not be54 * s64 at caller side. This ensures it is properly type-cast before div_s64.55 */56static inline s64 ns_to_sja1105_delta(s64 ns)57{58	return div_s64(ns, 200);59}60 61static inline s64 sja1105_delta_to_ns(s64 delta)62{63	return delta * 200;64}65 66struct sja1105_ptp_cmd {67	u64 startptpcp;		/* start toggling PTP_CLK pin */68	u64 stopptpcp;		/* stop toggling PTP_CLK pin */69	u64 ptpstrtsch;		/* start schedule */70	u64 ptpstopsch;		/* stop schedule */71	u64 resptp;		/* reset */72	u64 corrclk4ts;		/* use the corrected clock for timestamps */73	u64 ptpclkadd;		/* enum sja1105_ptp_clk_mode */74};75 76struct sja1105_ptp_data {77	struct timer_list extts_timer;78	/* Used only on SJA1105 to reconstruct partial timestamps */79	struct sk_buff_head skb_rxtstamp_queue;80	/* Used on SJA1110 where meta frames are generated only for81	 * 2-step TX timestamps82	 */83	struct sk_buff_head skb_txtstamp_queue;84	struct ptp_clock_info caps;85	struct ptp_clock *clock;86	struct sja1105_ptp_cmd cmd;87	/* Serializes all operations on the PTP hardware clock */88	struct mutex lock;89	bool extts_enabled;90	u64 ptpsyncts;91};92 93int sja1105_ptp_clock_register(struct dsa_switch *ds);94 95void sja1105_ptp_clock_unregister(struct dsa_switch *ds);96 97void sja1105et_ptp_cmd_packing(u8 *buf, struct sja1105_ptp_cmd *cmd,98			       enum packing_op op);99 100void sja1105pqrs_ptp_cmd_packing(u8 *buf, struct sja1105_ptp_cmd *cmd,101				 enum packing_op op);102 103int sja1105_get_ts_info(struct dsa_switch *ds, int port,104			struct kernel_ethtool_ts_info *ts);105 106void sja1105_ptp_txtstamp_skb(struct dsa_switch *ds, int slot,107			      struct sk_buff *clone);108 109bool sja1105_port_rxtstamp(struct dsa_switch *ds, int port,110			   struct sk_buff *skb, unsigned int type);111 112void sja1105_port_txtstamp(struct dsa_switch *ds, int port,113			   struct sk_buff *skb);114 115int sja1105_hwtstamp_get(struct dsa_switch *ds, int port, struct ifreq *ifr);116 117int sja1105_hwtstamp_set(struct dsa_switch *ds, int port, struct ifreq *ifr);118 119int __sja1105_ptp_gettimex(struct dsa_switch *ds, u64 *ns,120			   struct ptp_system_timestamp *sts);121 122int __sja1105_ptp_settime(struct dsa_switch *ds, u64 ns,123			  struct ptp_system_timestamp *ptp_sts);124 125int __sja1105_ptp_adjtime(struct dsa_switch *ds, s64 delta);126 127int sja1105_ptp_commit(struct dsa_switch *ds, struct sja1105_ptp_cmd *cmd,128		       sja1105_spi_rw_mode_t rw);129 130bool sja1105_rxtstamp(struct dsa_switch *ds, int port, struct sk_buff *skb);131bool sja1110_rxtstamp(struct dsa_switch *ds, int port, struct sk_buff *skb);132void sja1110_txtstamp(struct dsa_switch *ds, int port, struct sk_buff *skb);133 134void sja1110_process_meta_tstamp(struct dsa_switch *ds, int port, u8 ts_id,135				 enum sja1110_meta_tstamp dir, u64 tstamp);136 137#else138 139struct sja1105_ptp_cmd;140 141/* Structures cannot be empty in C. Bah!142 * Keep the mutex as the only element, which is a bit more difficult to143 * refactor out of sja1105_main.c anyway.144 */145struct sja1105_ptp_data {146	struct mutex lock;147};148 149static inline int sja1105_ptp_clock_register(struct dsa_switch *ds)150{151	return 0;152}153 154static inline void sja1105_ptp_clock_unregister(struct dsa_switch *ds) { }155 156static inline void sja1105_ptp_txtstamp_skb(struct dsa_switch *ds, int slot,157					    struct sk_buff *clone)158{159}160 161static inline int __sja1105_ptp_gettimex(struct dsa_switch *ds, u64 *ns,162					 struct ptp_system_timestamp *sts)163{164	return 0;165}166 167static inline int __sja1105_ptp_settime(struct dsa_switch *ds, u64 ns,168					struct ptp_system_timestamp *ptp_sts)169{170	return 0;171}172 173static inline int __sja1105_ptp_adjtime(struct dsa_switch *ds, s64 delta)174{175	return 0;176}177 178static inline int sja1105_ptp_commit(struct dsa_switch *ds,179				     struct sja1105_ptp_cmd *cmd,180				     sja1105_spi_rw_mode_t rw)181{182	return 0;183}184 185#define sja1105et_ptp_cmd_packing NULL186 187#define sja1105pqrs_ptp_cmd_packing NULL188 189#define sja1105_get_ts_info NULL190 191#define sja1105_port_rxtstamp NULL192 193#define sja1105_port_txtstamp NULL194 195#define sja1105_hwtstamp_get NULL196 197#define sja1105_hwtstamp_set NULL198 199#define sja1105_rxtstamp NULL200#define sja1110_rxtstamp NULL201#define sja1110_txtstamp NULL202 203#define sja1110_process_meta_tstamp NULL204 205#endif /* IS_ENABLED(CONFIG_NET_DSA_SJA1105_PTP) */206 207#endif /* _SJA1105_PTP_H */208