This is an automated email from the ASF dual-hosted git repository.

acassis pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit 6e14c8cfe59bdcfce88ca8e09f95e3bafe7bfec6
Author: Claude <[email protected]>
AuthorDate: Fri Sep 25 16:37:16 2026 +0000

    net/netdev: add NETDEV_TX_STAMP and handle SIOCETHTOOL ETHTOOL_GET_TS_INFO
    
    Add the NETDEV_TX_STAMP capability flag to d_features, next to the
    existing NETDEV_RX_STAMP, so a driver can declare that it delivers
    hardware TX timestamps.
    
    SIOCETHTOOL and ETHTOOL_GET_TS_INFO were already defined but not
    implemented.  Add struct ethtool_ts_info, with the same layout as
    Linux, and handle SIOCETHTOOL in netdev_ioctl.c so that userspace (such
    as ptpd) can query the timestamping capabilities of an interface the
    same way linuxptp/ptp4l does on Linux:
    
    - ETHTOOL_GET_TS_INFO fills so_timestamping from d_features:
      RX_HARDWARE | RAW_HARDWARE with NETDEV_RX_STAMP, otherwise
      RX_SOFTWARE | SOFTWARE (the stack stamps received packets with
      CLOCK_REALTIME), and TX_HARDWARE | RAW_HARDWARE with NETDEV_TX_STAMP.
      phc_index is -1, tx_types and rx_filters are zero.
    - Any other ethtool command is passed to the driver's d_ioctl when
      CONFIG_NETDEV_IOCTL is enabled, otherwise -ENOTTY is returned.
    
    Assisted-by: Claude:claude-sonnet-5
    Signed-off-by: Daniel P. Carvalho <[email protected]>
---
 include/nuttx/ethtool.h    | 31 +++++++++++++++++
 include/nuttx/net/netdev.h |  1 +
 net/netdev/netdev_ioctl.c  | 85 ++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 117 insertions(+)

diff --git a/include/nuttx/ethtool.h b/include/nuttx/ethtool.h
index 26412a6a1f4..87cd3f0e1d5 100644
--- a/include/nuttx/ethtool.h
+++ b/include/nuttx/ethtool.h
@@ -23,6 +23,12 @@
 #ifndef __INCLUDE_NUTTX_ETHTOOL_H
 #define __INCLUDE_NUTTX_ETHTOOL_H
 
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <stdint.h>
+
 /****************************************************************************
  * Pre-processor Definitions
  ****************************************************************************/
@@ -221,4 +227,29 @@ struct ethtool_cmd
   uint32_t reserved[2];
 };
 
+/* struct ethtool_ts_info - holds a device's timestamping and PHC
+ * association (ETHTOOL_GET_TS_INFO), same layout as Linux.
+ * @cmd: command number = %ETHTOOL_GET_TS_INFO
+ * @so_timestamping: bit mask of the sum of the supported SO_TIMESTAMPING
+ *  flags (SOF_TIMESTAMPING_*)
+ * @phc_index: device index of the associated PHC, or -1 if there is none
+ * @tx_types: bit mask of the supported hwtstamp_tx_types values; zero,
+ *  NuttX has no SIOCSHWTSTAMP to select them
+ * @tx_reserved: reserved for future use, zero
+ * @rx_filters: bit mask of the supported hwtstamp_rx_filters values; zero,
+ *  NuttX has no SIOCSHWTSTAMP to select them
+ * @rx_reserved: reserved for future use, zero
+ */
+
+struct ethtool_ts_info
+{
+  uint32_t cmd;
+  uint32_t so_timestamping;
+  int32_t  phc_index;
+  uint32_t tx_types;
+  uint32_t tx_reserved[3];
+  uint32_t rx_filters;
+  uint32_t rx_reserved[3];
+};
+
 #endif
diff --git a/include/nuttx/net/netdev.h b/include/nuttx/net/netdev.h
index c5395ba67cd..a5a78c078c7 100644
--- a/include/nuttx/net/netdev.h
+++ b/include/nuttx/net/netdev.h
@@ -85,6 +85,7 @@
 #define NETDEV_TX_CSUM  (1 << 1) /* Netdev support hardware tx checksum */
 #define NETDEV_RX_CSUM  (1 << 2) /* Netdev support hardware rx checksum */
 #define NETDEV_RX_STAMP (1 << 3) /* Netdev support hardware timestamp */
+#define NETDEV_TX_STAMP (1 << 4) /* Netdev provides hardware TX timestamps */
 
 /* Determine the largest possible address */
 
