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/netdev/eth.h"
#include "periph/gpio.h"
#include "timex.h"
#define ENABLE_DEBUG 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,
void *info)
static int stm32_eth_recv(netdev_t *netdev, void *_buf, size_t max_len,
void *_info)
{
(void)info;
(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
* DMA buffers */
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;
}
/* 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;
while (remain) {
size_t chunk = MIN(remain, ETH_RX_BUFFER_SIZE);
memcpy(data, rx_curr->buffer_addr, chunk);
data += chunk;
remain -= chunk;
/* Hand over descriptor to DMA */
rx_curr->status = RX_DESC_STAT_OWN;
rx_curr = rx_curr->desc_next;
}
if ((size + ETHERNET_FCS_LEN - 1) % ETH_RX_BUFFER_SIZE < ETHERNET_FCS_LEN) {
/* one additional rx descriptor was needed only for the FCS, hand that
* back to the DMA as well */
while (1) {
/* there can be one more DMA descriptor than needed for holding the Ethernet
* payload, as the 4 byte FCS will also be stored by DMA */
if (remain) {
size_t chunk = MIN(remain, ETH_RX_BUFFER_SIZE);
memcpy(buf, rx_curr->buffer_addr, chunk);
buf += chunk;
remain -= chunk;
}
if (rx_curr->status & RX_DESC_STAT_LS) {
/* LS bit set --> reached last DMA descriptor of this frame */
if (IS_USED(MODULE_PERIPH_PTP)) {
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 = rx_curr->desc_next;
}