Merge pull request #15610 from maribu/stm32-ethernet-rx-timestamp

drivers/stm32_eth: add RX timestamps
This commit is contained in:
Marian Buschsieweke 2021-01-26 13:32:19 +01:00 committed by GitHub
commit 38188017a8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 35 additions and 17 deletions

View File

@ -28,6 +28,7 @@ config BOARD_NUCLEO_F767ZI
select HAS_PERIPH_PTP
select HAS_PERIPH_PTP_SPEED_ADJUSTMENT
select HAS_PERIPH_PTP_TIMER
select HAS_PERIPH_PTP_TXRX_TIMESTAMPS
# Put other features for this board (in alphabetical order)
select HAS_RIOTBOOT

View File

@ -9,6 +9,7 @@ FEATURES_PROVIDED += periph_i2c
FEATURES_PROVIDED += periph_ptp
FEATURES_PROVIDED += periph_ptp_speed_adjustment
FEATURES_PROVIDED += periph_ptp_timer
FEATURES_PROVIDED += periph_ptp_txrx_timestamps
FEATURES_PROVIDED += periph_rtc
FEATURES_PROVIDED += periph_rtt
FEATURES_PROVIDED += periph_spi

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;
}

View File

@ -220,6 +220,12 @@ config HAS_PERIPH_PTP_TIMER
help
Indicates that the PTP clock can be used as timer.
config HAS_PERIPH_PTP_TXRX_TIMESTAMPS
bool
help
Indicates that the PTP clock can provide exact time stamps of the
reception and transmission of frames.
config HAS_PERIPH_PWM
bool
help