diff --git a/net/netdev/netdev_ioctl.c b/net/netdev/netdev_ioctl.c
index 4f6610f4396..1b846e30e61 100644
--- a/net/netdev/netdev_ioctl.c
+++ b/net/netdev/netdev_ioctl.c
@@ -43,6 +43,7 @@
 #include <net/ethernet.h>
 #include <netinet/in.h>
 
+#include <nuttx/ethtool.h>
 #include <nuttx/net/netdev.h>
 #include <nuttx/net/radiodev.h>
 #include <nuttx/net/vlan.h>
@@ -767,6 +768,7 @@ static ssize_t net_ioctl_ifreq_arglen(uint8_t domain, int 
cmd)
       case SIOCGIFCOUNT:
       case SIOCSIFFLAGS:
       case SIOCGIFFLAGS:
+      case SIOCETHTOOL:
       case SIOCMIINOTIFY:
       case SIOCGMIIPHY:
       case SIOCGMIIREG:
@@ -809,6 +811,85 @@ static ssize_t net_ioctl_ifreq_arglen(uint8_t domain, int 
cmd)
   return -ENOTTY;
 }
 
+/****************************************************************************
+ * Name: netdev_ethtool_ioctl
+ *
+ * Description:
+ *   Handle the SIOCETHTOOL command.  req->ifr_data points to an ethtool
+ *   command structure whose first field is the ETHTOOL_* command.
+ *   ETHTOOL_GET_TS_INFO is answered from the device features; any other
+ *   command is passed to the driver.
+ *
+ * Input Parameters:
+ *   dev      The network device
+ *   req      The argument of the ioctl cmd
+ *
+ * Returned Value:
+ *   >=0 on success (positive non-zero values are cmd-specific)
+ *   Negated errno returned on failure.
+ *
+ ****************************************************************************/
+
+static int netdev_ethtool_ioctl(FAR struct net_driver_s *dev,
+                                FAR struct ifreq *req)
+{
+  FAR uint32_t *ethcmd = req->ifr_data;
+
+  if (ethcmd == NULL)
+    {
+      return -EINVAL;
+    }
+
+  switch (*ethcmd)
+    {
+      case ETHTOOL_GET_TS_INFO:  /* Get time stamping and PHC info */
+        {
+          FAR struct ethtool_ts_info *info = req->ifr_data;
+
+          memset(info, 0, sizeof(*info));
+          info->cmd       = ETHTOOL_GET_TS_INFO;
+          info->phc_index = -1;
+
+#ifdef CONFIG_NET_TIMESTAMP
+          /* Received packets carry the hardware timestamp when the driver
+           * provides one, and are stamped by the stack with CLOCK_REALTIME
+           * otherwise.
+           */
+
+          if ((dev->d_features & NETDEV_RX_STAMP) != 0)
+            {
+              info->so_timestamping |= SOF_TIMESTAMPING_RX_HARDWARE |
+                                       SOF_TIMESTAMPING_RAW_HARDWARE;
+            }
+          else
+            {
+              info->so_timestamping |= SOF_TIMESTAMPING_RX_SOFTWARE |
+                                       SOF_TIMESTAMPING_SOFTWARE;
+            }
+
+          if ((dev->d_features & NETDEV_TX_STAMP) != 0)
+            {
+              info->so_timestamping |= SOF_TIMESTAMPING_TX_HARDWARE |
+                                       SOF_TIMESTAMPING_RAW_HARDWARE;
+            }
+#endif
+
+          return OK;
+        }
+
+      default:
+#ifdef CONFIG_NETDEV_IOCTL
+        if (dev->d_ioctl != NULL)
+          {
+            return dev->d_ioctl(dev, SIOCETHTOOL,
+                                (unsigned long)(uintptr_t)req->ifr_data);
+          }
+#endif
+
+        return -ENOTTY;
+    }
+}
+
 /****************************************************************************
  * Name: netdev_ifr_ioctl
  *
@@ -1088,6 +1169,10 @@ static int netdev_ifr_ioctl(FAR struct socket *psock, 
int cmd,
         req->ifr_flags = dev->d_flags;
         break;
 
+      case SIOCETHTOOL:   /* Ethtool interface */
+        ret = netdev_ethtool_ioctl(dev, req);
+        break;
+
       /* MAC address operations only make sense if Ethernet or 6LoWPAN are
        * supported.
        */

Reply via email to