Timestamp transmitted event messages with the hardware clock instead of
reading the clock after sendmsg() returns.
When hardware timestamping is selected on an AF_PACKET socket, request
SOF_TIMESTAMPING_TX_HARDWARE for each event message, wait for the
looped-back packet on the error queue with MSG_ERRQUEUE, and take the
timestamp from its SO_TIMESTAMPING control message, as on Linux. Sync,
Delay_Req and Pdelay_Req get their real departure time.
- Use a transmit socket of its own, separate from the event socket, so
the error queue is not shared with received packets.
- Handle POLLERR separately from POLLIN in the main loop and drain all
pending packets on each wakeup.
- If the timestamp does not arrive, fall back to a software timestamp
taken before the frame is sent. After three consecutive failures the
driver is assumed not to provide hardware transmit timestamps, a
warning is printed once and only software timestamps are used, so a
driver without support does not stall the daemon.
- Take the software timestamp before sending in every mode. It used to
be taken after sendmsg() returned, so a fast peer's reply could appear
to arrive before the request had left and give a negative delay.
- Accept a measured path delay down to -100 microseconds and clamp it to
zero, since hardware timestamps on both ends can make a short link
measure slightly negative.
Assisted-by: Claude:claude-sonnet-5
Signed-off-by: Daniel P. Carvalho <danieloak@gmail.com>