drivers: ethernet: nxp: timestamping to all potential packets.

add timestamping on Tx to packets marked for timestamping
add timestamping on Rx to all packets for later use
fix race condidition on adding timestamp when sending delay_req

Signed-off-by: Adib Taraben <theadib@gmail.com>
This commit is contained in:
Adib Taraben 2025-04-06 22:54:25 +02:00 committed by Daniel DeGrasse
commit 9b8be4971e
2 changed files with 26 additions and 25 deletions

View file

@ -163,12 +163,15 @@ static inline void ts_register_tx_event(const struct device *dev,
struct net_pkt *pkt = frameinfo->context; struct net_pkt *pkt = frameinfo->context;
if (pkt && atomic_get(&pkt->atomic_ref) > 0) { if (pkt && atomic_get(&pkt->atomic_ref) > 0) {
if (eth_get_ptp_data(net_pkt_iface(pkt), pkt) && frameinfo->isTsAvail) { if ((eth_get_ptp_data(net_pkt_iface(pkt), pkt) ||
net_pkt_is_tx_timestamping(pkt)) &&
frameinfo->isTsAvail) {
/* Timestamp is written to packet in ISR. /* Timestamp is written to packet in ISR.
* Semaphore ensures sequential execution of writing * Semaphore ensures sequential execution of writing
* the timestamp here and subsequently reading the timestamp * the timestamp here and subsequently reading the timestamp
* after waiting for the semaphore in eth_wait_for_ptp_ts(). * after waiting for the semaphore in eth_wait_for_ptp_ts().
*/ */
pkt->timestamp.nanosecond = frameinfo->timeStamp.nanosecond; pkt->timestamp.nanosecond = frameinfo->timeStamp.nanosecond;
pkt->timestamp.second = frameinfo->timeStamp.second; pkt->timestamp.second = frameinfo->timeStamp.second;
@ -184,7 +187,9 @@ static inline void eth_wait_for_ptp_ts(const struct device *dev, struct net_pkt
struct nxp_enet_mac_data *data = dev->data; struct nxp_enet_mac_data *data = dev->data;
net_pkt_ref(pkt); net_pkt_ref(pkt);
k_sem_take(&data->ptp.ptp_ts_sem, K_FOREVER); while (k_sem_take(&data->ptp.ptp_ts_sem, K_MSEC(200)) != 0) {
LOG_ERR("error on take PTP semaphore");
}
} }
#else #else
#define eth_get_ptp_data(...) false #define eth_get_ptp_data(...) false
@ -220,10 +225,11 @@ static int eth_nxp_enet_tx(const struct device *dev, struct net_pkt *pkt)
goto exit; goto exit;
} }
frame_is_timestamped = eth_get_ptp_data(net_pkt_iface(pkt), pkt); frame_is_timestamped =
eth_get_ptp_data(net_pkt_iface(pkt), pkt) || net_pkt_is_tx_timestamping(pkt);
ret = ENET_SendFrame(data->base, &data->enet_handle, data->tx_frame_buf, ret = ENET_SendFrame(data->base, &data->enet_handle, data->tx_frame_buf, total_len, RING_ID,
total_len, RING_ID, frame_is_timestamped, pkt); frame_is_timestamped, pkt);
if (ret != kStatus_Success) { if (ret != kStatus_Success) {
LOG_ERR("ENET_SendFrame error: %d", ret); LOG_ERR("ENET_SendFrame error: %d", ret);
@ -339,6 +345,7 @@ static int eth_nxp_enet_rx(const struct device *dev)
{ {
#if defined(CONFIG_PTP_CLOCK_NXP_ENET) #if defined(CONFIG_PTP_CLOCK_NXP_ENET)
const struct nxp_enet_mac_config *config = dev->config; const struct nxp_enet_mac_config *config = dev->config;
struct net_ptp_time ptp_time;
#endif #endif
struct nxp_enet_mac_data *data = dev->data; struct nxp_enet_mac_data *data = dev->data;
uint32_t frame_length = 0U; uint32_t frame_length = 0U;
@ -391,14 +398,9 @@ static int eth_nxp_enet_rx(const struct device *dev)
#if defined(CONFIG_PTP_CLOCK_NXP_ENET) #if defined(CONFIG_PTP_CLOCK_NXP_ENET)
k_mutex_lock(data->ptp.ptp_mutex, K_FOREVER); k_mutex_lock(data->ptp.ptp_mutex, K_FOREVER);
/* Invalid value by default. */ /* Timestamp the packet using PTP clock. Add full second part
pkt->timestamp.nanosecond = UINT32_MAX; * the hardware timestamp contains the fractional part of the second only
pkt->timestamp.second = UINT64_MAX; */
/* Timestamp the packet using PTP clock */
if (eth_get_ptp_data(get_iface(data), pkt)) {
struct net_ptp_time ptp_time;
ptp_clock_get(config->ptp_clock, &ptp_time); ptp_clock_get(config->ptp_clock, &ptp_time);
/* If latest timestamp reloads after getting from Rx BD, /* If latest timestamp reloads after getting from Rx BD,
@ -410,7 +412,6 @@ static int eth_nxp_enet_rx(const struct device *dev)
pkt->timestamp.nanosecond = ts; pkt->timestamp.nanosecond = ts;
pkt->timestamp.second = ptp_time.second; pkt->timestamp.second = ptp_time.second;
}
k_mutex_unlock(data->ptp.ptp_mutex); k_mutex_unlock(data->ptp.ptp_mutex);
#endif /* CONFIG_PTP_CLOCK_NXP_ENET */ #endif /* CONFIG_PTP_CLOCK_NXP_ENET */

View file

@ -309,14 +309,14 @@ static int port_delay_req_msg_transmit(struct ptp_port *port)
port->iface, port->iface,
port_delay_req_timestamp_cb); port_delay_req_timestamp_cb);
sys_slist_append(&port->delay_req_list, &msg->node);
ret = port_msg_send(port, msg, PTP_SOCKET_EVENT); ret = port_msg_send(port, msg, PTP_SOCKET_EVENT);
if (ret < 0) { if (ret < 0) {
sys_slist_find_and_remove(&port->delay_req_list, &msg->node);
ptp_msg_unref(msg); ptp_msg_unref(msg);
return -EFAULT; return -EFAULT;
} }
sys_slist_append(&port->delay_req_list, &msg->node);
LOG_DBG("Port %d sends Delay_Req message", port->port_ds.id.port_number); LOG_DBG("Port %d sends Delay_Req message", port->port_ds.id.port_number);
return 0; return 0;
} }