Commit | Line | Data |
---|---|---|
cb9eff09 PO |
1 | The existing interfaces for getting network packages time stamped are: |
2 | ||
3 | * SO_TIMESTAMP | |
4 | Generate time stamp for each incoming packet using the (not necessarily | |
5 | monotonous!) system time. Result is returned via recv_msg() in a | |
6 | control message as timeval (usec resolution). | |
7 | ||
8 | * SO_TIMESTAMPNS | |
9 | Same time stamping mechanism as SO_TIMESTAMP, but returns result as | |
10 | timespec (nsec resolution). | |
11 | ||
12 | * IP_MULTICAST_LOOP + SO_TIMESTAMP[NS] | |
13 | Only for multicasts: approximate send time stamp by receiving the looped | |
14 | packet and using its receive time stamp. | |
15 | ||
16 | The following interface complements the existing ones: receive time | |
17 | stamps can be generated and returned for arbitrary packets and much | |
18 | closer to the point where the packet is really sent. Time stamps can | |
19 | be generated in software (as before) or in hardware (if the hardware | |
20 | has such a feature). | |
21 | ||
22 | SO_TIMESTAMPING: | |
23 | ||
adca4767 AL |
24 | Instructs the socket layer which kind of information should be collected |
25 | and/or reported. The parameter is an integer with some of the following | |
26 | bits set. Setting other bits is an error and doesn't change the current | |
27 | state. | |
28 | ||
29 | Four of the bits are requests to the stack to try to generate | |
30 | timestamps. Any combination of them is valid. | |
31 | ||
32 | SOF_TIMESTAMPING_TX_HARDWARE: try to obtain send time stamps in hardware | |
33 | SOF_TIMESTAMPING_TX_SOFTWARE: try to obtain send time stamps in software | |
34 | SOF_TIMESTAMPING_RX_HARDWARE: try to obtain receive time stamps in hardware | |
35 | SOF_TIMESTAMPING_RX_SOFTWARE: try to obtain receive time stamps in software | |
36 | ||
37 | The other three bits control which timestamps will be reported in a | |
38 | generated control message. If none of these bits are set or if none of | |
39 | the set bits correspond to data that is available, then the control | |
40 | message will not be generated: | |
41 | ||
42 | SOF_TIMESTAMPING_SOFTWARE: report systime if available | |
26c4fdb0 | 43 | SOF_TIMESTAMPING_SYS_HARDWARE: report hwtimetrans if available (deprecated) |
adca4767 AL |
44 | SOF_TIMESTAMPING_RAW_HARDWARE: report hwtimeraw if available |
45 | ||
46 | It is worth noting that timestamps may be collected for reasons other | |
47 | than being requested by a particular socket with | |
48 | SOF_TIMESTAMPING_[TR]X_(HARD|SOFT)WARE. For example, most drivers that | |
49 | can generate hardware receive timestamps ignore | |
50 | SOF_TIMESTAMPING_RX_HARDWARE. It is still a good idea to set that flag | |
51 | in case future drivers pay attention. | |
52 | ||
53 | If timestamps are reported, they will appear in a control message with | |
54 | cmsg_level==SOL_SOCKET, cmsg_type==SO_TIMESTAMPING, and a payload like | |
55 | this: | |
69298698 PL |
56 | |
57 | struct scm_timestamping { | |
58 | struct timespec systime; | |
59 | struct timespec hwtimetrans; | |
60 | struct timespec hwtimeraw; | |
61 | }; | |
cb9eff09 PO |
62 | |
63 | recvmsg() can be used to get this control message for regular incoming | |
64 | packets. For send time stamps the outgoing packet is looped back to | |
65 | the socket's error queue with the send time stamp(s) attached. It can | |
66 | be received with recvmsg(flags=MSG_ERRQUEUE). The call returns the | |
67 | original outgoing packet data including all headers preprended down to | |
68 | and including the link layer, the scm_timestamping control message and | |
69 | a sock_extended_err control message with ee_errno==ENOMSG and | |
70 | ee_origin==SO_EE_ORIGIN_TIMESTAMPING. A socket with such a pending | |
71 | bounced packet is ready for reading as far as select() is concerned. | |
51f31cab PO |
72 | If the outgoing packet has to be fragmented, then only the first |
73 | fragment is time stamped and returned to the sending socket. | |
cb9eff09 PO |
74 | |
75 | All three values correspond to the same event in time, but were | |
76 | generated in different ways. Each of these values may be empty (= all | |
77 | zero), in which case no such value was available. If the application | |
78 | is not interested in some of these values, they can be left blank to | |
79 | avoid the potential overhead of calculating them. | |
80 | ||
81 | systime is the value of the system time at that moment. This | |
82 | corresponds to the value also returned via SO_TIMESTAMP[NS]. If the | |
83 | time stamp was generated by hardware, then this field is | |
84 | empty. Otherwise it is filled in if SOF_TIMESTAMPING_SOFTWARE is | |
85 | set. | |
86 | ||
87 | hwtimeraw is the original hardware time stamp. Filled in if | |
88 | SOF_TIMESTAMPING_RAW_HARDWARE is set. No assumptions about its | |
89 | relation to system time should be made. | |
90 | ||
4d276eb6 WB |
91 | hwtimetrans is always zero. This field is deprecated. It used to hold |
92 | hw timestamps converted to system time. Instead, expose the hardware | |
26c4fdb0 WB |
93 | clock device on the NIC directly as a HW PTP clock source, to allow |
94 | time conversion in userspace and optionally synchronize system time | |
95 | with a userspace PTP stack such as linuxptp. For the PTP clock API, | |
96 | see Documentation/ptp/ptp.txt. | |
cb9eff09 PO |
97 | |
98 | ||
fd468c74 | 99 | SIOCSHWTSTAMP, SIOCGHWTSTAMP: |
cb9eff09 PO |
100 | |
101 | Hardware time stamping must also be initialized for each device driver | |
69298698 PL |
102 | that is expected to do hardware time stamping. The parameter is defined in |
103 | /include/linux/net_tstamp.h as: | |
cb9eff09 PO |
104 | |
105 | struct hwtstamp_config { | |
69298698 PL |
106 | int flags; /* no flags defined right now, must be zero */ |
107 | int tx_type; /* HWTSTAMP_TX_* */ | |
108 | int rx_filter; /* HWTSTAMP_FILTER_* */ | |
cb9eff09 PO |
109 | }; |
110 | ||
111 | Desired behavior is passed into the kernel and to a specific device by | |
112 | calling ioctl(SIOCSHWTSTAMP) with a pointer to a struct ifreq whose | |
113 | ifr_data points to a struct hwtstamp_config. The tx_type and | |
114 | rx_filter are hints to the driver what it is expected to do. If | |
115 | the requested fine-grained filtering for incoming packets is not | |
116 | supported, the driver may time stamp more than just the requested types | |
117 | of packets. | |
118 | ||
119 | A driver which supports hardware time stamping shall update the struct | |
120 | with the actual, possibly more permissive configuration. If the | |
121 | requested packets cannot be time stamped, then nothing should be | |
122 | changed and ERANGE shall be returned (in contrast to EINVAL, which | |
123 | indicates that SIOCSHWTSTAMP is not supported at all). | |
124 | ||
125 | Only a processes with admin rights may change the configuration. User | |
126 | space is responsible to ensure that multiple processes don't interfere | |
127 | with each other and that the settings are reset. | |
128 | ||
fd468c74 BH |
129 | Any process can read the actual configuration by passing this |
130 | structure to ioctl(SIOCGHWTSTAMP) in the same way. However, this has | |
131 | not been implemented in all drivers. | |
132 | ||
cb9eff09 PO |
133 | /* possible values for hwtstamp_config->tx_type */ |
134 | enum { | |
135 | /* | |
136 | * no outgoing packet will need hardware time stamping; | |
137 | * should a packet arrive which asks for it, no hardware | |
138 | * time stamping will be done | |
139 | */ | |
140 | HWTSTAMP_TX_OFF, | |
141 | ||
142 | /* | |
143 | * enables hardware time stamping for outgoing packets; | |
144 | * the sender of the packet decides which are to be | |
145 | * time stamped by setting SOF_TIMESTAMPING_TX_SOFTWARE | |
146 | * before sending the packet | |
147 | */ | |
148 | HWTSTAMP_TX_ON, | |
149 | }; | |
150 | ||
151 | /* possible values for hwtstamp_config->rx_filter */ | |
152 | enum { | |
153 | /* time stamp no incoming packet at all */ | |
154 | HWTSTAMP_FILTER_NONE, | |
155 | ||
156 | /* time stamp any incoming packet */ | |
157 | HWTSTAMP_FILTER_ALL, | |
158 | ||
69298698 PL |
159 | /* return value: time stamp all packets requested plus some others */ |
160 | HWTSTAMP_FILTER_SOME, | |
cb9eff09 PO |
161 | |
162 | /* PTP v1, UDP, any kind of event packet */ | |
163 | HWTSTAMP_FILTER_PTP_V1_L4_EVENT, | |
164 | ||
69298698 PL |
165 | /* for the complete list of values, please check |
166 | * the include file /include/linux/net_tstamp.h | |
167 | */ | |
cb9eff09 PO |
168 | }; |
169 | ||
170 | ||
171 | DEVICE IMPLEMENTATION | |
172 | ||
173 | A driver which supports hardware time stamping must support the | |
69298698 | 174 | SIOCSHWTSTAMP ioctl and update the supplied struct hwtstamp_config with |
fd468c74 BH |
175 | the actual values as described in the section on SIOCSHWTSTAMP. It |
176 | should also support SIOCGHWTSTAMP. | |
69298698 PL |
177 | |
178 | Time stamps for received packets must be stored in the skb. To get a pointer | |
179 | to the shared time stamp structure of the skb call skb_hwtstamps(). Then | |
180 | set the time stamps in the structure: | |
181 | ||
182 | struct skb_shared_hwtstamps { | |
183 | /* hardware time stamp transformed into duration | |
184 | * since arbitrary point in time | |
185 | */ | |
186 | ktime_t hwtstamp; | |
69298698 | 187 | }; |
cb9eff09 PO |
188 | |
189 | Time stamps for outgoing packets are to be generated as follows: | |
2244d07b OH |
190 | - In hard_start_xmit(), check if (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) |
191 | is set no-zero. If yes, then the driver is expected to do hardware time | |
192 | stamping. | |
cb9eff09 | 193 | - If this is possible for the skb and requested, then declare |
2244d07b OH |
194 | that the driver is doing the time stamping by setting the flag |
195 | SKBTX_IN_PROGRESS in skb_shinfo(skb)->tx_flags , e.g. with | |
196 | ||
197 | skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS; | |
198 | ||
199 | You might want to keep a pointer to the associated skb for the next step | |
200 | and not free the skb. A driver not supporting hardware time stamping doesn't | |
201 | do that. A driver must never touch sk_buff::tstamp! It is used to store | |
202 | software generated time stamps by the network subsystem. | |
59cb89e6 JK |
203 | - Driver should call skb_tx_timestamp() as close to passing sk_buff to hardware |
204 | as possible. skb_tx_timestamp() provides a software time stamp if requested | |
205 | and hardware timestamping is not possible (SKBTX_IN_PROGRESS not set). | |
cb9eff09 PO |
206 | - As soon as the driver has sent the packet and/or obtained a |
207 | hardware time stamp for it, it passes the time stamp back by | |
208 | calling skb_hwtstamp_tx() with the original skb, the raw | |
69298698 PL |
209 | hardware time stamp. skb_hwtstamp_tx() clones the original skb and |
210 | adds the timestamps, therefore the original skb has to be freed now. | |
211 | If obtaining the hardware time stamp somehow fails, then the driver | |
212 | should not fall back to software time stamping. The rationale is that | |
213 | this would occur at a later time in the processing pipeline than other | |
214 | software time stamping and therefore could lead to unexpected deltas | |
215 | between time stamps. |