From 604b1fedc5d3d6456d684a3b23f72bdc730cd846 Mon Sep 17 00:00:00 2001 From: "Daniel P. Carvalho" Date: Thu, 10 Sep 2026 21:18:30 -0300 Subject: [PATCH 1/6] drivers/timers: Add TMRDEPPATH/TMRVPATH for PTP clock drivers. Every other timer driver block in this Make.defs sets TMRDEPPATH and TMRVPATH so DEPPATH/VPATH include this directory. CONFIG_PTP_CLOCK and CONFIG_PTP_CLOCK_DUMMY were the only two missing it, leaving ptp_clock.c/ptp_clock_dummy.c unreachable via VPATH and without a generated dependency file when no other timer driver in this file is also selected. Assisted-by: Claude:claude-sonnet-5 Signed-off-by: Daniel P. Carvalho (cherry picked from commit 6d3812229d1c527971bf3a2b9d7d2675796fc688) --- drivers/timers/Make.defs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/timers/Make.defs b/drivers/timers/Make.defs index fa14e5311bc9c..1b0bf427fb8ba 100644 --- a/drivers/timers/Make.defs +++ b/drivers/timers/Make.defs @@ -155,10 +155,14 @@ endif ifeq ($(CONFIG_PTP_CLOCK),y) CSRCS += ptp_clock.c + TMRDEPPATH = --dep-path timers + TMRVPATH = :timers endif ifeq ($(CONFIG_PTP_CLOCK_DUMMY),y) CSRCS += ptp_clock_dummy.c + TMRDEPPATH = --dep-path timers + TMRVPATH = :timers endif # Include timer build support (if any were selected) From 6d5c0624c4bbef0b4748ebc3c7ae019075d39891 Mon Sep 17 00:00:00 2001 From: "Daniel P. Carvalho" Date: Sun, 13 Sep 2026 12:21:26 -0300 Subject: [PATCH 2/6] arch/arm/stm32: Convert RX hardware timestamp before pkt_input(). stm32_receive() called pkt_input() before stm32_eth_ptp_convert_rxtime(), so every packet handed to a packet socket carried the previous frame's RX timestamp instead of its own in dev->d_rxtime. Reorder so the timestamp is converted first. Assisted-by: Claude:claude-sonnet-5 Signed-off-by: Daniel P. Carvalho (cherry picked from commit 9bfa20da28da79a567e3b38cb127767cf9e03042) --- arch/arm/src/common/stm32/stm32_eth_m3m4_v1.c | 21 +++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/arch/arm/src/common/stm32/stm32_eth_m3m4_v1.c b/arch/arm/src/common/stm32/stm32_eth_m3m4_v1.c index b151bf6e9ced8..6614bdc10731c 100644 --- a/arch/arm/src/common/stm32/stm32_eth_m3m4_v1.c +++ b/arch/arm/src/common/stm32/stm32_eth_m3m4_v1.c @@ -1714,12 +1714,6 @@ static void stm32_receive(struct stm32_ethmac_s *priv) while (stm32_recvframe(priv) == OK) { -#ifdef CONFIG_NET_PKT - /* When packet sockets are enabled, feed the frame into the tap */ - - pkt_input(&priv->dev); -#endif - /* Check if the packet is a valid size for the network buffer * configuration (this should not happen) */ @@ -1741,9 +1735,24 @@ static void stm32_receive(struct stm32_ethmac_s *priv) } #ifdef CONFIG_STM32_ETH_TIMESTAMP_RX + /* Convert this frame's hardware RX timestamp before handing the + * frame to pkt_input() below. pkt_input() copies dev->d_rxtime + * into the packet socket's queued metadata immediately, so if + * the conversion ran after it, every packet would be tagged + * with the *previous* frame's timestamp instead of its own, + * introducing effectively random error on the order of the + * inter-frame interval into every RX timestamp. + */ + stm32_eth_ptp_convert_rxtime(priv); #endif +#ifdef CONFIG_NET_PKT + /* When packet sockets are enabled, feed the frame into the tap */ + + pkt_input(&priv->dev); +#endif + /* We only accept IP packets of the configured type and ARP packets */ #ifdef CONFIG_NET_IPv4 From d4cce751c7f5d131ace7991221866510c53af21b Mon Sep 17 00:00:00 2001 From: "Daniel P. Carvalho" Date: Sun, 13 Sep 2026 12:21:39 -0300 Subject: [PATCH 3/6] arch/arm/stm32: Disable reception of self-transmitted frames. Set ETH_MACCR_ROD unconditionally when configuring the MAC. In half-duplex mode the MAC otherwise reflects every frame it transmits back to its own receiver, flooding the receive path with our own traffic right as a genuine reply arrives. The bit has no effect in full-duplex (confirmed on our hardware: fduplex=1), so setting it unconditionally is safe and changes nothing observable for boards already running full-duplex. The sibling stm32f7 driver has the same gap (ETH_MACCR_ROD cleared but never set) and stm32h7's equivalent ETH_MACCR_DO bit has the same issue; both are left out of scope here since only m3m4_v1 hardware was available to validate against. Assisted-by: Claude:claude-sonnet-5 Signed-off-by: Daniel P. Carvalho (cherry picked from commit 41536cb8c9f5ff448864d2eb490b35aea7cdafcf) --- arch/arm/src/common/stm32/stm32_eth_m3m4_v1.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/arch/arm/src/common/stm32/stm32_eth_m3m4_v1.c b/arch/arm/src/common/stm32/stm32_eth_m3m4_v1.c index 6614bdc10731c..a033064d3f33d 100644 --- a/arch/arm/src/common/stm32/stm32_eth_m3m4_v1.c +++ b/arch/arm/src/common/stm32/stm32_eth_m3m4_v1.c @@ -3913,6 +3913,16 @@ static int stm32_macconfig(struct stm32_ethmac_s *priv) regval &= ~MACCR_CLEAR_BITS; regval |= MACCR_SET_BITS; + /* Disable reception of our own transmitted frames. In half-duplex + * mode the MAC otherwise reflects every frame it transmits back to + * its own receiver (this bit has no effect in full-duplex, so it is + * safe to set unconditionally). Without it, a busy transmitter can + * flood the receive path with its own traffic right as a genuine + * reply arrives. + */ + + regval |= ETH_MACCR_ROD; + if (priv->fduplex) { /* Set the DM bit for full duplex support */ From 3c869fd828033b02b49a0cb0fa4a51fcf3b23e06 Mon Sep 17 00:00:00 2001 From: "Daniel P. Carvalho" Date: Thu, 17 Sep 2026 14:37:27 -0300 Subject: [PATCH 4/6] arch/arm/stm32: deliver direct hardware counter timestamps for PTP. The MAC hardware counter is the PTP clock reference. Delivering its raw timestamp directly (instead of synthesizing one against CLOCK_REALTIME, which starts at an arbitrary boot-time phase) lets the PTP daemon close the feedback loop and phase-lock the MAC counter - and therefore the physical PPS output - to the master. Assisted-by: Gemini:gemini-3.8-flash-medium Signed-off-by: Daniel P. Carvalho --- arch/arm/src/common/stm32/stm32_eth_m3m4_v1.c | 40 +++++-------------- 1 file changed, 11 insertions(+), 29 deletions(-) diff --git a/arch/arm/src/common/stm32/stm32_eth_m3m4_v1.c b/arch/arm/src/common/stm32/stm32_eth_m3m4_v1.c index a033064d3f33d..90fc38586daa4 100644 --- a/arch/arm/src/common/stm32/stm32_eth_m3m4_v1.c +++ b/arch/arm/src/common/stm32/stm32_eth_m3m4_v1.c @@ -774,8 +774,10 @@ static int stm32_ethconfig(struct stm32_ethmac_s *priv); #ifdef CONFIG_STM32_ETH_PTP static int stm32_eth_ptp_adjust(long ppb); static void stm32_eth_ptp_init(uint64_t timestamp); +#ifdef CONFIG_STM32_ETH_PTP_RTC_HIRES static uint64_t stm32_eth_ptp_gettime(void); #endif +#endif #ifdef CONFIG_STM32_ETH_TIMESTAMP_RX static void stm32_eth_ptp_convert_rxtime(struct stm32_ethmac_s *priv); @@ -3707,6 +3709,7 @@ static void stm32_eth_ptp_init(uint64_t timestamp) #endif } +#ifdef CONFIG_STM32_ETH_PTP_RTC_HIRES /**************************************************************************** * Name: stm32_eth_ptp_gettime * @@ -3751,6 +3754,7 @@ static uint64_t stm32_eth_ptp_gettime(void) return ((uint64_t)high2 << 32); } } +#endif static inline void ptp_to_timespec(uint64_t timestamp, struct timespec *ts) { @@ -3763,7 +3767,6 @@ static inline void ptp_to_timespec(uint64_t timestamp, struct timespec *ts) static void stm32_eth_ptp_convert_rxtime(struct stm32_ethmac_s *priv) { uint64_t timestamp; - struct timespec rxtime; timestamp = ((uint64_t)priv->rxtimehigh << 32) | ((priv->rxtimelow & ETH_PTPTSLR_MASK) << 1); @@ -3782,35 +3785,14 @@ static void stm32_eth_ptp_convert_rxtime(struct stm32_ethmac_s *priv) return; } -#ifdef CONFIG_STM32_ETH_PTP_RTC_HIRES - /* PTP is the system time reference, just add the base time */ - - ptp_to_timespec(timestamp, &rxtime); - clock_timespec_add(&rxtime, &g_stm32_eth_ptp_basetime, - &priv->dev.d_rxtime); + /* Convert 64-bit hardware timestamp directly into timespec. + * In a PTP system, the MAC hardware counter is the PTP clock reference. + * Delivering the hardware counter's timestamp directly allows the PTP + * daemon to close the feedback loop and phase-lock the MAC counter (and + * therefore the physical PPS output) to the master. + */ -#else - { - struct timespec realtime; - uint64_t ptptime; - irqstate_t flags; - - /* Sample PTP and CLOCK_REALTIME close to each other */ - - clock_gettime(CLOCK_REALTIME, &realtime); - flags = spin_lock_irqsave(&g_rtc_lock); - ptptime = stm32_eth_ptp_gettime(); - spin_unlock_irqrestore(&g_rtc_lock, flags); - - /* Compute how much time has elapsed since packet reception - * and add that to current time. - */ - - timestamp = ptptime - timestamp; - ptp_to_timespec(timestamp, &rxtime); - clock_timespec_add(&rxtime, &realtime, &priv->dev.d_rxtime); - } -#endif /* CONFIG_STM32_ETH_PTP_RTC_HIRES */ + ptp_to_timespec(timestamp, &priv->dev.d_rxtime); } #endif /* CONFIG_STM32_ETH_TIMESTAMP_RX */ From 47ab95b6e853fd3f68a9d5b7fec2e3a173674056 Mon Sep 17 00:00:00 2001 From: "Daniel P. Carvalho" Date: Thu, 17 Sep 2026 17:33:32 -0300 Subject: [PATCH 5/6] arch/arm/stm32: implement PTP hardware clock driver (/dev/ptp0) Implement lower-half PTP hardware clock operations (struct ptp_lowerhalf_s and struct ptp_ops_s) in the STM32 Ethernet driver and register it with the generic PTP clock framework (drivers/timers/ptp_clock.c) to expose /dev/ptp0. Supported operations: - adjfine: adjust PTP clock frequency in parts per billion (ppb) - adjphase: adjust PTP clock phase via hardware TSSTU - adjtime: shift PTP clock time by signed delta in nanoseconds - gettime: atomic double-read of hardware timestamp registers - settime: initialize hardware timestamp counter via TSSTI - getres: return 1 ns clock resolution Also fix a sign bug in stm32_eth_ptp_adjust() where uint64_t addend promoted negative ppb adjustments to unsigned, corrupting frequency trim for crystals running faster than nominal. Follow-up to #20148 per review recommendation to use the standard POSIX /dev/ptp0 character driver instead of custom socket ioctls. Assisted-by: Gemini:gemini-3.8-pro Signed-off-by: Daniel P. Carvalho --- arch/arm/src/common/stm32/stm32_eth_m3m4_v1.c | 261 +++++++++++++++++- 1 file changed, 249 insertions(+), 12 deletions(-) diff --git a/arch/arm/src/common/stm32/stm32_eth_m3m4_v1.c b/arch/arm/src/common/stm32/stm32_eth_m3m4_v1.c index 90fc38586daa4..56947eb3a2a63 100644 --- a/arch/arm/src/common/stm32/stm32_eth_m3m4_v1.c +++ b/arch/arm/src/common/stm32/stm32_eth_m3m4_v1.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -54,6 +55,10 @@ # include #endif +#if defined(CONFIG_PTP_CLOCK) || defined(CONFIG_STM32_ETH_PTP) +# include +#endif + #include "arm_internal.h" #include "chip.h" #include "stm32_gpio.h" @@ -630,6 +635,9 @@ struct stm32_ethmac_s uint32_t rxtimelow; /* Received packet timestamp subsecond */ uint32_t rxtimehigh; /* Received packet timestamp seconds */ #endif +#if defined(CONFIG_STM32_ETH_PTP) && defined(CONFIG_PTP_CLOCK) + struct ptp_lowerhalf_s ptp_lower; /* PTP hardware clock lower half */ +#endif }; /**************************************************************************** @@ -772,7 +780,10 @@ static int stm32_ethconfig(struct stm32_ethmac_s *priv); /* PTP initialization and access */ #ifdef CONFIG_STM32_ETH_PTP -static int stm32_eth_ptp_adjust(long ppb); +static int stm32_ptp_adjfine(struct ptp_lowerhalf_s *lower, long ppb); +#ifdef CONFIG_PTP_CLOCK +static int stm32_ptp_adjtime(struct ptp_lowerhalf_s *lower, int64_t delta); +#endif static void stm32_eth_ptp_init(uint64_t timestamp); #ifdef CONFIG_STM32_ETH_PTP_RTC_HIRES static uint64_t stm32_eth_ptp_gettime(void); @@ -3567,15 +3578,19 @@ static inline void stm32_ethgpioconfig(struct stm32_ethmac_s *priv) #ifdef CONFIG_STM32_ETH_PTP /**************************************************************************** - * Function: stm32_eth_ptp_adjust + * Name: stm32_ptp_adjfine * * Description: - * Adjust PTP timer run rate. + * Adjust the PTP clock frequency in parts per billion (ppb). * * Input Parameters: - * ppb - Adjustment in parts per billion (nanoseconds per second). - * Zero is default rate, positive value makes clock run faster - * and negative value slower. + * lower - Pointer to the PTP clock lower-half instance (unused; this + * implementation also serves as the PTP timer's own internal + * rate setter, called with lower == NULL from + * stm32_eth_ptp_init() and up_rtc_adjtime()). + * ppb - Adjustment in parts per billion (nanoseconds per second). + * Zero is default rate, positive value makes clock run faster + * and negative value slower. * * Returned Value: * OK on success, negated errno on failure. @@ -3585,12 +3600,14 @@ static inline void stm32_ethgpioconfig(struct stm32_ethmac_s *priv) * ****************************************************************************/ -static int stm32_eth_ptp_adjust(long ppb) +static int stm32_ptp_adjfine(struct ptp_lowerhalf_s *lower, long ppb) { uint32_t regval; - uint64_t addend; + int64_t addend; uint32_t increment; + UNUSED(lower); + /* Compute addend value to achieve nominal timer rate. * Increment is set by stm32_eth_ptp_init() and remains constants after * that. @@ -3608,9 +3625,9 @@ static int stm32_eth_ptp_adjust(long ppb) /* Check for overflows */ - if (addend == 0 || (uint32_t)addend != addend) + if (addend <= 0 || addend > UINT32_MAX) { - nerr("PTP adjustment out of range: ppb=%ld, addend=%lld\n", + nerr("PTP adjustment out of range: ppb=%ld, addend=%" PRId64 "\n", ppb, addend); return -EINVAL; } @@ -3632,6 +3649,72 @@ static int stm32_eth_ptp_adjust(long ppb) return OK; } +#ifdef CONFIG_PTP_CLOCK +/**************************************************************************** + * Name: stm32_ptp_adjtime + * + * Description: + * Nudge the PTP hardware counter's phase by a signed delta, in + * nanoseconds, via the System Time Update (TSSTU) mechanism. Unlike + * stm32_eth_ptp_init(), this does not reset the rate (addend) that + * stm32_ptp_adjfine() may already have applied. + * + * Input Parameters: + * lower - Pointer to the PTP clock lower-half instance (unused; this + * implementation also serves as the PTP timer's own internal + * phase setter, called with lower == NULL from + * stm32_ptp_adjphase()). + * delta - Amount to add to (positive) or subtract from (negative) the + * current counter value, in nanoseconds. + * + * Returned Value: + * OK on success, negated errno on failure. + * + ****************************************************************************/ + +static int stm32_ptp_adjtime(struct ptp_lowerhalf_s *lower, int64_t delta) +{ + uint32_t regval; + uint32_t sec; + uint32_t subsec; + uint32_t abs_nsec; + uint64_t abs_ns; + bool negative; + + UNUSED(lower); + + negative = (delta < 0); + abs_ns = llabs(delta); + + sec = abs_ns / NSEC_PER_SEC; + abs_nsec = abs_ns % NSEC_PER_SEC; + + /* Convert the nanosecond remainder to the same 32-bit binary fraction + * of a second used by ptp_to_timespec()/stm32_eth_ptp_init(), then + * halve it to fit the 31-bit TSUSS field (mirrors the >>1 done in + * stm32_eth_ptp_init()). + */ + + subsec = (((uint64_t)abs_nsec << 32) / NSEC_PER_SEC) >> 1; + subsec &= ETH_PTPTSLR_MASK; + + stm32_putreg(sec, STM32_ETH_PTPTSHUR); + stm32_putreg(subsec | (negative ? ETH_PTPTSLU_TSUPNS : 0), + STM32_ETH_PTPTSLUR); + + regval = stm32_getreg(STM32_ETH_PTPTSCR); + stm32_putreg(regval | ETH_PTPTSCR_TSSTU, STM32_ETH_PTPTSCR); + up_udelay(1); + if (stm32_getreg(STM32_ETH_PTPTSCR) & ETH_PTPTSCR_TSSTU) + { + nerr("PTP phase update failed\n"); + return -EBUSY; + } + + return OK; +} +#endif /* CONFIG_PTP_CLOCK */ + /**************************************************************************** * Function: stm32_eth_ptp_init * @@ -3678,7 +3761,7 @@ static void stm32_eth_ptp_init(uint64_t timestamp) /* Update addend value to default rate */ - stm32_eth_ptp_adjust(0); + stm32_ptp_adjfine(NULL, 0); /* Enable fine update mode */ @@ -3709,6 +3792,148 @@ static void stm32_eth_ptp_init(uint64_t timestamp) #endif } +#if defined(CONFIG_STM32_ETH_PTP) && defined(CONFIG_PTP_CLOCK) +/**************************************************************************** + * Name: stm32_ptp_adjphase + * + * Description: + * Adjust the PTP clock phase by a signed offset in nanoseconds. + * + * Input Parameters: + * lower - Pointer to the PTP clock lower-half instance + * phase - Phase adjustment in nanoseconds + * + * Returned Value: + * OK on success, negated errno on failure. + * + ****************************************************************************/ + +static int stm32_ptp_adjphase(struct ptp_lowerhalf_s *lower, int32_t phase) +{ + return stm32_ptp_adjtime(lower, phase); +} + +/**************************************************************************** + * Name: stm32_ptp_gettime + * + * Description: + * Read the current time from the PTP hardware clock. + * + * Input Parameters: + * lower - Pointer to the PTP clock lower-half instance + * ts - Location to store the current PTP time + * sts - System timestamp pair (unused, can be NULL) + * + * Returned Value: + * OK on success, negated errno on failure. + * + ****************************************************************************/ + +static int stm32_ptp_gettime(struct ptp_lowerhalf_s *lower, + struct timespec *ts, + struct ptp_system_timestamp *sts) +{ + uint32_t high1; + uint32_t low; + uint32_t high2; + uint32_t subsec; + + high1 = getreg32(STM32_ETH_PTPTSHR); + low = getreg32(STM32_ETH_PTPTSLR); + high2 = getreg32(STM32_ETH_PTPTSHR); + + if (high1 != high2) + { + low = getreg32(STM32_ETH_PTPTSLR); + } + + ts->tv_sec = high2; + subsec = (low & ETH_PTPTSLR_MASK) << 1; + ts->tv_nsec = ((uint64_t)subsec * NSEC_PER_SEC) >> 32; + + return OK; +} + +/**************************************************************************** + * Name: stm32_ptp_settime + * + * Description: + * Set the current time on the PTP hardware clock. + * + * Input Parameters: + * lower - Pointer to the PTP clock lower-half instance + * ts - Time value to set + * + * Returned Value: + * OK on success, negated errno on failure. + * + ****************************************************************************/ + +static int stm32_ptp_settime(struct ptp_lowerhalf_s *lower, + const struct timespec *ts) +{ + uint32_t regval; + uint32_t subsec; + + if (ts->tv_nsec < 0 || ts->tv_nsec >= NSEC_PER_SEC) + { + return -EINVAL; + } + + subsec = (((uint64_t)ts->tv_nsec << 32) / NSEC_PER_SEC) >> 1; + subsec &= ETH_PTPTSLR_MASK; + + stm32_putreg((uint32_t)ts->tv_sec, STM32_ETH_PTPTSHUR); + stm32_putreg(subsec, STM32_ETH_PTPTSLUR); + + regval = stm32_getreg(STM32_ETH_PTPTSCR); + stm32_putreg(regval | ETH_PTPTSCR_TSSTI, STM32_ETH_PTPTSCR); + up_udelay(1); + + if (stm32_getreg(STM32_ETH_PTPTSCR) & ETH_PTPTSCR_TSSTI) + { + nerr("PTP timestamp update failed\n"); + return -EBUSY; + } + + return OK; +} + +/**************************************************************************** + * Name: stm32_ptp_getres + * + * Description: + * Get the resolution of the PTP hardware clock (1 ns). + * + * Input Parameters: + * lower - Pointer to the PTP clock lower-half instance + * res - Location to store the resolution + * + * Returned Value: + * OK on success. + * + ****************************************************************************/ + +static int stm32_ptp_getres(struct ptp_lowerhalf_s *lower, + struct timespec *res) +{ + res->tv_sec = 0; + res->tv_nsec = 1; + return OK; +} + +static const struct ptp_ops_s g_stm32_ptp_ops = +{ + stm32_ptp_adjfine, /* adjfine */ + stm32_ptp_adjphase, /* adjphase */ + stm32_ptp_adjtime, /* adjtime */ + stm32_ptp_gettime, /* gettime */ + NULL, /* getcrosststamp */ + stm32_ptp_settime, /* settime */ + stm32_ptp_getres, /* getres */ +}; +#endif + #ifdef CONFIG_STM32_ETH_PTP_RTC_HIRES /**************************************************************************** * Name: stm32_eth_ptp_gettime @@ -4242,6 +4467,18 @@ int stm32_ethinitialize(int intf) /* Register the device with the OS so that socket IOCTLs can be performed */ netdev_register(&priv->dev, NET_LL_ETHERNET); + +#if defined(CONFIG_STM32_ETH_PTP) && defined(CONFIG_PTP_CLOCK) + /* Register the PTP clock character driver (/dev/ptp0) */ + + priv->ptp_lower.ops = &g_stm32_ptp_ops; + ret = ptp_clock_register(&priv->ptp_lower, 500000000, intf); + if (ret < 0) + { + nerr("ERROR: Failed to register PTP clock: %d\n", ret); + } +#endif + return OK; } @@ -4416,7 +4653,7 @@ int up_rtc_settime(const struct timespec *tp) int up_rtc_adjtime(long ppb) { - return stm32_eth_ptp_adjust(ppb); + return stm32_ptp_adjfine(NULL, ppb); } #endif /* CONFIG_STM32_ETH_PTP_RTC_HIRES */ From ea45d16fd48f5e0e2d81ce8de8c3e9910e1abee5 Mon Sep 17 00:00:00 2001 From: "Daniel P. Carvalho" Date: Fri, 18 Sep 2026 10:45:24 -0300 Subject: [PATCH 6/6] net/pkt: remove unused variable conn in append_timestamping Variable conn is declared and initialized in append_timestamping() but never referenced, triggering -Wunused-variable compiler warning. Assisted-by: Gemini:gemini-3.8-pro Signed-off-by: Daniel P. Carvalho --- net/pkt/pkt_recvmsg.c | 1 - 1 file changed, 1 deletion(-) diff --git a/net/pkt/pkt_recvmsg.c b/net/pkt/pkt_recvmsg.c index df1e4eea3842c..3ed20b5a238ce 100644 --- a/net/pkt/pkt_recvmsg.c +++ b/net/pkt/pkt_recvmsg.c @@ -350,7 +350,6 @@ static void append_timestamp(FAR struct pkt_recvfrom_s *pstate, static void append_timestamping(FAR struct pkt_recvfrom_s *pstate, FAR struct iob_s *iob) { - FAR struct pkt_conn_s *conn = pstate->pr_conn; struct timespec ts[3]; memset(&ts, 0, sizeof(ts));