Patrick Ohly | cb9eff0 | 2009-02-12 05:03:36 +0000 | [diff] [blame] | 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 | |
| 24 | Instructs the socket layer which kind of information is wanted. The |
| 25 | parameter is an integer with some of the following bits set. Setting |
| 26 | other bits is an error and doesn't change the current state. |
| 27 | |
| 28 | SOF_TIMESTAMPING_TX_HARDWARE: try to obtain send time stamp in hardware |
| 29 | SOF_TIMESTAMPING_TX_SOFTWARE: if SOF_TIMESTAMPING_TX_HARDWARE is off or |
| 30 | fails, then do it in software |
| 31 | SOF_TIMESTAMPING_RX_HARDWARE: return the original, unmodified time stamp |
| 32 | as generated by the hardware |
| 33 | SOF_TIMESTAMPING_RX_SOFTWARE: if SOF_TIMESTAMPING_RX_HARDWARE is off or |
| 34 | fails, then do it in software |
| 35 | SOF_TIMESTAMPING_RAW_HARDWARE: return original raw hardware time stamp |
| 36 | SOF_TIMESTAMPING_SYS_HARDWARE: return hardware time stamp transformed to |
| 37 | the system time base |
| 38 | SOF_TIMESTAMPING_SOFTWARE: return system time stamp generated in |
| 39 | software |
| 40 | |
| 41 | SOF_TIMESTAMPING_TX/RX determine how time stamps are generated. |
| 42 | SOF_TIMESTAMPING_RAW/SYS determine how they are reported in the |
| 43 | following control message: |
| 44 | struct scm_timestamping { |
| 45 | struct timespec systime; |
| 46 | struct timespec hwtimetrans; |
| 47 | struct timespec hwtimeraw; |
| 48 | }; |
| 49 | |
| 50 | recvmsg() can be used to get this control message for regular incoming |
| 51 | packets. For send time stamps the outgoing packet is looped back to |
| 52 | the socket's error queue with the send time stamp(s) attached. It can |
| 53 | be received with recvmsg(flags=MSG_ERRQUEUE). The call returns the |
| 54 | original outgoing packet data including all headers preprended down to |
| 55 | and including the link layer, the scm_timestamping control message and |
| 56 | a sock_extended_err control message with ee_errno==ENOMSG and |
| 57 | ee_origin==SO_EE_ORIGIN_TIMESTAMPING. A socket with such a pending |
| 58 | bounced packet is ready for reading as far as select() is concerned. |
Patrick Ohly | 51f31ca | 2009-02-12 05:03:39 +0000 | [diff] [blame] | 59 | If the outgoing packet has to be fragmented, then only the first |
| 60 | fragment is time stamped and returned to the sending socket. |
Patrick Ohly | cb9eff0 | 2009-02-12 05:03:36 +0000 | [diff] [blame] | 61 | |
| 62 | All three values correspond to the same event in time, but were |
| 63 | generated in different ways. Each of these values may be empty (= all |
| 64 | zero), in which case no such value was available. If the application |
| 65 | is not interested in some of these values, they can be left blank to |
| 66 | avoid the potential overhead of calculating them. |
| 67 | |
| 68 | systime is the value of the system time at that moment. This |
| 69 | corresponds to the value also returned via SO_TIMESTAMP[NS]. If the |
| 70 | time stamp was generated by hardware, then this field is |
| 71 | empty. Otherwise it is filled in if SOF_TIMESTAMPING_SOFTWARE is |
| 72 | set. |
| 73 | |
| 74 | hwtimeraw is the original hardware time stamp. Filled in if |
| 75 | SOF_TIMESTAMPING_RAW_HARDWARE is set. No assumptions about its |
| 76 | relation to system time should be made. |
| 77 | |
| 78 | hwtimetrans is the hardware time stamp transformed so that it |
| 79 | corresponds as good as possible to system time. This correlation is |
| 80 | not perfect; as a consequence, sorting packets received via different |
| 81 | NICs by their hwtimetrans may differ from the order in which they were |
| 82 | received. hwtimetrans may be non-monotonic even for the same NIC. |
| 83 | Filled in if SOF_TIMESTAMPING_SYS_HARDWARE is set. Requires support |
| 84 | by the network device and will be empty without that support. |
| 85 | |
| 86 | |
| 87 | SIOCSHWTSTAMP: |
| 88 | |
| 89 | Hardware time stamping must also be initialized for each device driver |
| 90 | that is expected to do hardware time stamping. The parameter is: |
| 91 | |
| 92 | struct hwtstamp_config { |
| 93 | int flags; /* no flags defined right now, must be zero */ |
| 94 | int tx_type; /* HWTSTAMP_TX_* */ |
| 95 | int rx_filter; /* HWTSTAMP_FILTER_* */ |
| 96 | }; |
| 97 | |
| 98 | Desired behavior is passed into the kernel and to a specific device by |
| 99 | calling ioctl(SIOCSHWTSTAMP) with a pointer to a struct ifreq whose |
| 100 | ifr_data points to a struct hwtstamp_config. The tx_type and |
| 101 | rx_filter are hints to the driver what it is expected to do. If |
| 102 | the requested fine-grained filtering for incoming packets is not |
| 103 | supported, the driver may time stamp more than just the requested types |
| 104 | of packets. |
| 105 | |
| 106 | A driver which supports hardware time stamping shall update the struct |
| 107 | with the actual, possibly more permissive configuration. If the |
| 108 | requested packets cannot be time stamped, then nothing should be |
| 109 | changed and ERANGE shall be returned (in contrast to EINVAL, which |
| 110 | indicates that SIOCSHWTSTAMP is not supported at all). |
| 111 | |
| 112 | Only a processes with admin rights may change the configuration. User |
| 113 | space is responsible to ensure that multiple processes don't interfere |
| 114 | with each other and that the settings are reset. |
| 115 | |
| 116 | /* possible values for hwtstamp_config->tx_type */ |
| 117 | enum { |
| 118 | /* |
| 119 | * no outgoing packet will need hardware time stamping; |
| 120 | * should a packet arrive which asks for it, no hardware |
| 121 | * time stamping will be done |
| 122 | */ |
| 123 | HWTSTAMP_TX_OFF, |
| 124 | |
| 125 | /* |
| 126 | * enables hardware time stamping for outgoing packets; |
| 127 | * the sender of the packet decides which are to be |
| 128 | * time stamped by setting SOF_TIMESTAMPING_TX_SOFTWARE |
| 129 | * before sending the packet |
| 130 | */ |
| 131 | HWTSTAMP_TX_ON, |
| 132 | }; |
| 133 | |
| 134 | /* possible values for hwtstamp_config->rx_filter */ |
| 135 | enum { |
| 136 | /* time stamp no incoming packet at all */ |
| 137 | HWTSTAMP_FILTER_NONE, |
| 138 | |
| 139 | /* time stamp any incoming packet */ |
| 140 | HWTSTAMP_FILTER_ALL, |
| 141 | |
| 142 | /* return value: time stamp all packets requested plus some others */ |
| 143 | HWTSTAMP_FILTER_SOME, |
| 144 | |
| 145 | /* PTP v1, UDP, any kind of event packet */ |
| 146 | HWTSTAMP_FILTER_PTP_V1_L4_EVENT, |
| 147 | |
| 148 | ... |
| 149 | }; |
| 150 | |
| 151 | |
| 152 | DEVICE IMPLEMENTATION |
| 153 | |
| 154 | A driver which supports hardware time stamping must support the |
| 155 | SIOCSHWTSTAMP ioctl. Time stamps for received packets must be stored |
| 156 | in the skb with skb_hwtstamp_set(). |
| 157 | |
| 158 | Time stamps for outgoing packets are to be generated as follows: |
| 159 | - In hard_start_xmit(), check if skb_hwtstamp_check_tx_hardware() |
| 160 | returns non-zero. If yes, then the driver is expected |
| 161 | to do hardware time stamping. |
| 162 | - If this is possible for the skb and requested, then declare |
| 163 | that the driver is doing the time stamping by calling |
| 164 | skb_hwtstamp_tx_in_progress(). A driver not supporting |
| 165 | hardware time stamping doesn't do that. A driver must never |
| 166 | touch sk_buff::tstamp! It is used to store how time stamping |
| 167 | for an outgoing packets is to be done. |
| 168 | - As soon as the driver has sent the packet and/or obtained a |
| 169 | hardware time stamp for it, it passes the time stamp back by |
| 170 | calling skb_hwtstamp_tx() with the original skb, the raw |
| 171 | hardware time stamp and a handle to the device (necessary |
| 172 | to convert the hardware time stamp to system time). If obtaining |
| 173 | the hardware time stamp somehow fails, then the driver should |
| 174 | not fall back to software time stamping. The rationale is that |
| 175 | this would occur at a later time in the processing pipeline |
| 176 | than other software time stamping and therefore could lead |
| 177 | to unexpected deltas between time stamps. |
| 178 | - If the driver did not call skb_hwtstamp_tx_in_progress(), then |
| 179 | dev_hard_start_xmit() checks whether software time stamping |
| 180 | is wanted as fallback and potentially generates the time stamp. |