cpu/stm32/periph_eth: RX Timestamps

This commit is contained in:
Marian Buschsieweke 2020-07-29 11:02:59 +02:00
parent 83201ddb00
commit 62aa3d103f
No known key found for this signature in database
GPG Key ID: 61F64C6599B1539F

View File

@ -32,6 +32,7 @@
#include "net/eui_provider.h" #include "net/eui_provider.h"
#include "net/netdev/eth.h" #include "net/netdev/eth.h"
#include "periph/gpio.h" #include "periph/gpio.h"
#include "timex.h"
#define ENABLE_DEBUG 0 #define ENABLE_DEBUG 0
#define ENABLE_DEBUG_VERBOSE 0 #define ENABLE_DEBUG_VERBOSE 0
@ -618,12 +619,12 @@ static void handle_lost_rx_irqs(void)
} }
} }
static int stm32_eth_recv(netdev_t *netdev, void *buf, size_t max_len, static int stm32_eth_recv(netdev_t *netdev, void *_buf, size_t max_len,
void *info) void *_info)
{ {
(void)info;
(void)netdev; (void)netdev;
char *data = buf; netdev_eth_rx_info_t *info = _info;
char *buf = _buf;
/* Determine the size of received frame. The frame might span multiple /* Determine the size of received frame. The frame might span multiple
* DMA buffers */ * DMA buffers */
int size = get_rx_frame_size(); int size = get_rx_frame_size();
@ -650,20 +651,29 @@ static int stm32_eth_recv(netdev_t *netdev, void *buf, size_t max_len,
return -ENOBUFS; return -ENOBUFS;
} }
/* Fetch payload, collect RX timestamp from last descriptor if module periph_ptp is used, and
* hand DMA descriptors back to the DMA */
size_t remain = size; size_t remain = size;
while (remain) { while (1) {
size_t chunk = MIN(remain, ETH_RX_BUFFER_SIZE); /* there can be one more DMA descriptor than needed for holding the Ethernet
memcpy(data, rx_curr->buffer_addr, chunk); * payload, as the 4 byte FCS will also be stored by DMA */
data += chunk; if (remain) {
remain -= chunk; size_t chunk = MIN(remain, ETH_RX_BUFFER_SIZE);
/* Hand over descriptor to DMA */ memcpy(buf, rx_curr->buffer_addr, chunk);
rx_curr->status = RX_DESC_STAT_OWN; buf += chunk;
rx_curr = rx_curr->desc_next; remain -= chunk;
} }
if (rx_curr->status & RX_DESC_STAT_LS) {
if ((size + ETHERNET_FCS_LEN - 1) % ETH_RX_BUFFER_SIZE < ETHERNET_FCS_LEN) { /* LS bit set --> reached last DMA descriptor of this frame */
/* one additional rx descriptor was needed only for the FCS, hand that if (IS_USED(MODULE_PERIPH_PTP)) {
* back to the DMA as well */ info->timestamp = rx_curr->ts_low;
info->timestamp += (uint64_t)rx_curr->ts_high * NS_PER_SEC;
info->flags |= NETDEV_ETH_RX_INFO_FLAG_TIMESTAMP;
}
rx_curr->status = RX_DESC_STAT_OWN;
rx_curr = rx_curr->desc_next;
break;
}
rx_curr->status = RX_DESC_STAT_OWN; rx_curr->status = RX_DESC_STAT_OWN;
rx_curr = rx_curr->desc_next; rx_curr = rx_curr->desc_next;
} }