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 | |
43 | SOF_TIMESTAMPING_SYS_HARDWARE: report hwtimetrans if available | |
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 | ||
91 | hwtimetrans is the hardware time stamp transformed so that it | |
92 | corresponds as good as possible to system time. This correlation is | |
93 | not perfect; as a consequence, sorting packets received via different | |
94 | NICs by their hwtimetrans may differ from the order in which they were | |
95 | received. hwtimetrans may be non-monotonic even for the same NIC. | |
96 | Filled in if SOF_TIMESTAMPING_SYS_HARDWARE is set. Requires support | |
97 | by the network device and will be empty without that support. | |
98 | ||
99 | ||
fd468c74 | 100 | SIOCSHWTSTAMP, SIOCGHWTSTAMP: |
cb9eff09 PO |
101 | |
102 | Hardware time stamping must also be initialized for each device driver | |
69298698 PL |
103 | that is expected to do hardware time stamping. The parameter is defined in |
104 | /include/linux/net_tstamp.h as: | |
cb9eff09 PO |
105 | |
106 | struct hwtstamp_config { | |
69298698 PL |
107 | int flags; /* no flags defined right now, must be zero */ |
108 | int tx_type; /* HWTSTAMP_TX_* */ | |
109 | int rx_filter; /* HWTSTAMP_FILTER_* */ | |
cb9eff09 PO |
110 | }; |
111 | ||
112 | Desired behavior is passed into the kernel and to a specific device by | |
113 | calling ioctl(SIOCSHWTSTAMP) with a pointer to a struct ifreq whose | |
114 | ifr_data points to a struct hwtstamp_config. The tx_type and | |
115 | rx_filter are hints to the driver what it is expected to do. If | |
116 | the requested fine-grained filtering for incoming packets is not | |
117 | supported, the driver may time stamp more than just the requested types | |
118 | of packets. | |
119 | ||
120 | A driver which supports hardware time stamping shall update the struct | |
121 | with the actual, possibly more permissive configuration. If the | |
122 | requested packets cannot be time stamped, then nothing should be | |
123 | changed and ERANGE shall be returned (in contrast to EINVAL, which | |
124 | indicates that SIOCSHWTSTAMP is not supported at all). | |
125 | ||
126 | Only a processes with admin rights may change the configuration. User | |
127 | space is responsible to ensure that multiple processes don't interfere | |
128 | with each other and that the settings are reset. | |
129 | ||
fd468c74 BH |
130 | Any process can read the actual configuration by passing this |
131 | structure to ioctl(SIOCGHWTSTAMP) in the same way. However, this has | |
132 | not been implemented in all drivers. | |
133 | ||
cb9eff09 PO |
134 | /* possible values for hwtstamp_config->tx_type */ |
135 | enum { | |
136 | /* | |
137 | * no outgoing packet will need hardware time stamping; | |
138 | * should a packet arrive which asks for it, no hardware | |
139 | * time stamping will be done | |
140 | */ | |
141 | HWTSTAMP_TX_OFF, | |
142 | ||
143 | /* | |
144 | * enables hardware time stamping for outgoing packets; | |
145 | * the sender of the packet decides which are to be | |
146 | * time stamped by setting SOF_TIMESTAMPING_TX_SOFTWARE | |
147 | * before sending the packet | |
148 | */ | |
149 | HWTSTAMP_TX_ON, | |
150 | }; | |
151 | ||
152 | /* possible values for hwtstamp_config->rx_filter */ | |
153 | enum { | |
154 | /* time stamp no incoming packet at all */ | |
155 | HWTSTAMP_FILTER_NONE, | |
156 | ||
157 | /* time stamp any incoming packet */ | |
158 | HWTSTAMP_FILTER_ALL, | |
159 | ||
69298698 PL |
160 | /* return value: time stamp all packets requested plus some others */ |
161 | HWTSTAMP_FILTER_SOME, | |
cb9eff09 PO |
162 | |
163 | /* PTP v1, UDP, any kind of event packet */ | |
164 | HWTSTAMP_FILTER_PTP_V1_L4_EVENT, | |
165 | ||
69298698 PL |
166 | /* for the complete list of values, please check |
167 | * the include file /include/linux/net_tstamp.h | |
168 | */ | |
cb9eff09 PO |
169 | }; |
170 | ||
171 | ||
172 | DEVICE IMPLEMENTATION | |
173 | ||
174 | A driver which supports hardware time stamping must support the | |
69298698 | 175 | SIOCSHWTSTAMP ioctl and update the supplied struct hwtstamp_config with |
fd468c74 BH |
176 | the actual values as described in the section on SIOCSHWTSTAMP. It |
177 | should also support SIOCGHWTSTAMP. | |
69298698 PL |
178 | |
179 | Time stamps for received packets must be stored in the skb. To get a pointer | |
180 | to the shared time stamp structure of the skb call skb_hwtstamps(). Then | |
181 | set the time stamps in the structure: | |
182 | ||
183 | struct skb_shared_hwtstamps { | |
184 | /* hardware time stamp transformed into duration | |
185 | * since arbitrary point in time | |
186 | */ | |
187 | ktime_t hwtstamp; | |
188 | ktime_t syststamp; /* hwtstamp transformed to system time base */ | |
189 | }; | |
cb9eff09 PO |
190 | |
191 | Time stamps for outgoing packets are to be generated as follows: | |
2244d07b OH |
192 | - In hard_start_xmit(), check if (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) |
193 | is set no-zero. If yes, then the driver is expected to do hardware time | |
194 | stamping. | |
cb9eff09 | 195 | - If this is possible for the skb and requested, then declare |
2244d07b OH |
196 | that the driver is doing the time stamping by setting the flag |
197 | SKBTX_IN_PROGRESS in skb_shinfo(skb)->tx_flags , e.g. with | |
198 | ||
199 | skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS; | |
200 | ||
201 | You might want to keep a pointer to the associated skb for the next step | |
202 | and not free the skb. A driver not supporting hardware time stamping doesn't | |
203 | do that. A driver must never touch sk_buff::tstamp! It is used to store | |
204 | software generated time stamps by the network subsystem. | |
59cb89e6 JK |
205 | - Driver should call skb_tx_timestamp() as close to passing sk_buff to hardware |
206 | as possible. skb_tx_timestamp() provides a software time stamp if requested | |
207 | and hardware timestamping is not possible (SKBTX_IN_PROGRESS not set). | |
cb9eff09 PO |
208 | - As soon as the driver has sent the packet and/or obtained a |
209 | hardware time stamp for it, it passes the time stamp back by | |
210 | calling skb_hwtstamp_tx() with the original skb, the raw | |
69298698 PL |
211 | hardware time stamp. skb_hwtstamp_tx() clones the original skb and |
212 | adds the timestamps, therefore the original skb has to be freed now. | |
213 | If obtaining the hardware time stamp somehow fails, then the driver | |
214 | should not fall back to software time stamping. The rationale is that | |
215 | this would occur at a later time in the processing pipeline than other | |
216 | software time stamping and therefore could lead to unexpected deltas | |
217 | between time stamps. |