wenquan2015 commented on PR #20161:
URL: https://github.com/apache/nuttx/pull/20161#issuecomment-5709416599
> > @daniel-p-carvalho please review and try this pr for hw timestamp.
>
> Tried this on real hardware (RMII Ethernet, STM32H743BI). The
SO_TIMESTAMPING infrastructure itself is all correct - setsockopt/getsockopt,
cmsg, the error queue, poll(POLLPRI), everything works exactly as expected.
>
> What I found: on real hardware, TX timestamp delivery depends on the
transmitted frame looping back through the receive path (io_conn match in
pkt_in()). That works fine in the simulator (which already has that loopback
simulated), but on a real Ethernet board, full-duplex, point-to-point, the
transmitted frame never shows up on RX again - so poll/recvmsg never fire.
Probably just wasn't caught because testing this needs real physical hardware
with a second point on the network, not just the simulator.
>
> I put together a prototype to close that last gap: a new function
(pkt_tx_timestamp_complete()) that lets the driver deliver the timestamp
directly from the TX-complete interrupt, without depending on any loopback -
which is how hardware TX timestamping normally works (read the completed
descriptor). Wired it into the STM32H7 driver as a reference and validated it
end to end: poll/recvmsg now deliver correctly.
>
> Left the branches available in case they're useful:
>
> daniel-p-carvalho/apache-nuttx#test/pr20161-h7-tx-timestamp (the new
delivery path + driver wiring)
daniel-p-carvalho/nuttx-apps#test/pr20161-h7-tx-timestamp (the test I used to
validate it) Happy to help if there's anything I can do.
SO_TIMESTAMPING_TX_HARDWARE depends on driver-level implementation. When
transmitting, the driver checks if the IOB is tagged for
hardware TX timestamping, clones the packet, and after the transmission
completes successfully, stamps the hardware timestamp onto
the cloned copy and loops it back to the RX path for delivery via
MSG_ERRQUEUE.
TX Hardware Timestamp: Generic Driver Implementation Pattern
Transmit path (driver_transmit):
1. Check pkt->io_conn != NULL → TX hardware timestamp requested
2. Clone the pkt (iob_clone) and hold the clone in driver private
structure
3. Start timeout timer (guard against missing timestamp / pkt leak)
4. Configure hardware: enable timestamp capture on TX descriptor
5. Submit original pkt to DMA and free it after transmission as normal
TX completion interrupt (driver_txisr):
1. Read TX timestamp from hardware registers (or poll for it)
2. Write timestamp into held clone's iob->io_time
3. Store clone into driver's pending queue
4. Notify upper layer via netdev_lower_rxready()
Receive path (driver_receive):
1. First check if a TX timestamp clone is pending delivery
2. If yes: return the clone
(upper layer routes it via pkt_in → io_conn match
→ errahead queue → userspace MSG_ERRQUEUE)
3. Otherwise: process normal RX packets
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]