AI Trajectory


Trajectory: (Expand/Collapse All)
Seq Timestamp Type Name Duration
0/0 2026/08/13 22:53 flow patch-triage
5m Args:
null

Results:
{
  "EnableConfigs": [
    "NETDEVSIM",
    "PTP_1588_CLOCK_MOCK",
    "PTP_1588_CLOCK"
  ],
  "FocusSymbols": [
    "nsim_set_ts_config",
    "nsim_get_ts_config",
    "nsim_get_ts_info",
    "mock_phc_get_ptp_info"
  ],
  "KMSANReasoning": "The patch adds hardware timestamping support to the `netdevsim` driver. It introduces `nsim_get_ts_info`, `nsim_set_ts_config`, and `nsim_get_ts_config` to configure timestamping, and modifies `nsim_start_xmit` to sample the mock PTP clock and attach timestamps to the skb.\n\nAnalysis of potential uninitialized memory risks:\n1. `nsim_get_ts_info` populates a `struct kernel_ethtool_ts_info`. This structure is fully zeroed by `ethtool_init_tsinfo` in the ethtool core before `ops-\u003eget_ts_info` is called. The driver only modifies specific fields, leaving no uninitialized memory.\n2. `nsim_get_ts_config` copies `ns-\u003etstamp_config` to a `struct kernel_hwtstamp_config`. `ns-\u003etstamp_config` is zero-initialized when the `netdevsim` private data is allocated via `alloc_netdev` (which uses `kvzalloc`). The core ioctl handler (`dev_get_hwtstamp`) then copies the relevant fields to a `struct hwtstamp_config` (which has no padding) before copying it to user space. No uninitialized memory is leaked.\n3. In `nsim_start_xmit`, `tx_ts` and `rx_ts` are populated by `mock_phc_gettime64`, which uses `ns_to_timespec64` to return a fully initialized `struct timespec64`.\n4. The `struct skb_shared_hwtstamps` attached to the skb is zero-initialized (`= {}`) before the `hwtstamp` field is assigned, preventing any uninitialized memory from being attached to the packet.\n\nSince all structures sent to user space or attached to packets are fully initialized, this patch does not introduce any uninitialized memory risks or info-leaks. Standard KASAN and LOCKDEP are sufficient to detect any potential memory corruption or locking issues.",
  "NeedsKMSAN": false,
  "Reasoning": "The patch adds hardware timestamping support to the netdevsim driver using the ptp_mock clock. This introduces new ioctl/ethtool entry points for configuring timestamping and modifies the TX path to sample the mock PHC. Since netdevsim is specifically designed for testing and fuzzing in virtualized environments, these changes are highly relevant and reachable for fuzzing.",
  "WorthFuzzing": true
}

1/1 2026/08/13 22:53 action read-patch-diff
0m Args:
null

Results:
{
  "PatchDiff": "commit b6aea84e729d797211e4a5ec6cecd6ba02904bb8\nAuthor: syz-cluster \u003ctriage@syzkaller.com\u003e\nDate:   Thu Aug 13 22:53:29 2026 +0000\n\n    syz-cluster: applied patch under review\n\ndiff --git a/drivers/net/netdevsim/ethtool.c b/drivers/net/netdevsim/ethtool.c\nindex 025ea79879f3a..24e7d5592e799 100644\n--- a/drivers/net/netdevsim/ethtool.c\n+++ b/drivers/net/netdevsim/ethtool.c\n@@ -200,7 +200,22 @@ static int nsim_get_ts_info(struct net_device *dev,\n {\n \tstruct netdevsim *ns = netdev_priv(dev);\n \n+\tethtool_op_get_ts_info(dev, info);\n+\tif (!ns-\u003ephc) {\n+\t\tinfo-\u003ephc_index = -1;\n+\t\treturn 0;\n+\t}\n+\n \tinfo-\u003ephc_index = mock_phc_index(ns-\u003ephc);\n+\tif (info-\u003ephc_index \u003c 0)\n+\t\treturn 0;\n+\n+\tinfo-\u003eso_timestamping |= SOF_TIMESTAMPING_TX_HARDWARE |\n+\t\t\t\t SOF_TIMESTAMPING_RX_HARDWARE |\n+\t\t\t\t SOF_TIMESTAMPING_RAW_HARDWARE;\n+\n+\tinfo-\u003etx_types = BIT(HWTSTAMP_TX_OFF) | BIT(HWTSTAMP_TX_ON);\n+\tinfo-\u003erx_filters = BIT(HWTSTAMP_FILTER_NONE) | BIT(HWTSTAMP_FILTER_ALL);\n \n \treturn 0;\n }\ndiff --git a/drivers/net/netdevsim/netdev.c b/drivers/net/netdevsim/netdev.c\nindex 4e9d7e10b527e..108f265a278a4 100644\n--- a/drivers/net/netdevsim/netdev.c\n+++ b/drivers/net/netdevsim/netdev.c\n@@ -30,6 +30,8 @@\n #include \u003cnet/rtnetlink.h\u003e\n #include \u003cnet/udp_tunnel.h\u003e\n #include \u003cnet/busy_poll.h\u003e\n+#include \u003clinux/ptp_clock_kernel.h\u003e\n+#include \u003clinux/timecounter.h\u003e\n \n #include \"netdevsim.h\"\n \n@@ -122,12 +124,18 @@ static int nsim_forward_skb(struct net_device *tx_dev,\n \n static netdev_tx_t nsim_start_xmit(struct sk_buff *skb, struct net_device *dev)\n {\n+\tstruct skb_shared_hwtstamps shhwtstamps = {};\n+\tstruct ptp_clock_info *ptp_info_tx = NULL;\n+\tstruct ptp_clock_info *ptp_info_rx = NULL;\n \tstruct netdevsim *ns = netdev_priv(dev);\n+\tstruct timespec64 tx_ts, rx_ts;\n+\tstruct sk_buff *skb_orig = skb;\n \tstruct skb_ext *psp_ext = NULL;\n \tstruct net_device *peer_dev;\n \tunsigned int len = skb-\u003elen;\n \tstruct netdevsim *peer_ns;\n \tstruct netdev_config *cfg;\n+\tunsigned long flags;\n \tstruct nsim_rq *rq;\n \tint rxq;\n \tint dr;\n@@ -164,6 +172,46 @@ static netdev_tx_t nsim_start_xmit(struct sk_buff *skb, struct net_device *dev)\n \t\tskb_linearize(skb);\n \n \tskb_tx_timestamp(skb);\n+\n+\tif (unlikely(READ_ONCE(peer_ns-\u003etstamp_config.rx_filter) !=\n+\t\t     HWTSTAMP_FILTER_NONE))\n+\t\tptp_info_rx = mock_phc_get_ptp_info(peer_ns-\u003ephc);\n+\n+\tif (unlikely(skb_shinfo(skb)-\u003etx_flags \u0026 SKBTX_HW_TSTAMP) \u0026\u0026\n+\t    READ_ONCE(ns-\u003etstamp_config.tx_type) == HWTSTAMP_TX_ON)\n+\t\tptp_info_tx = mock_phc_get_ptp_info(ns-\u003ephc);\n+\n+\tif (unlikely(ptp_info_tx || ptp_info_rx)) {\n+\t\t/* Sample both PHCs with IRQs off to keep the reads adjacent */\n+\t\tlocal_irq_save(flags);\n+\t\tif (ptp_info_tx)\n+\t\t\tptp_info_tx-\u003egettime64(ptp_info_tx, \u0026tx_ts);\n+\t\tif (ptp_info_rx)\n+\t\t\tptp_info_rx-\u003egettime64(ptp_info_rx, \u0026rx_ts);\n+\t\tlocal_irq_restore(flags);\n+\n+\t\t/* If TX hardware timestamping is enabled report TX timestamp */\n+\t\tif (ptp_info_tx) {\n+\t\t\tshhwtstamps.hwtstamp = timespec64_to_ktime(tx_ts);\n+\t\t\tskb_tstamp_tx(skb_orig, \u0026shhwtstamps);\n+\t\t}\n+\n+\t\t/* Unshare the skb, stamping it must not corrupt cloned copies\n+\t\t * and prevents returning single tstamp for Tx and Rx\n+\t\t */\n+\t\tskb = skb_unshare(skb_orig, GFP_ATOMIC);\n+\t\tif (unlikely(!skb)) {\n+\t\t\tif (psp_ext)\n+\t\t\t\t__skb_ext_put(psp_ext);\n+\t\t\tgoto out_drop_cnt;\n+\t\t}\n+\n+\t\t/* If RX hardware timestamping is enabled report RX timestamp */\n+\t\tif (ptp_info_rx)\n+\t\t\tskb_hwtstamps(skb)-\u003ehwtstamp =\n+\t\t\t\ttimespec64_to_ktime(rx_ts);\n+\t}\n+\n \tif (unlikely(nsim_forward_skb(dev, peer_dev,\n \t\t\t\t      skb, rq, psp_ext) == NET_RX_DROP))\n \t\tgoto out_drop_cnt;\n@@ -185,6 +233,63 @@ static netdev_tx_t nsim_start_xmit(struct sk_buff *skb, struct net_device *dev)\n \treturn NETDEV_TX_OK;\n }\n \n+static int nsim_set_ts_config(struct net_device *netdev,\n+\t\t\t      struct kernel_hwtstamp_config *config,\n+\t\t\t      struct netlink_ext_ack *extack)\n+{\n+\tstruct netdevsim *ns = netdev_priv(netdev);\n+\tint rx_filter;\n+\n+\tif (!ns-\u003ephc)\n+\t\treturn -EOPNOTSUPP;\n+\n+\tswitch (config-\u003erx_filter) {\n+\tcase HWTSTAMP_FILTER_NONE:\n+\t\trx_filter = HWTSTAMP_FILTER_NONE;\n+\t\tbreak;\n+\tcase HWTSTAMP_FILTER_PTP_V1_L4_EVENT:\n+\tcase HWTSTAMP_FILTER_PTP_V1_L4_SYNC:\n+\tcase HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ:\n+\tcase HWTSTAMP_FILTER_PTP_V2_EVENT:\n+\tcase HWTSTAMP_FILTER_PTP_V2_L4_EVENT:\n+\tcase HWTSTAMP_FILTER_PTP_V2_SYNC:\n+\tcase HWTSTAMP_FILTER_PTP_V2_L4_SYNC:\n+\tcase HWTSTAMP_FILTER_PTP_V2_DELAY_REQ:\n+\tcase HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ:\n+\tcase HWTSTAMP_FILTER_NTP_ALL:\n+\tcase HWTSTAMP_FILTER_ALL:\n+\t\trx_filter = HWTSTAMP_FILTER_ALL;\n+\t\tbreak;\n+\tdefault:\n+\t\treturn -ERANGE;\n+\t}\n+\n+\tswitch (config-\u003etx_type) {\n+\tcase HWTSTAMP_TX_OFF:\n+\t\tWRITE_ONCE(ns-\u003etstamp_config.tx_type, HWTSTAMP_TX_OFF);\n+\t\tbreak;\n+\tcase HWTSTAMP_TX_ON:\n+\t\tWRITE_ONCE(ns-\u003etstamp_config.tx_type, HWTSTAMP_TX_ON);\n+\t\tbreak;\n+\tdefault:\n+\t\treturn -ERANGE;\n+\t}\n+\n+\tWRITE_ONCE(ns-\u003etstamp_config.rx_filter, rx_filter);\n+\tconfig-\u003erx_filter = rx_filter;\n+\n+\treturn 0;\n+}\n+\n+static int nsim_get_ts_config(struct net_device *netdev,\n+\t\t\t      struct kernel_hwtstamp_config *config)\n+{\n+\tstruct netdevsim *ns = netdev_priv(netdev);\n+\n+\t*config = ns-\u003etstamp_config;\n+\treturn 0;\n+}\n+\n static int nsim_set_rx_mode(struct net_device *dev,\n \t\t\t    struct netdev_hw_addr_list *uc,\n \t\t\t    struct netdev_hw_addr_list *mc)\n@@ -647,6 +752,8 @@ static const struct net_device_ops nsim_netdev_ops = {\n \t.ndo_vlan_rx_add_vid\t= nsim_vlan_rx_add_vid,\n \t.ndo_vlan_rx_kill_vid\t= nsim_vlan_rx_kill_vid,\n \t.net_shaper_ops\t\t= \u0026nsim_shaper_ops,\n+\t.ndo_hwtstamp_get\t= nsim_get_ts_config,\n+\t.ndo_hwtstamp_set\t= nsim_set_ts_config,\n };\n \n static const struct net_device_ops nsim_vf_netdev_ops = {\ndiff --git a/drivers/net/netdevsim/netdevsim.h b/drivers/net/netdevsim/netdevsim.h\nindex 64f77f93d937c..5cdd1e294446c 100644\n--- a/drivers/net/netdevsim/netdevsim.h\n+++ b/drivers/net/netdevsim/netdevsim.h\n@@ -108,6 +108,7 @@ struct netdevsim {\n \tstruct net_device *netdev;\n \tstruct nsim_dev *nsim_dev;\n \tstruct nsim_dev_port *nsim_dev_port;\n+\tstruct kernel_hwtstamp_config tstamp_config;\n \tstruct mock_phc *phc;\n \tstruct nsim_rq **rq;\n \ndiff --git a/drivers/ptp/ptp_mock.c b/drivers/ptp/ptp_mock.c\nindex 4d66b61471210..7a4e5f3274a67 100644\n--- a/drivers/ptp/ptp_mock.c\n+++ b/drivers/ptp/ptp_mock.c\n@@ -49,15 +49,16 @@ static u64 mock_phc_cc_read(struct cyclecounter *cc)\n static int mock_phc_adjfine(struct ptp_clock_info *info, long scaled_ppm)\n {\n \tstruct mock_phc *phc = info_to_phc(info);\n+\tunsigned long flags;\n \ts64 adj;\n \n \tadj = (s64)scaled_ppm \u003c\u003c MOCK_PHC_FADJ_SHIFT;\n \tadj = div_s64(adj, MOCK_PHC_FADJ_DENOMINATOR);\n \n-\tspin_lock(\u0026phc-\u003elock);\n+\tspin_lock_irqsave(\u0026phc-\u003elock, flags);\n \ttimecounter_read(\u0026phc-\u003etc);\n \tphc-\u003ecc.mult = MOCK_PHC_CC_MULT + adj;\n-\tspin_unlock(\u0026phc-\u003elock);\n+\tspin_unlock_irqrestore(\u0026phc-\u003elock, flags);\n \n \treturn 0;\n }\n@@ -65,10 +66,11 @@ static int mock_phc_adjfine(struct ptp_clock_info *info, long scaled_ppm)\n static int mock_phc_adjtime(struct ptp_clock_info *info, s64 delta)\n {\n \tstruct mock_phc *phc = info_to_phc(info);\n+\tunsigned long flags;\n \n-\tspin_lock(\u0026phc-\u003elock);\n+\tspin_lock_irqsave(\u0026phc-\u003elock, flags);\n \ttimecounter_adjtime(\u0026phc-\u003etc, delta);\n-\tspin_unlock(\u0026phc-\u003elock);\n+\tspin_unlock_irqrestore(\u0026phc-\u003elock, flags);\n \n \treturn 0;\n }\n@@ -78,10 +80,11 @@ static int mock_phc_settime64(struct ptp_clock_info *info,\n {\n \tstruct mock_phc *phc = info_to_phc(info);\n \tu64 ns = timespec64_to_ns(ts);\n+\tunsigned long flags;\n \n-\tspin_lock(\u0026phc-\u003elock);\n+\tspin_lock_irqsave(\u0026phc-\u003elock, flags);\n \ttimecounter_init(\u0026phc-\u003etc, \u0026phc-\u003ecc, ns);\n-\tspin_unlock(\u0026phc-\u003elock);\n+\tspin_unlock_irqrestore(\u0026phc-\u003elock, flags);\n \n \treturn 0;\n }\n@@ -89,11 +92,12 @@ static int mock_phc_settime64(struct ptp_clock_info *info,\n static int mock_phc_gettime64(struct ptp_clock_info *info, struct timespec64 *ts)\n {\n \tstruct mock_phc *phc = info_to_phc(info);\n+\tunsigned long flags;\n \tu64 ns;\n \n-\tspin_lock(\u0026phc-\u003elock);\n+\tspin_lock_irqsave(\u0026phc-\u003elock, flags);\n \tns = timecounter_read(\u0026phc-\u003etc);\n-\tspin_unlock(\u0026phc-\u003elock);\n+\tspin_unlock_irqrestore(\u0026phc-\u003elock, flags);\n \n \t*ts = ns_to_timespec64(ns);\n \n@@ -171,5 +175,11 @@ void mock_phc_destroy(struct mock_phc *phc)\n }\n EXPORT_SYMBOL_GPL(mock_phc_destroy);\n \n+struct ptp_clock_info *mock_phc_get_ptp_info(struct mock_phc *phc)\n+{\n+\treturn \u0026phc-\u003einfo;\n+}\n+EXPORT_SYMBOL_GPL(mock_phc_get_ptp_info);\n+\n MODULE_DESCRIPTION(\"Mock-up PTP Hardware Clock driver\");\n MODULE_LICENSE(\"GPL\");\ndiff --git a/include/linux/ptp_mock.h b/include/linux/ptp_mock.h\nindex 72eb401034d93..e33188dec2b7f 100644\n--- a/include/linux/ptp_mock.h\n+++ b/include/linux/ptp_mock.h\n@@ -16,6 +16,7 @@ struct mock_phc;\n struct mock_phc *mock_phc_create(struct device *dev);\n void mock_phc_destroy(struct mock_phc *phc);\n int mock_phc_index(struct mock_phc *phc);\n+struct ptp_clock_info *mock_phc_get_ptp_info(struct mock_phc *phc);\n \n #else\n \n@@ -33,6 +34,10 @@ static inline int mock_phc_index(struct mock_phc *phc)\n \treturn -1;\n }\n \n+static inline struct ptp_clock_info *mock_phc_get_ptp_info(struct mock_phc *phc)\n+{\n+\treturn NULL;\n+}\n #endif\n \n #endif /* _PTP_MOCK_H_ */\ndiff --git a/tools/testing/selftests/drivers/net/Makefile b/tools/testing/selftests/drivers/net/Makefile\nindex d5bf4cb638a8c..18bb7c693b69a 100644\n--- a/tools/testing/selftests/drivers/net/Makefile\n+++ b/tools/testing/selftests/drivers/net/Makefile\n@@ -19,6 +19,7 @@ TEST_PROGS := \\\n \tnetpoll_basic.py \\\n \tping.py \\\n \tpsp.py \\\n+\tptp.py \\\n \tqueues.py \\\n \tring_reconfig.py \\\n \tshaper.py \\\ndiff --git a/tools/testing/selftests/drivers/net/config b/tools/testing/selftests/drivers/net/config\nindex b6989c7d3d9d1..7be30a72e1197 100644\n--- a/tools/testing/selftests/drivers/net/config\n+++ b/tools/testing/selftests/drivers/net/config\n@@ -21,5 +21,6 @@ CONFIG_NET_SCH_INGRESS=y\n CONFIG_NET_SCH_PRIO=m\n CONFIG_PPP=y\n CONFIG_PPPOE=y\n+CONFIG_PTP_1588_CLOCK_MOCK=y\n CONFIG_VLAN_8021Q=m\n CONFIG_XDP_SOCKETS=y\ndiff --git a/tools/testing/selftests/drivers/net/ptp.py b/tools/testing/selftests/drivers/net/ptp.py\nnew file mode 100755\nindex 0000000000000..57ea77659b117\n--- /dev/null\n+++ b/tools/testing/selftests/drivers/net/ptp.py\n@@ -0,0 +1,84 @@\n+#!/usr/bin/env python3\n+# SPDX-License-Identifier: GPL-2.0-only\n+#\n+# By Maciek Machnikowski \u003cmaciek@machnikowski.net\u003e (c) 2026,\n+\n+\"\"\"\n+Test suite for PTP sync using ptp4l.\n+\n+Start a ptp4l leader and follower and check that the follower locks onto the\n+leader (state s2)\n+\"\"\"\n+\n+import time\n+\n+from lib.py import (\n+    NetDrvEpEnv,\n+    bkg,\n+    fd_read_timeout,\n+    ksft_exit,\n+    ksft_pr,\n+    ksft_run,\n+    ksft_true,\n+)\n+\n+PTP4L_SYNC_TIMEOUT = 40\n+\n+\n+def _poll_follower_sync(follower, timeout):\n+    \"\"\"Read the follower stdout pipe until ptp4l reports sync state s2.\n+\n+    Returns a tuple (synced, output) where output is the text read so far.\n+    The synchronized ptp4l log line looks like this:\n+    ptp4l[18374.558]: master offset        844 s2 freq    +822 path delay       521\n+    \"\"\"\n+    fd_file = follower.proc.stdout\n+    fd = fd_file.fileno()\n+    buf = b\"\"\n+    deadline = time.monotonic() + timeout\n+    while time.monotonic() \u003c deadline:\n+        if b\" s2 \" in buf:\n+            break\n+        if follower.proc.poll() is not None:\n+            chunk = fd_file.read()\n+            if chunk:\n+                buf += chunk\n+            break\n+        try:\n+            remaining = deadline - time.monotonic()\n+            buf += fd_read_timeout(fd, max(0, min(1, remaining)))\n+        except TimeoutError:\n+            continue\n+    return b\" s2 \" in buf, buf.decode(\"utf-8\", \"replace\")\n+\n+\n+def ptp_sync_test(cfg):\n+    \"\"\"Verify ptp4l leader/follower synchronization reaches state s2.\"\"\"\n+    cfg.require_cmd(\"ptp4l\", remote=True)\n+\n+    leader_cmd = f\"ptp4l -i {cfg.remote_ifname} -m -2\"\n+    follower_cmd = f\"ptp4l -i {cfg.ifname} -m -s -2\"\n+\n+    with bkg(leader_cmd, host=cfg.remote), \\\n+         bkg(follower_cmd) as follower:\n+        synced, output = _poll_follower_sync(follower, PTP4L_SYNC_TIMEOUT)\n+\n+    if synced:\n+        return\n+\n+    ksft_pr(f\"ptp4l follower did not reach locked state (s2) within \"\n+            f\"{PTP4L_SYNC_TIMEOUT}s\")\n+    tail = output.strip().split(\"\\n\")[-10:]\n+    ksft_pr(\"Follower log (last 10 lines): \" + \" | \".join(tail))\n+    ksft_true(False, \"PTP sync timeout\")\n+\n+\n+def main():\n+    \"\"\"Run ksft tests.\"\"\"\n+    with NetDrvEpEnv(__file__) as cfg:\n+        ksft_run([ptp_sync_test], args=(cfg, ))\n+    ksft_exit()\n+\n+\n+if __name__ == \"__main__\":\n+    main()\n"
}

2/1 2026/08/13 22:53 agent patch-evaluator
0m Model:
best-expensive

Args:
null

Results:
{
  "EnableConfigs": [
    "NETDEVSIM",
    "PTP_1588_CLOCK_MOCK",
    "PTP_1588_CLOCK"
  ],
  "FocusSymbols": [
    "nsim_set_ts_config",
    "nsim_get_ts_config",
    "nsim_get_ts_info",
    "mock_phc_get_ptp_info"
  ],
  "Reasoning": "The patch adds hardware timestamping support to the netdevsim driver using the ptp_mock clock. This introduces new ioctl/ethtool entry points for configuring timestamping and modifies the TX path to sample the mock PHC. Since netdevsim is specifically designed for testing and fuzzing in virtualized environments, these changes are highly relevant and reachable for fuzzing.",
  "WorthFuzzing": true
}

Instruction:
You are an expert Linux kernel maintainer.
Your job is to review a provided patch series and determine
if it makes functional changes to the kernel that should be fuzzed.

IMPORTANT: The changes have ALREADY been applied and committed as the HEAD commit in
your workspace. Do NOT rely on your internal knowledge of the kernel. You must actively
use your code access tools to examine the actual source code and confirm any assumptions.

Return WorthFuzzing=false if the patch only contains:
- Modifications to Documentation/, Kconfig files, or code comments.
- Purely decorative changes, such as logging (e.g., pr_err, printk) or tracepoints.
- Changes to numeric constants or macros that do not functionally alter execution flow.
- Code paths that are impossible to reach in virtualized environments like GCE or QEMU,
  even when utilizing software-emulated hardware (e.g., usb gadget, mac80211_hwsim).
- Code in vendor-specific PCIe switch, SmartNIC, or GPU drivers (e.g., mlxsw, pds_core, qed,
  ionic, amdgpu) that require physical PCIe hardware cards not emulated in standard QEMU.
- Driver .remove, .shutdown, or pci_unregister_driver teardown callbacks (e.g., igb_remove)
  that are executed only during PCI hot-unplug or sysfs driver unbind operations.

If it modifies reachable core kernel logic, drivers, or architectures, use your code search
tools to verify the code can be executed, then return WorthFuzzing=true.

When returning WorthFuzzing=true, you MUST ALSO:
1. Extract any specific kernel functions that should be heavily fuzzed into FocusSymbols.
   Avoid listing generic hot-path functions to prevent skewed test distributions.
   Prefer non-static, non-inlined API entrypoint functions over internal static helper functions
   (which are inlined by the compiler and do not have distinct symbol addresses).
2. Identify any specific CONFIG_ options required to properly test this new/modified feature.
   Go and look into the Kconfig files and check for ifdefs around the code, do not make assumptions.
   Also check "depends on" lines in Kconfig to include any non-standard parent subsystem configs
   needed for Kbuild to compile the code statically into vmlinux. List them in the EnableConfigs
   output array, and DO NOT add a 'CONFIG_' prefix (e.g., return "NET_IPV4" instead of "CONFIG_NET_IPV4").
Prefer calling several tools at the same time to save round-trips.


Use set-results tool to provide results of the analysis.
It must be called exactly once before the final reply.
Ignore results of this tool.

Prompt:
For your convenience, here is the diff of the changes:
commit b6aea84e729d797211e4a5ec6cecd6ba02904bb8
Author: syz-cluster <triage@syzkaller.com>
Date:   Thu Aug 13 22:53:29 2026 +0000

    syz-cluster: applied patch under review

diff --git a/drivers/net/netdevsim/ethtool.c b/drivers/net/netdevsim/ethtool.c
index 025ea79879f3a..24e7d5592e799 100644
--- a/drivers/net/netdevsim/ethtool.c
+++ b/drivers/net/netdevsim/ethtool.c
@@ -200,7 +200,22 @@ static int nsim_get_ts_info(struct net_device *dev,
 {
 	struct netdevsim *ns = netdev_priv(dev);
 
+	ethtool_op_get_ts_info(dev, info);
+	if (!ns->phc) {
+		info->phc_index = -1;
+		return 0;
+	}
+
 	info->phc_index = mock_phc_index(ns->phc);
+	if (info->phc_index < 0)
+		return 0;
+
+	info->so_timestamping |= SOF_TIMESTAMPING_TX_HARDWARE |
+				 SOF_TIMESTAMPING_RX_HARDWARE |
+				 SOF_TIMESTAMPING_RAW_HARDWARE;
+
+	info->tx_types = BIT(HWTSTAMP_TX_OFF) | BIT(HWTSTAMP_TX_ON);
+	info->rx_filters = BIT(HWTSTAMP_FILTER_NONE) | BIT(HWTSTAMP_FILTER_ALL);
 
 	return 0;
 }
diff --git a/drivers/net/netdevsim/netdev.c b/drivers/net/netdevsim/netdev.c
index 4e9d7e10b527e..108f265a278a4 100644
--- a/drivers/net/netdevsim/netdev.c
+++ b/drivers/net/netdevsim/netdev.c
@@ -30,6 +30,8 @@
 #include <net/rtnetlink.h>
 #include <net/udp_tunnel.h>
 #include <net/busy_poll.h>
+#include <linux/ptp_clock_kernel.h>
+#include <linux/timecounter.h>
 
 #include "netdevsim.h"
 
@@ -122,12 +124,18 @@ static int nsim_forward_skb(struct net_device *tx_dev,
 
 static netdev_tx_t nsim_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
+	struct skb_shared_hwtstamps shhwtstamps = {};
+	struct ptp_clock_info *ptp_info_tx = NULL;
+	struct ptp_clock_info *ptp_info_rx = NULL;
 	struct netdevsim *ns = netdev_priv(dev);
+	struct timespec64 tx_ts, rx_ts;
+	struct sk_buff *skb_orig = skb;
 	struct skb_ext *psp_ext = NULL;
 	struct net_device *peer_dev;
 	unsigned int len = skb->len;
 	struct netdevsim *peer_ns;
 	struct netdev_config *cfg;
+	unsigned long flags;
 	struct nsim_rq *rq;
 	int rxq;
 	int dr;
@@ -164,6 +172,46 @@ static netdev_tx_t nsim_start_xmit(struct sk_buff *skb, struct net_device *dev)
 		skb_linearize(skb);
 
 	skb_tx_timestamp(skb);
+
+	if (unlikely(READ_ONCE(peer_ns->tstamp_config.rx_filter) !=
+		     HWTSTAMP_FILTER_NONE))
+		ptp_info_rx = mock_phc_get_ptp_info(peer_ns->phc);
+
+	if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) &&
+	    READ_ONCE(ns->tstamp_config.tx_type) == HWTSTAMP_TX_ON)
+		ptp_info_tx = mock_phc_get_ptp_info(ns->phc);
+
+	if (unlikely(ptp_info_tx || ptp_info_rx)) {
+		/* Sample both PHCs with IRQs off to keep the reads adjacent */
+		local_irq_save(flags);
+		if (ptp_info_tx)
+			ptp_info_tx->gettime64(ptp_info_tx, &tx_ts);
+		if (ptp_info_rx)
+			ptp_info_rx->gettime64(ptp_info_rx, &rx_ts);
+		local_irq_restore(flags);
+
+		/* If TX hardware timestamping is enabled report TX timestamp */
+		if (ptp_info_tx) {
+			shhwtstamps.hwtstamp = timespec64_to_ktime(tx_ts);
+			skb_tstamp_tx(skb_orig, &shhwtstamps);
+		}
+
+		/* Unshare the skb, stamping it must not corrupt cloned copies
+		 * and prevents returning single tstamp for Tx and Rx
+		 */
+		skb = skb_unshare(skb_orig, GFP_ATOMIC);
+		if (unlikely(!skb)) {
+			if (psp_ext)
+				__skb_ext_put(psp_ext);
+			goto out_drop_cnt;
+		}
+
+		/* If RX hardware timestamping is enabled report RX timestamp */
+		if (ptp_info_rx)
+			skb_hwtstamps(skb)->hwtstamp =
+				timespec64_to_ktime(rx_ts);
+	}
+
 	if (unlikely(nsim_forward_skb(dev, peer_dev,
 				      skb, rq, psp_ext) == NET_RX_DROP))
 		goto out_drop_cnt;
@@ -185,6 +233,63 @@ static netdev_tx_t nsim_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	return NETDEV_TX_OK;
 }
 
+static int nsim_set_ts_config(struct net_device *netdev,
+			      struct kernel_hwtstamp_config *config,
+			      struct netlink_ext_ack *extack)
+{
+	struct netdevsim *ns = netdev_priv(netdev);
+	int rx_filter;
+
+	if (!ns->phc)
+		return -EOPNOTSUPP;
+
+	switch (config->rx_filter) {
+	case HWTSTAMP_FILTER_NONE:
+		rx_filter = HWTSTAMP_FILTER_NONE;
+		break;
+	case HWTSTAMP_FILTER_PTP_V1_L4_EVENT:
+	case HWTSTAMP_FILTER_PTP_V1_L4_SYNC:
+	case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ:
+	case HWTSTAMP_FILTER_PTP_V2_EVENT:
+	case HWTSTAMP_FILTER_PTP_V2_L4_EVENT:
+	case HWTSTAMP_FILTER_PTP_V2_SYNC:
+	case HWTSTAMP_FILTER_PTP_V2_L4_SYNC:
+	case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ:
+	case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ:
+	case HWTSTAMP_FILTER_NTP_ALL:
+	case HWTSTAMP_FILTER_ALL:
+		rx_filter = HWTSTAMP_FILTER_ALL;
+		break;
+	default:
+		return -ERANGE;
+	}
+
+	switch (config->tx_type) {
+	case HWTSTAMP_TX_OFF:
+		WRITE_ONCE(ns->tstamp_config.tx_type, HWTSTAMP_TX_OFF);
+		break;
+	case HWTSTAMP_TX_ON:
+		WRITE_ONCE(ns->tstamp_config.tx_type, HWTSTAMP_TX_ON);
+		break;
+	default:
+		return -ERANGE;
+	}
+
+	WRITE_ONCE(ns->tstamp_config.rx_filter, rx_filter);
+	config->rx_filter = rx_filter;
+
+	return 0;
+}
+
+static int nsim_get_ts_config(struct net_device *netdev,
+			      struct kernel_hwtstamp_config *config)
+{
+	struct netdevsim *ns = netdev_priv(netdev);
+
+	*config = ns->tstamp_config;
+	return 0;
+}
+
 static int nsim_set_rx_mode(struct net_device *dev,
 			    struct netdev_hw_addr_list *uc,
 			    struct netdev_hw_addr_list *mc)
@@ -647,6 +752,8 @@ static const struct net_device_ops nsim_netdev_ops = {
 	.ndo_vlan_rx_add_vid	= nsim_vlan_rx_add_vid,
 	.ndo_vlan_rx_kill_vid	= nsim_vlan_rx_kill_vid,
 	.net_shaper_ops		= &nsim_shaper_ops,
+	.ndo_hwtstamp_get	= nsim_get_ts_config,
+	.ndo_hwtstamp_set	= nsim_set_ts_config,
 };
 
 static const struct net_device_ops nsim_vf_netdev_ops = {
diff --git a/drivers/net/netdevsim/netdevsim.h b/drivers/net/netdevsim/netdevsim.h
index 64f77f93d937c..5cdd1e294446c 100644
--- a/drivers/net/netdevsim/netdevsim.h
+++ b/drivers/net/netdevsim/netdevsim.h
@@ -108,6 +108,7 @@ struct netdevsim {
 	struct net_device *netdev;
 	struct nsim_dev *nsim_dev;
 	struct nsim_dev_port *nsim_dev_port;
+	struct kernel_hwtstamp_config tstamp_config;
 	struct mock_phc *phc;
 	struct nsim_rq **rq;
 
diff --git a/drivers/ptp/ptp_mock.c b/drivers/ptp/ptp_mock.c
index 4d66b61471210..7a4e5f3274a67 100644
--- a/drivers/ptp/ptp_mock.c
+++ b/drivers/ptp/ptp_mock.c
@@ -49,15 +49,16 @@ static u64 mock_phc_cc_read(struct cyclecounter *cc)
 static int mock_phc_adjfine(struct ptp_clock_info *info, long scaled_ppm)
 {
 	struct mock_phc *phc = info_to_phc(info);
+	unsigned long flags;
 	s64 adj;
 
 	adj = (s64)scaled_ppm << MOCK_PHC_FADJ_SHIFT;
 	adj = div_s64(adj, MOCK_PHC_FADJ_DENOMINATOR);
 
-	spin_lock(&phc->lock);
+	spin_lock_irqsave(&phc->lock, flags);
 	timecounter_read(&phc->tc);
 	phc->cc.mult = MOCK_PHC_CC_MULT + adj;
-	spin_unlock(&phc->lock);
+	spin_unlock_irqrestore(&phc->lock, flags);
 
 	return 0;
 }
@@ -65,10 +66,11 @@ static int mock_phc_adjfine(struct ptp_clock_info *info, long scaled_ppm)
 static int mock_phc_adjtime(struct ptp_clock_info *info, s64 delta)
 {
 	struct mock_phc *phc = info_to_phc(info);
+	unsigned long flags;
 
-	spin_lock(&phc->lock);
+	spin_lock_irqsave(&phc->lock, flags);
 	timecounter_adjtime(&phc->tc, delta);
-	spin_unlock(&phc->lock);
+	spin_unlock_irqrestore(&phc->lock, flags);
 
 	return 0;
 }
@@ -78,10 +80,11 @@ static int mock_phc_settime64(struct ptp_clock_info *info,
 {
 	struct mock_phc *phc = info_to_phc(info);
 	u64 ns = timespec64_to_ns(ts);
+	unsigned long flags;
 
-	spin_lock(&phc->lock);
+	spin_lock_irqsave(&phc->lock, flags);
 	timecounter_init(&phc->tc, &phc->cc, ns);
-	spin_unlock(&phc->lock);
+	spin_unlock_irqrestore(&phc->lock, flags);
 
 	return 0;
 }
@@ -89,11 +92,12 @@ static int mock_phc_settime64(struct ptp_clock_info *info,
 static int mock_phc_gettime64(struct ptp_clock_info *info, struct timespec64 *ts)
 {
 	struct mock_phc *phc = info_to_phc(info);
+	unsigned long flags;
 	u64 ns;
 
-	spin_lock(&phc->lock);
+	spin_lock_irqsave(&phc->lock, flags);
 	ns = timecounter_read(&phc->tc);
-	spin_unlock(&phc->lock);
+	spin_unlock_irqrestore(&phc->lock, flags);
 
 	*ts = ns_to_timespec64(ns);
 
@@ -171,5 +175,11 @@ void mock_phc_destroy(struct mock_phc *phc)
 }
 EXPORT_SYMBOL_GPL(mock_phc_destroy);
 
+struct ptp_clock_info *mock_phc_get_ptp_info(struct mock_phc *phc)
+{
+	return &phc->info;
+}
+EXPORT_SYMBOL_GPL(mock_phc_get_ptp_info);
+
 MODULE_DESCRIPTION("Mock-up PTP Hardware Clock driver");
 MODULE_LICENSE("GPL");
diff --git a/include/linux/ptp_mock.h b/include/linux/ptp_mock.h
index 72eb401034d93..e33188dec2b7f 100644
--- a/include/linux/ptp_mock.h
+++ b/include/linux/ptp_mock.h
@@ -16,6 +16,7 @@ struct mock_phc;
 struct mock_phc *mock_phc_create(struct device *dev);
 void mock_phc_destroy(struct mock_phc *phc);
 int mock_phc_index(struct mock_phc *phc);
+struct ptp_clock_info *mock_phc_get_ptp_info(struct mock_phc *phc);
 
 #else
 
@@ -33,6 +34,10 @@ static inline int mock_phc_index(struct mock_phc *phc)
 	return -1;
 }
 
+static inline struct ptp_clock_info *mock_phc_get_ptp_info(struct mock_phc *phc)
+{
+	return NULL;
+}
 #endif
 
 #endif /* _PTP_MOCK_H_ */
diff --git a/tools/testing/selftests/drivers/net/Makefile b/tools/testing/selftests/drivers/net/Makefile
index d5bf4cb638a8c..18bb7c693b69a 100644
--- a/tools/testing/selftests/drivers/net/Makefile
+++ b/tools/testing/selftests/drivers/net/Makefile
@@ -19,6 +19,7 @@ TEST_PROGS := \
 	netpoll_basic.py \
 	ping.py \
 	psp.py \
+	ptp.py \
 	queues.py \
 	ring_reconfig.py \
 	shaper.py \
diff --git a/tools/testing/selftests/drivers/net/config b/tools/testing/selftests/drivers/net/config
index b6989c7d3d9d1..7be30a72e1197 100644
--- a/tools/testing/selftests/drivers/net/config
+++ b/tools/testing/selftests/drivers/net/config
@@ -21,5 +21,6 @@ CONFIG_NET_SCH_INGRESS=y
 CONFIG_NET_SCH_PRIO=m
 CONFIG_PPP=y
 CONFIG_PPPOE=y
+CONFIG_PTP_1588_CLOCK_MOCK=y
 CONFIG_VLAN_8021Q=m
 CONFIG_XDP_SOCKETS=y
diff --git a/tools/testing/selftests/drivers/net/ptp.py b/tools/testing/selftests/drivers/net/ptp.py
new file mode 100755
index 0000000000000..57ea77659b117
--- /dev/null
+++ b/tools/testing/selftests/drivers/net/ptp.py
@@ -0,0 +1,84 @@
+#!/usr/bin/env python3
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# By Maciek Machnikowski <maciek@machnikowski.net> (c) 2026,
+
+"""
+Test suite for PTP sync using ptp4l.
+
+Start a ptp4l leader and follower and check that the follower locks onto the
+leader (state s2)
+"""
+
+import time
+
+from lib.py import (
+    NetDrvEpEnv,
+    bkg,
+    fd_read_timeout,
+    ksft_exit,
+    ksft_pr,
+    ksft_run,
+    ksft_true,
+)
+
+PTP4L_SYNC_TIMEOUT = 40
+
+
+def _poll_follower_sync(follower, timeout):
+    """Read the follower stdout pipe until ptp4l reports sync state s2.
+
+    Returns a tuple (synced, output) where output is the text read so far.
+    The synchronized ptp4l log line looks like this:
+    ptp4l[18374.558]: master offset        844 s2 freq    +822 path delay       521
+    """
+    fd_file = follower.proc.stdout
+    fd = fd_file.fileno()
+    buf = b""
+    deadline = time.monotonic() + timeout
+    while time.monotonic() < deadline:
+        if b" s2 " in buf:
+            break
+        if follower.proc.poll() is not None:
+            chunk = fd_file.read()
+            if chunk:
+                buf += chunk
+            break
+        try:
+            remaining = deadline - time.monotonic()
+            buf += fd_read_timeout(fd, max(0, min(1, remaining)))
+        except TimeoutError:
+            continue
+    return b" s2 " in buf, buf.decode("utf-8", "replace")
+
+
+def ptp_sync_test(cfg):
+    """Verify ptp4l leader/follower synchronization reaches state s2."""
+    cfg.require_cmd("ptp4l", remote=True)
+
+    leader_cmd = f"ptp4l -i {cfg.remote_ifname} -m -2"
+    follower_cmd = f"ptp4l -i {cfg.ifname} -m -s -2"
+
+    with bkg(leader_cmd, host=cfg.remote), \
+         bkg(follower_cmd) as follower:
+        synced, output = _poll_follower_sync(follower, PTP4L_SYNC_TIMEOUT)
+
+    if synced:
+        return
+
+    ksft_pr(f"ptp4l follower did not reach locked state (s2) within "
+            f"{PTP4L_SYNC_TIMEOUT}s")
+    tail = output.strip().split("\n")[-10:]
+    ksft_pr("Follower log (last 10 lines): " + " | ".join(tail))
+    ksft_true(False, "PTP sync timeout")
+
+
+def main():
+    """Run ksft tests."""
+    with NetDrvEpEnv(__file__) as cfg:
+        ksft_run([ptp_sync_test], args=(cfg, ))
+    ksft_exit()
+
+
+if __name__ == "__main__":
+    main()

3/2 2026/08/13 22:53 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 7211
							output: 35
							thoughts: 443
						

Thoughts:
**My Assessment of the Netdevsim Hardware Timestamping Patch**

Okay, so I've got a patch here that's adding hardware timestamping to `netdevsim`, which is a neat little software-emulated network device. This is interesting because `netdevsim` is a prime target for testing and fuzzing, especially in virtualized environments – exactly the use case it was designed for. We're leveraging `ptp_mock` to achieve this timestamping, which seems like a sensible approach.

The patch touches a handful of key files: `ethtool.c`, `netdev.c`, `netdevsim.h`, `ptp_mock.c`, `ptp_mock.h`, and adds a test in `ptp.py`. Specifically, it looks like:

*   We're adding `nsim_get_ts_info` to `ethtool.c`. This is where we will inspect timestamping information.
*   `nsim_start_xmit` in `netdev.c` is getting the timestamping logic. This will be an important function to test.
*   We have `nsim_set_ts_config` and `nsim_get_ts_config` added to `netdev.c` for configuring timestamping. These are certainly important.
*   On the `ptp_mock` side, we have `mock_phc_get_ptp_info` in `ptp_mock.c`.
*   And finally, `ndo_hwtstamp_get` and `ndo_hwtstamp_set` in `nsim_netdev_ops` handle the timestamping operations.

Given the nature of the changes, this definitely warrants fuzzing. The integration with `ptp_mock` is a good sign, and the potential for corner cases in emulated environments always exists. My initial focus for fuzzing will be on those config/get/info functions: `nsim_set_ts_config`, `nsim_get_ts_config`, `nsim_get_ts_info`, and `mock_phc_get_ptp_info`. Understanding the config interaction with `ptp_mock` will be critical, as well as testing to ensure the timing aspects are well-behaved.

I'll check the kernel configs to see which ones are relevant. I'll be looking for `CONFIG_NETDEVSIM` and `CONFIG_PTP_1588_CLOCK_MOCK` to be enabled, and I'll also verify the dependencies and configurations in the `Kconfig` files for both `netdevsim` and `ptp` to make sure everything's set up correctly. This will help determine the correct targets for fuzzing and if the new code interacts correctly with the existing configuration options.



4/2 2026/08/13 22:53 tool grepper
0m Error:
no matches

Args:
{
  "Expression": "config NETDEVSIM",
  "PathPrefix": "drivers/net/netdevsim/Kconfig"
}

Results:
{
  "error": "no matches"
}

5/2 2026/08/13 22:53 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 8308
							output: 25
							thoughts: 42
						

Thoughts:
Okay, here's my take on those thoughts, framed as an expert's internal monologue:

**Investigating a Kconfig File**

Hmm, that's odd. The path I'm looking at, specifically `drivers/net/netdevsim/Kconfig`, doesn't seem to be present. That's a classic situation. I need to quickly determine the correct location or the existence of the relevant configuration options.

My first thought is to broaden the search. Perhaps the functionality has been refactored or moved. Let me immediately check the parent directory, `drivers/net/Kconfig`, to see if a more general configuration is present. If it's not there, then my next step is to examine the specific directory again, `drivers/net/netdevsim/`, to make sure I am not missing a file by misreading the file. It's possible I am looking at the wrong branch or version. I'll make sure to double check that too, but my gut feeling is that something may have changed in the Kconfig structure.



6/2 2026/08/13 22:53 tool codesearch-dir-index
0m Args:
{
  "Dir": "drivers/net/netdevsim"
}

Results:
{
  "Files": [
    "bpf.c",
    "bus.c",
    "dev.c",
    "ethtool.c",
    "fib.c",
    "health.c",
    "hwstats.c",
    "ipsec.c",
    "macsec.c",
    "netdev.c",
    "netdevsim.h",
    "psample.c",
    "psp.c",
    "tc.c",
    "udp_tunnels.c"
  ],
  "Subdirs": null
}

7/2 2026/08/13 22:53 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 8714
							output: 29
							thoughts: 18
						

Thoughts:
Okay, here's my summary, in the first person, as an expert in my field, based on the provided thought:

**Navigating the Driver Landscape**

Okay, so I'm thinking about where to find the configuration options for this network driver. My intuition's telling me that the relevant `Kconfig` file, the one that defines the build-time configuration options, is likely located within the `drivers/net/` directory of the kernel source, specifically as `Kconfig`. That's the most logical place, given the driver's purpose. It's the standard convention, and I'd be surprised if it were anywhere else. I'll start my search there.



8/2 2026/08/13 22:53 tool grepper
0m Args:
{
  "Expression": "config NETDEVSIM",
  "PathPrefix": "drivers/net/"
}

Results:
{
  "Output": "drivers/net/Kconfig=602=source \"drivers/net/hyperv/Kconfig\"\ndrivers/net/Kconfig-603-\ndrivers/net/Kconfig:604:config NETDEVSIM\ndrivers/net/Kconfig-605-\ttristate \"Simulated networking device\"\n"
}

9/2 2026/08/13 22:53 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 8994
							output: 38
							thoughts: 18
						

Thoughts:
Okay, here's my attempt at summarizing that thought process, keeping in mind I'm speaking to a fellow expert:

**Investigating `PTP_1588_CLOCK_MOCK`**

Alright, time to dive in. Let's start by taking a look at `PTP_1588_CLOCK_MOCK`. I need to figure out what's going on with this thing. What's the status of the module, and what functions does it have at its disposal? Specifically, is it up and running as a clock, or is it behaving as it should as a mock. What interfaces does it expose, and what dependencies does it have? What kind of tests have been run against this component, and do those results suggest any potential pitfalls that warrant immediate scrutiny? Does the mocking behavior align with the defined requirements and expected outcomes for this particular scenario? Ultimately, I need to understand its role within the larger system and how it interacts with other components, as a mock will affect dependencies as defined in the system. Let's see what we can dig up.



10/2 2026/08/13 22:53 tool grepper
0m Args:
{
  "Expression": "config PTP_1588_CLOCK_MOCK",
  "PathPrefix": "drivers/ptp/"
}

Results:
{
  "Output": "drivers/ptp/Kconfig=175=config PTP_1588_CLOCK_FC3W\n--\ndrivers/ptp/Kconfig-186-\ndrivers/ptp/Kconfig:187:config PTP_1588_CLOCK_MOCK\ndrivers/ptp/Kconfig-188-\ttristate \"Mock-up PTP clock\"\n"
}

11/2 2026/08/13 22:53 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 9382
							output: 35
							thoughts: 21
						

Thoughts:
Here's my take on the dependencies of `PTP_1588_CLOCK_MOCK`, from my perspective:

**Deep Dive into `PTP_1588_CLOCK_MOCK` Dependencies**

Okay, time to get a handle on this `PTP_1588_CLOCK_MOCK` module. I need to understand its relationship to the rest of the system, what other pieces it leans on, and potentially, what might break if something *it* relies on changes. We're talking dependencies, plain and simple.

First, I need to check the build system – what does the makefile or build scripts tell me? Are there specific include paths I should be aware of? This will point me towards the header files it's incorporating and potentially, the libraries it's linked against. I'm looking for clues about where the rubber meets the road here.

Then, a quick scan of the code itself. I'll search for `#include` directives, naturally. But beyond that, I'm thinking about function calls. What functions are *used* by the mock? Are they from internal modules, external libraries, or some custom API? What headers do those functions originate from? Do any of them touch the hardware abstraction layer, or networking stack?

I'll be mindful of any resource locks or shared data. Is there any potential for race conditions or unintended side effects if the mock interacts with other parts of the codebase? Dependency analysis goes beyond just files; it includes behavior and data flow, too.

I'm also looking for any assumptions this module makes about the environment it's running in. Is it assuming a particular hardware platform? A specific network configuration? If it relies on a specific timer interrupt frequency, or a particular PTP profile, I need to know about that.

Essentially, I want a complete map: a clear understanding of the input, processing and output of `PTP_1588_CLOCK_MOCK` and how it plugs into the grand scheme of things. Once I have *that*, I can confidently reason about its impact, test its behavior, and, ultimately, make informed decisions.



12/2 2026/08/13 22:53 tool read-file
0m Args:
{
  "File": "drivers/ptp/Kconfig",
  "FirstLine": 180,
  "LineCount": 20
}

Results:
{
  "Contents": " 180:\t\t  This driver adds support for using Renesas FemtoClock3 Wireless\n 181:\t\t  as a PTP clock. This clock is only useful if your time stamping\n 182:\t\t  MAC is connected to the RENESAS chip.\n 183:\t\n 184:\t\t  To compile this driver as a module, choose M here: the module\n 185:\t\t  will be called ptp_fc3.\n 186:\t\n 187:\tconfig PTP_1588_CLOCK_MOCK\n 188:\t\ttristate \"Mock-up PTP clock\"\n 189:\t\tdepends on PTP_1588_CLOCK\n 190:\t\thelp\n 191:\t\t  This driver offers a set of PTP clock manipulation operations over\n 192:\t\t  the system monotonic time. It can be used by virtual network device\n 193:\t\t  drivers to emulate PTP capabilities.\n 194:\t\n 195:\t\t  To compile this driver as a module, choose M here: the module\n 196:\t\t  will be called ptp_mock.\n 197:\t\n 198:\tconfig PTP_1588_CLOCK_VMW\n 199:\t\ttristate \"VMware virtual PTP clock\"\n"
}

13/2 2026/08/13 22:53 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 10229
							output: 34
							thoughts: 41
						

Thoughts:
Okay, here's my interpretation of those thoughts, summarized from my perspective as someone deeply involved in this area:

**Analyzing Dependencies for `PTP_1588_CLOCK_MOCK`**

Alright, I see it clearly: `PTP_1588_CLOCK_MOCK` is built on top of `PTP_1588_CLOCK`. That's not surprising; the mock is supposed to *simulate* the behavior of the real clock, so it naturally relies on the core clock functionality. Now, I need to understand how the whole system is interconnected. So, my next logical step is to dive into the dependencies of `NETDEVSIM`. Knowing what `NETDEVSIM` relies upon will give me a more complete picture of how `PTP_1588_CLOCK_MOCK` fits into the broader simulation framework, and how changes in one area might ripple through others. It's time to map those relationships.



14/2 2026/08/13 22:53 tool read-file
0m Args:
{
  "File": "drivers/net/Kconfig",
  "FirstLine": 600,
  "LineCount": 20
}

Results:
{
  "Contents": " 600:\t\n 601:\tsource \"drivers/net/thunderbolt/Kconfig\"\n 602:\tsource \"drivers/net/hyperv/Kconfig\"\n 603:\t\n 604:\tconfig NETDEVSIM\n 605:\t\ttristate \"Simulated networking device\"\n 606:\t\tdepends on DEBUG_FS\n 607:\t\tdepends on INET\n 608:\t\tdepends on PSAMPLE || PSAMPLE=n\n 609:\t\tdepends on PTP_1588_CLOCK_MOCK || PTP_1588_CLOCK_MOCK=n\n 610:\t\tselect NET_DEVLINK\n 611:\t\tselect PAGE_POOL\n 612:\t\tselect NET_SHAPER\n 613:\t\thelp\n 614:\t\t  This driver is a developer testing tool and software model that can\n 615:\t\t  be used to test various control path networking APIs, especially\n 616:\t\t  HW-offload related.\n 617:\t\n 618:\t\t  To compile this driver as a module, choose M here: the module\n 619:\t\t  will be called netdevsim.\n"
}

15/2 2026/08/13 22:53 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 10817
							output: 41
							thoughts: 509
						

Thoughts:
**Analyzing the Dependencies and Implementation of NETDEVSIM Time Stamping**

Okay, so `NETDEVSIM`'s time stamping functionality hinges on `PTP_1588_CLOCK_MOCK`, which makes sense. Therefore, to ensure everything's enabled, I need to enable all three: `NETDEVSIM`, `PTP_1588_CLOCK_MOCK`, and `PTP_1588_CLOCK`. Simple enough.

Now, let's dive into the core functions that handle this: `nsim_get_ts_info`, `nsim_set_ts_config`, `nsim_get_ts_config`, and `mock_phc_get_ptp_info`. My first thought is to check their visibility – are they static or exported?

A quick scan reveals:
*   `nsim_get_ts_info` is static in `ethtool.c`.
*   `nsim_set_ts_config` and `nsim_get_ts_config` are static in `netdev.c`.
*   `mock_phc_get_ptp_info` is exported in `ptp_mock.c`.

A slight snag. The instructions generally prefer non-static, exported API functions. However, on closer inspection, `nsim_get_ts_info`, `nsim_set_ts_config`, and `nsim_get_ts_config` are actually the implementation for `ethtool_ops` and `net_device_ops`, the *entry points* for the time stamping feature. They're static, but they are the *entrypoints* for the feature. They are *the* functions.

Let me be sure these are static. A quick check of `ethtool.c` confirms that `nsim_get_ts_info` is indeed static, but crucially, it's assigned to `ethtool_ops.get_ts_info`, as expected. So, while I am usually wary of static functions with the same name if they are used to build up `FocusSymbols`, this is not a concern here.

Alright, *that's* settled. I think I have a clear picture.



16/2 2026/08/13 22:54 tool grepper
0m Args:
{
  "Expression": "nsim_get_ts_info",
  "PathPrefix": "drivers/net/netdevsim/ethtool.c"
}

Results:
{
  "Output": "drivers/net/netdevsim/ethtool.c=176=nsim_get_fec_stats(struct net_device *dev, struct ethtool_fec_stats *fec_stats,\n--\ndrivers/net/netdevsim/ethtool.c-197-\ndrivers/net/netdevsim/ethtool.c:198:static int nsim_get_ts_info(struct net_device *dev,\ndrivers/net/netdevsim/ethtool.c-199-\t\t\t    struct kernel_ethtool_ts_info *info)\n--\ndrivers/net/netdevsim/ethtool.c=223=static const struct ethtool_ops nsim_ethtool_ops = {\n--\ndrivers/net/netdevsim/ethtool.c-239-\t.get_fec_stats\t\t\t= nsim_get_fec_stats,\ndrivers/net/netdevsim/ethtool.c:240:\t.get_ts_info\t\t\t= nsim_get_ts_info,\ndrivers/net/netdevsim/ethtool.c-241-};\n"
}

17/2 2026/08/13 22:54 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 12143
							output: 40
							thoughts: 350
						

Thoughts:
**My Thought Process on Identifying Key API Functions**

Okay, so I'm looking at these functions and trying to figure out which ones are the most important for exposing as APIs, especially for the new feature. First instinct: they're mostly static, but *is* there anything non-static? Aha, `mock_phc_get_ptp_info` is non-static! Excellent.

I briefly considered `nsim_start_xmit`, since that's the TX hot path, but it's *static*, and that's not what the prompt wants me to prioritize. Then I thought about the other mock functions like the adjtime functions, but those are all static and assigned to `ptp_clock_info` so those are internal.

But, hang on... `mock_phc_get_ptp_info` is actually exported. That's a key function for this specific mock implementation. That's good.

If I want to highlight the new feature specifically, I could just mention `mock_phc_get_ptp_info`. But, I also know I should consider those static ones, like `nsim_set_ts_config`, `nsim_get_ts_config`, and `nsim_get_ts_info`, since they're the only entrypoints.

The prompt does say to prefer non-static, so the static ones seem to be less desirable, but maybe I can include `nsim_set_ts_config` because it's the *only* entrypoint. Okay, let's list those.

So, I think the functions I should be prioritizing are:
`nsim_set_ts_config`
`nsim_get_ts_config`
`nsim_get_ts_info`
`mock_phc_get_ptp_info`

Just going to quickly double check that `nsim_set_ts_config` is indeed static.



18/2 2026/08/13 22:54 tool grepper
0m Args:
{
  "Expression": "nsim_set_ts_config",
  "PathPrefix": "drivers/net/netdevsim/netdev.c"
}

Results:
{
  "Output": "drivers/net/netdevsim/netdev.c=125=static netdev_tx_t nsim_start_xmit(struct sk_buff *skb, struct net_device *dev)\n--\ndrivers/net/netdevsim/netdev.c-235-\ndrivers/net/netdevsim/netdev.c:236:static int nsim_set_ts_config(struct net_device *netdev,\ndrivers/net/netdevsim/netdev.c-237-\t\t\t      struct kernel_hwtstamp_config *config,\n--\ndrivers/net/netdevsim/netdev.c=732=static const struct net_device_ops nsim_netdev_ops = {\n--\ndrivers/net/netdevsim/netdev.c-755-\t.ndo_hwtstamp_get\t= nsim_get_ts_config,\ndrivers/net/netdevsim/netdev.c:756:\t.ndo_hwtstamp_set\t= nsim_set_ts_config,\ndrivers/net/netdevsim/netdev.c-757-};\n"
}

19/2 2026/08/13 22:54 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 13235
							output: 186
							thoughts: 353
						

Thoughts:
**My Configuration Checklist**

Okay, so I've got a set of configurations here, it looks like they're static and I need to keep track of what's going on with them. Let's make a list.

The primary configs are `NETDEVSIM`, `PTP_1588_CLOCK_MOCK`, and `PTP_1588_CLOCK`. I need to figure out if `PTP_1588_CLOCK` is even *required*. Ah, right, `PTP_1588_CLOCK_MOCK` depends on it, so yes, it's definitely needed.

Now, are there any other related configurations? I see that `NETDEVSIM` has dependencies on `DEBUG_FS`, `INET`, and `PSAMPLE`. `INET` and `DEBUG_FS` are pretty standard so those should be fine. Okay, with all of that in mind I should add `NETDEVSIM`, `PTP_1588_CLOCK_MOCK`, and `PTP_1588_CLOCK`.

I need to quickly review the changes in `drivers/ptp/ptp_mock.c`. It looks like the patch is adding `spin_lock_irqsave` and `spin_unlock_irqrestore` to the static functions `mock_phc_adjfine`, `mock_phc_adjtime`, `mock_phc_settime64`, and `mock_phc_gettime64`. It's also adding `mock_phc_get_ptp_info`.

I'll also make sure to add `mock_phc_get_ptp_info`, `nsim_set_ts_config`, `nsim_get_ts_config`, and `nsim_get_ts_info` to `FocusSymbols`.

Alright, I think that's everything. Time to call `set-results`.



20/2 2026/08/13 22:54 tool set-results
0m Args:
{
  "EnableConfigs": [
    "NETDEVSIM",
    "PTP_1588_CLOCK_MOCK",
    "PTP_1588_CLOCK"
  ],
  "FocusSymbols": [
    "nsim_set_ts_config",
    "nsim_get_ts_config",
    "nsim_get_ts_info",
    "mock_phc_get_ptp_info"
  ],
  "Reasoning": "The patch adds hardware timestamping support to the netdevsim driver using the ptp_mock clock. This introduces new ioctl/ethtool entry points for configuring timestamping and modifies the TX path to sample the mock PHC. Since netdevsim is specifically designed for testing and fuzzing in virtualized environments, these changes are highly relevant and reachable for fuzzing.",
  "WorthFuzzing": true
}

Results:
{
  "EnableConfigs": [
    "NETDEVSIM",
    "PTP_1588_CLOCK_MOCK",
    "PTP_1588_CLOCK"
  ],
  "FocusSymbols": [
    "nsim_set_ts_config",
    "nsim_get_ts_config",
    "nsim_get_ts_info",
    "mock_phc_get_ptp_info"
  ],
  "Reasoning": "The patch adds hardware timestamping support to the netdevsim driver using the ptp_mock clock. This introduces new ioctl/ethtool entry points for configuring timestamping and modifies the TX path to sample the mock PHC. Since netdevsim is specifically designed for testing and fuzzing in virtualized environments, these changes are highly relevant and reachable for fuzzing.",
  "WorthFuzzing": true
}

21/1 2026/08/13 22:54 action If
4m Args:
{
  "WorthFuzzing": true
}

Results:
null

22/2 2026/08/13 22:54 agent kmsan-evaluator
4m Model:
best-expensive

Args:
null

Results:
{
  "KMSANReasoning": "The patch adds hardware timestamping support to the `netdevsim` driver. It introduces `nsim_get_ts_info`, `nsim_set_ts_config`, and `nsim_get_ts_config` to configure timestamping, and modifies `nsim_start_xmit` to sample the mock PTP clock and attach timestamps to the skb.\n\nAnalysis of potential uninitialized memory risks:\n1. `nsim_get_ts_info` populates a `struct kernel_ethtool_ts_info`. This structure is fully zeroed by `ethtool_init_tsinfo` in the ethtool core before `ops-\u003eget_ts_info` is called. The driver only modifies specific fields, leaving no uninitialized memory.\n2. `nsim_get_ts_config` copies `ns-\u003etstamp_config` to a `struct kernel_hwtstamp_config`. `ns-\u003etstamp_config` is zero-initialized when the `netdevsim` private data is allocated via `alloc_netdev` (which uses `kvzalloc`). The core ioctl handler (`dev_get_hwtstamp`) then copies the relevant fields to a `struct hwtstamp_config` (which has no padding) before copying it to user space. No uninitialized memory is leaked.\n3. In `nsim_start_xmit`, `tx_ts` and `rx_ts` are populated by `mock_phc_gettime64`, which uses `ns_to_timespec64` to return a fully initialized `struct timespec64`.\n4. The `struct skb_shared_hwtstamps` attached to the skb is zero-initialized (`= {}`) before the `hwtstamp` field is assigned, preventing any uninitialized memory from being attached to the packet.\n\nSince all structures sent to user space or attached to packets are fully initialized, this patch does not introduce any uninitialized memory risks or info-leaks. Standard KASAN and LOCKDEP are sufficient to detect any potential memory corruption or locking issues.",
  "NeedsKMSAN": false
}

Instruction:
You are an expert Linux kernel security engineer specializing in kernel memory
error detectors (KASAN and KMSAN). Your job is to review the provided patch series and
determine if the code changes justify spawning a dedicated KMSAN (KernelMemorySanitizer)
fuzzing session in addition to standard KASAN fuzzing.

CRITICAL DISTINCTION BETWEEN KASAN AND KMSAN:
- Standard KASAN kernel builds (upstream-apparmor-kasan.config) already enable
  a comprehensive suite of debugging tools and sanitizers, including KASAN
  (out-of-bounds accesses, use-after-free, double free, invalid free), LOCKDEP
  (locking bugs and deadlocks), UB-sanitizers, and memory corruption checks.
- KMSAN (KernelMemorySanitizer) detects reads of UNINITIALIZED memory (stack, heap,
  or page allocations) and kernel-to-user memory info-leaks.

Rule: THERE IS NO SENSE IN RUNNING A KMSAN SESSION IF A BUG CAN BE CAUGHT BY KASAN,
LOCKDEP, OR OTHER STANDARD BUG DETECTORS.
A dedicated KMSAN fuzzing session incurs significant resource costs. You must ONLY
set NeedsKMSAN=true if the code changes introduce or expose UNINITIALIZED MEMORY risks
that are detected ONLY by KMSAN.

Look holistically at the patch series and surrounding code. Even if no direct
uninitialized field accesses or new buffer allocations are added in the diff itself,
a patch may alter control flow, bounds checking, or data length calculations in ways
that change how the rest of the code operates on existing buffers (e.g. allowing
uninitialized stack/heap memory to be read, copied to user space, or used in control
flow). Do not hesitate to use your code access tools to inspect the surrounding code,
called functions, and callers.

Set NeedsKMSAN=true ONLY IF the patch introduces or modifies:
1. Kernel structures sent to user space (via copy_to_user, put_user, netlink skb
   attributes, ioctl output arguments, socket options, or BPF buffers) where fields
   or structure padding might not be fully initialized/zeroed.
2. Conditional logic or branching that depends on potentially uninitialized variables
   or struct fields.
3. Allocation or initialization of complex data structures where uninitialized fields
   could be read later in reachable code paths.
4. Bounds checks, lengths, or logic in a way that allows surrounding code to access
   uninitialized bytes of existing buffers.

Set NeedsKMSAN=false IF:
- The code changes primarily risk out-of-bounds access, array overflows, NULL pointer
  dereferences, locking deadlocks, or use-after-free bugs (these are already caught
  by KASAN, LOCKDEP, or standard bug detectors).
- All stack/heap structures touched or introduced by the patch are fully zeroed
  or initialized (e.g. using = {0}, memset, kzalloc) before being read or copied.
- The patch does not introduce any risk of uninitialized memory usage or info-leaks.

Use your code access tools to inspect the surrounding code if necessary, then provide
detailed KMSANReasoning contrasting KASAN vs KMSAN applicability for this patch.
Prefer calling several tools at the same time to save round-trips.


Use set-results tool to provide results of the analysis.
It must be called exactly once before the final reply.
Ignore results of this tool.

Prompt:
For your convenience, here is the diff of the changes:
commit b6aea84e729d797211e4a5ec6cecd6ba02904bb8
Author: syz-cluster <triage@syzkaller.com>
Date:   Thu Aug 13 22:53:29 2026 +0000

    syz-cluster: applied patch under review

diff --git a/drivers/net/netdevsim/ethtool.c b/drivers/net/netdevsim/ethtool.c
index 025ea79879f3a..24e7d5592e799 100644
--- a/drivers/net/netdevsim/ethtool.c
+++ b/drivers/net/netdevsim/ethtool.c
@@ -200,7 +200,22 @@ static int nsim_get_ts_info(struct net_device *dev,
 {
 	struct netdevsim *ns = netdev_priv(dev);
 
+	ethtool_op_get_ts_info(dev, info);
+	if (!ns->phc) {
+		info->phc_index = -1;
+		return 0;
+	}
+
 	info->phc_index = mock_phc_index(ns->phc);
+	if (info->phc_index < 0)
+		return 0;
+
+	info->so_timestamping |= SOF_TIMESTAMPING_TX_HARDWARE |
+				 SOF_TIMESTAMPING_RX_HARDWARE |
+				 SOF_TIMESTAMPING_RAW_HARDWARE;
+
+	info->tx_types = BIT(HWTSTAMP_TX_OFF) | BIT(HWTSTAMP_TX_ON);
+	info->rx_filters = BIT(HWTSTAMP_FILTER_NONE) | BIT(HWTSTAMP_FILTER_ALL);
 
 	return 0;
 }
diff --git a/drivers/net/netdevsim/netdev.c b/drivers/net/netdevsim/netdev.c
index 4e9d7e10b527e..108f265a278a4 100644
--- a/drivers/net/netdevsim/netdev.c
+++ b/drivers/net/netdevsim/netdev.c
@@ -30,6 +30,8 @@
 #include <net/rtnetlink.h>
 #include <net/udp_tunnel.h>
 #include <net/busy_poll.h>
+#include <linux/ptp_clock_kernel.h>
+#include <linux/timecounter.h>
 
 #include "netdevsim.h"
 
@@ -122,12 +124,18 @@ static int nsim_forward_skb(struct net_device *tx_dev,
 
 static netdev_tx_t nsim_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
+	struct skb_shared_hwtstamps shhwtstamps = {};
+	struct ptp_clock_info *ptp_info_tx = NULL;
+	struct ptp_clock_info *ptp_info_rx = NULL;
 	struct netdevsim *ns = netdev_priv(dev);
+	struct timespec64 tx_ts, rx_ts;
+	struct sk_buff *skb_orig = skb;
 	struct skb_ext *psp_ext = NULL;
 	struct net_device *peer_dev;
 	unsigned int len = skb->len;
 	struct netdevsim *peer_ns;
 	struct netdev_config *cfg;
+	unsigned long flags;
 	struct nsim_rq *rq;
 	int rxq;
 	int dr;
@@ -164,6 +172,46 @@ static netdev_tx_t nsim_start_xmit(struct sk_buff *skb, struct net_device *dev)
 		skb_linearize(skb);
 
 	skb_tx_timestamp(skb);
+
+	if (unlikely(READ_ONCE(peer_ns->tstamp_config.rx_filter) !=
+		     HWTSTAMP_FILTER_NONE))
+		ptp_info_rx = mock_phc_get_ptp_info(peer_ns->phc);
+
+	if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) &&
+	    READ_ONCE(ns->tstamp_config.tx_type) == HWTSTAMP_TX_ON)
+		ptp_info_tx = mock_phc_get_ptp_info(ns->phc);
+
+	if (unlikely(ptp_info_tx || ptp_info_rx)) {
+		/* Sample both PHCs with IRQs off to keep the reads adjacent */
+		local_irq_save(flags);
+		if (ptp_info_tx)
+			ptp_info_tx->gettime64(ptp_info_tx, &tx_ts);
+		if (ptp_info_rx)
+			ptp_info_rx->gettime64(ptp_info_rx, &rx_ts);
+		local_irq_restore(flags);
+
+		/* If TX hardware timestamping is enabled report TX timestamp */
+		if (ptp_info_tx) {
+			shhwtstamps.hwtstamp = timespec64_to_ktime(tx_ts);
+			skb_tstamp_tx(skb_orig, &shhwtstamps);
+		}
+
+		/* Unshare the skb, stamping it must not corrupt cloned copies
+		 * and prevents returning single tstamp for Tx and Rx
+		 */
+		skb = skb_unshare(skb_orig, GFP_ATOMIC);
+		if (unlikely(!skb)) {
+			if (psp_ext)
+				__skb_ext_put(psp_ext);
+			goto out_drop_cnt;
+		}
+
+		/* If RX hardware timestamping is enabled report RX timestamp */
+		if (ptp_info_rx)
+			skb_hwtstamps(skb)->hwtstamp =
+				timespec64_to_ktime(rx_ts);
+	}
+
 	if (unlikely(nsim_forward_skb(dev, peer_dev,
 				      skb, rq, psp_ext) == NET_RX_DROP))
 		goto out_drop_cnt;
@@ -185,6 +233,63 @@ static netdev_tx_t nsim_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	return NETDEV_TX_OK;
 }
 
+static int nsim_set_ts_config(struct net_device *netdev,
+			      struct kernel_hwtstamp_config *config,
+			      struct netlink_ext_ack *extack)
+{
+	struct netdevsim *ns = netdev_priv(netdev);
+	int rx_filter;
+
+	if (!ns->phc)
+		return -EOPNOTSUPP;
+
+	switch (config->rx_filter) {
+	case HWTSTAMP_FILTER_NONE:
+		rx_filter = HWTSTAMP_FILTER_NONE;
+		break;
+	case HWTSTAMP_FILTER_PTP_V1_L4_EVENT:
+	case HWTSTAMP_FILTER_PTP_V1_L4_SYNC:
+	case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ:
+	case HWTSTAMP_FILTER_PTP_V2_EVENT:
+	case HWTSTAMP_FILTER_PTP_V2_L4_EVENT:
+	case HWTSTAMP_FILTER_PTP_V2_SYNC:
+	case HWTSTAMP_FILTER_PTP_V2_L4_SYNC:
+	case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ:
+	case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ:
+	case HWTSTAMP_FILTER_NTP_ALL:
+	case HWTSTAMP_FILTER_ALL:
+		rx_filter = HWTSTAMP_FILTER_ALL;
+		break;
+	default:
+		return -ERANGE;
+	}
+
+	switch (config->tx_type) {
+	case HWTSTAMP_TX_OFF:
+		WRITE_ONCE(ns->tstamp_config.tx_type, HWTSTAMP_TX_OFF);
+		break;
+	case HWTSTAMP_TX_ON:
+		WRITE_ONCE(ns->tstamp_config.tx_type, HWTSTAMP_TX_ON);
+		break;
+	default:
+		return -ERANGE;
+	}
+
+	WRITE_ONCE(ns->tstamp_config.rx_filter, rx_filter);
+	config->rx_filter = rx_filter;
+
+	return 0;
+}
+
+static int nsim_get_ts_config(struct net_device *netdev,
+			      struct kernel_hwtstamp_config *config)
+{
+	struct netdevsim *ns = netdev_priv(netdev);
+
+	*config = ns->tstamp_config;
+	return 0;
+}
+
 static int nsim_set_rx_mode(struct net_device *dev,
 			    struct netdev_hw_addr_list *uc,
 			    struct netdev_hw_addr_list *mc)
@@ -647,6 +752,8 @@ static const struct net_device_ops nsim_netdev_ops = {
 	.ndo_vlan_rx_add_vid	= nsim_vlan_rx_add_vid,
 	.ndo_vlan_rx_kill_vid	= nsim_vlan_rx_kill_vid,
 	.net_shaper_ops		= &nsim_shaper_ops,
+	.ndo_hwtstamp_get	= nsim_get_ts_config,
+	.ndo_hwtstamp_set	= nsim_set_ts_config,
 };
 
 static const struct net_device_ops nsim_vf_netdev_ops = {
diff --git a/drivers/net/netdevsim/netdevsim.h b/drivers/net/netdevsim/netdevsim.h
index 64f77f93d937c..5cdd1e294446c 100644
--- a/drivers/net/netdevsim/netdevsim.h
+++ b/drivers/net/netdevsim/netdevsim.h
@@ -108,6 +108,7 @@ struct netdevsim {
 	struct net_device *netdev;
 	struct nsim_dev *nsim_dev;
 	struct nsim_dev_port *nsim_dev_port;
+	struct kernel_hwtstamp_config tstamp_config;
 	struct mock_phc *phc;
 	struct nsim_rq **rq;
 
diff --git a/drivers/ptp/ptp_mock.c b/drivers/ptp/ptp_mock.c
index 4d66b61471210..7a4e5f3274a67 100644
--- a/drivers/ptp/ptp_mock.c
+++ b/drivers/ptp/ptp_mock.c
@@ -49,15 +49,16 @@ static u64 mock_phc_cc_read(struct cyclecounter *cc)
 static int mock_phc_adjfine(struct ptp_clock_info *info, long scaled_ppm)
 {
 	struct mock_phc *phc = info_to_phc(info);
+	unsigned long flags;
 	s64 adj;
 
 	adj = (s64)scaled_ppm << MOCK_PHC_FADJ_SHIFT;
 	adj = div_s64(adj, MOCK_PHC_FADJ_DENOMINATOR);
 
-	spin_lock(&phc->lock);
+	spin_lock_irqsave(&phc->lock, flags);
 	timecounter_read(&phc->tc);
 	phc->cc.mult = MOCK_PHC_CC_MULT + adj;
-	spin_unlock(&phc->lock);
+	spin_unlock_irqrestore(&phc->lock, flags);
 
 	return 0;
 }
@@ -65,10 +66,11 @@ static int mock_phc_adjfine(struct ptp_clock_info *info, long scaled_ppm)
 static int mock_phc_adjtime(struct ptp_clock_info *info, s64 delta)
 {
 	struct mock_phc *phc = info_to_phc(info);
+	unsigned long flags;
 
-	spin_lock(&phc->lock);
+	spin_lock_irqsave(&phc->lock, flags);
 	timecounter_adjtime(&phc->tc, delta);
-	spin_unlock(&phc->lock);
+	spin_unlock_irqrestore(&phc->lock, flags);
 
 	return 0;
 }
@@ -78,10 +80,11 @@ static int mock_phc_settime64(struct ptp_clock_info *info,
 {
 	struct mock_phc *phc = info_to_phc(info);
 	u64 ns = timespec64_to_ns(ts);
+	unsigned long flags;
 
-	spin_lock(&phc->lock);
+	spin_lock_irqsave(&phc->lock, flags);
 	timecounter_init(&phc->tc, &phc->cc, ns);
-	spin_unlock(&phc->lock);
+	spin_unlock_irqrestore(&phc->lock, flags);
 
 	return 0;
 }
@@ -89,11 +92,12 @@ static int mock_phc_settime64(struct ptp_clock_info *info,
 static int mock_phc_gettime64(struct ptp_clock_info *info, struct timespec64 *ts)
 {
 	struct mock_phc *phc = info_to_phc(info);
+	unsigned long flags;
 	u64 ns;
 
-	spin_lock(&phc->lock);
+	spin_lock_irqsave(&phc->lock, flags);
 	ns = timecounter_read(&phc->tc);
-	spin_unlock(&phc->lock);
+	spin_unlock_irqrestore(&phc->lock, flags);
 
 	*ts = ns_to_timespec64(ns);
 
@@ -171,5 +175,11 @@ void mock_phc_destroy(struct mock_phc *phc)
 }
 EXPORT_SYMBOL_GPL(mock_phc_destroy);
 
+struct ptp_clock_info *mock_phc_get_ptp_info(struct mock_phc *phc)
+{
+	return &phc->info;
+}
+EXPORT_SYMBOL_GPL(mock_phc_get_ptp_info);
+
 MODULE_DESCRIPTION("Mock-up PTP Hardware Clock driver");
 MODULE_LICENSE("GPL");
diff --git a/include/linux/ptp_mock.h b/include/linux/ptp_mock.h
index 72eb401034d93..e33188dec2b7f 100644
--- a/include/linux/ptp_mock.h
+++ b/include/linux/ptp_mock.h
@@ -16,6 +16,7 @@ struct mock_phc;
 struct mock_phc *mock_phc_create(struct device *dev);
 void mock_phc_destroy(struct mock_phc *phc);
 int mock_phc_index(struct mock_phc *phc);
+struct ptp_clock_info *mock_phc_get_ptp_info(struct mock_phc *phc);
 
 #else
 
@@ -33,6 +34,10 @@ static inline int mock_phc_index(struct mock_phc *phc)
 	return -1;
 }
 
+static inline struct ptp_clock_info *mock_phc_get_ptp_info(struct mock_phc *phc)
+{
+	return NULL;
+}
 #endif
 
 #endif /* _PTP_MOCK_H_ */
diff --git a/tools/testing/selftests/drivers/net/Makefile b/tools/testing/selftests/drivers/net/Makefile
index d5bf4cb638a8c..18bb7c693b69a 100644
--- a/tools/testing/selftests/drivers/net/Makefile
+++ b/tools/testing/selftests/drivers/net/Makefile
@@ -19,6 +19,7 @@ TEST_PROGS := \
 	netpoll_basic.py \
 	ping.py \
 	psp.py \
+	ptp.py \
 	queues.py \
 	ring_reconfig.py \
 	shaper.py \
diff --git a/tools/testing/selftests/drivers/net/config b/tools/testing/selftests/drivers/net/config
index b6989c7d3d9d1..7be30a72e1197 100644
--- a/tools/testing/selftests/drivers/net/config
+++ b/tools/testing/selftests/drivers/net/config
@@ -21,5 +21,6 @@ CONFIG_NET_SCH_INGRESS=y
 CONFIG_NET_SCH_PRIO=m
 CONFIG_PPP=y
 CONFIG_PPPOE=y
+CONFIG_PTP_1588_CLOCK_MOCK=y
 CONFIG_VLAN_8021Q=m
 CONFIG_XDP_SOCKETS=y
diff --git a/tools/testing/selftests/drivers/net/ptp.py b/tools/testing/selftests/drivers/net/ptp.py
new file mode 100755
index 0000000000000..57ea77659b117
--- /dev/null
+++ b/tools/testing/selftests/drivers/net/ptp.py
@@ -0,0 +1,84 @@
+#!/usr/bin/env python3
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# By Maciek Machnikowski <maciek@machnikowski.net> (c) 2026,
+
+"""
+Test suite for PTP sync using ptp4l.
+
+Start a ptp4l leader and follower and check that the follower locks onto the
+leader (state s2)
+"""
+
+import time
+
+from lib.py import (
+    NetDrvEpEnv,
+    bkg,
+    fd_read_timeout,
+    ksft_exit,
+    ksft_pr,
+    ksft_run,
+    ksft_true,
+)
+
+PTP4L_SYNC_TIMEOUT = 40
+
+
+def _poll_follower_sync(follower, timeout):
+    """Read the follower stdout pipe until ptp4l reports sync state s2.
+
+    Returns a tuple (synced, output) where output is the text read so far.
+    The synchronized ptp4l log line looks like this:
+    ptp4l[18374.558]: master offset        844 s2 freq    +822 path delay       521
+    """
+    fd_file = follower.proc.stdout
+    fd = fd_file.fileno()
+    buf = b""
+    deadline = time.monotonic() + timeout
+    while time.monotonic() < deadline:
+        if b" s2 " in buf:
+            break
+        if follower.proc.poll() is not None:
+            chunk = fd_file.read()
+            if chunk:
+                buf += chunk
+            break
+        try:
+            remaining = deadline - time.monotonic()
+            buf += fd_read_timeout(fd, max(0, min(1, remaining)))
+        except TimeoutError:
+            continue
+    return b" s2 " in buf, buf.decode("utf-8", "replace")
+
+
+def ptp_sync_test(cfg):
+    """Verify ptp4l leader/follower synchronization reaches state s2."""
+    cfg.require_cmd("ptp4l", remote=True)
+
+    leader_cmd = f"ptp4l -i {cfg.remote_ifname} -m -2"
+    follower_cmd = f"ptp4l -i {cfg.ifname} -m -s -2"
+
+    with bkg(leader_cmd, host=cfg.remote), \
+         bkg(follower_cmd) as follower:
+        synced, output = _poll_follower_sync(follower, PTP4L_SYNC_TIMEOUT)
+
+    if synced:
+        return
+
+    ksft_pr(f"ptp4l follower did not reach locked state (s2) within "
+            f"{PTP4L_SYNC_TIMEOUT}s")
+    tail = output.strip().split("\n")[-10:]
+    ksft_pr("Follower log (last 10 lines): " + " | ".join(tail))
+    ksft_true(False, "PTP sync timeout")
+
+
+def main():
+    """Run ksft tests."""
+    with NetDrvEpEnv(__file__) as cfg:
+        ksft_run([ptp_sync_test], args=(cfg, ))
+    ksft_exit()
+
+
+if __name__ == "__main__":
+    main()

23/3 2026/08/13 22:54 llm kmsan-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 7208
							output: 21
							thoughts: 870
						

Thoughts:
**Hardware Timestamping in `netdevsim` - A Deep Dive**

Okay, so this patch is adding hardware timestamping support to the `netdevsim` driver. My initial assessment is that it's a solid enhancement, but I need to understand the details to evaluate its completeness and potential implications.

Let's break down the key modifications. First, `nsim_get_ts_info` is being updated to report the driver's timestamping capabilities, which is the logical starting point. Then, `nsim_start_xmit` now samples the PTP clock to attach hardware timestamps to the skb during transmission. This is where the core functionality resides.  The addition of `nsim_set_ts_config` and `nsim_get_ts_config` is crucial. It lets userspace control and query the timestamping configuration, which is essential for any practical use case.  Finally, the update to `ptp_mock.c` is important to consider; using `spin_lock_irqsave` instead of `spin_lock` suggests a careful approach to ensure correct synchronization in an interrupt context, but I need to confirm the impact.

Now, let's zoom in on `nsim_start_xmit`. The code snippet you've provided is the key to understanding how timestamps are attached to the packets. The `shhwtstamps` struct, which contains hwtstamp metadata, is initialized to zero. Then, `tx_ts` and `rx_ts` are populated using `ptp_info_tx->gettime64` and `ptp_info_rx->gettime64`. The conditional logic indicates that timestamps are attached based on the presence of `ptp_info_tx` or `ptp_info_rx`, which is expected. The critical part is that the timestamp is converted to `ktime_t` and attached to the skb using `skb_tstamp_tx`.  This is standard practice. The use of `ptp_info_tx` and `ptp_info_rx` implies that the driver is designed to work with both transmit and receive timestamping, and the logic is structured to handle this.

Next, I need to check how `nsim_set_ts_config` and `nsim_get_ts_config` actually work.  `nsim_get_ts_config` simply copies the contents of `ns->tstamp_config` (a `struct kernel_hwtstamp_config`) to the user-supplied `config` buffer. This is fairly standard. I need to be sure the struct is properly initialized on the driver side, as it's the source for user-space configuration.  The private data is zero-initialized via `alloc_netdev`, so `ns->tstamp_config` should have sensible defaults, but I will review the defaults to confirm. I should also track where this structure is used in user space and which functions call `nsim_get_ts_config`, looking at `dev_get_hwtstamp_phylib`, `dev_get_hwtstamp` and `generic_hwtstamp_get` in `net/core/dev_ioctl.c` and `net/core/timestamping.c`. This will give me a better understanding of how the configuration is exposed to and used by user-space applications.



24/3 2026/08/13 22:54 tool grepper
0m Args:
{
  "Expression": "ndo_hwtstamp_get"
}

Results:
{
  "Output": "\nFull output is too long, showing 500 out of 541 lines.\nUse more precise expression if possible.\n\nDocumentation/networking/timestamping.rst=631=the actual values as described in the section on SIOCSHWTSTAMP. It\nDocumentation/networking/timestamping.rst:632:should also support ndo_hwtstamp_get NDO to retrieve configuration.\nDocumentation/networking/timestamping.rst-633-\n--\nDocumentation/translations/zh_CN/networking/timestamping.rst=513=ioctl 并更新提供的 struct hwtstamp_config 与实际值,如 SIOCSHWTSTAMP 部分\nDocumentation/translations/zh_CN/networking/timestamping.rst:514:所述。它还应支持 ndo_hwtstamp_get 或遗留 SIOCGHWTSTAMP。\nDocumentation/translations/zh_CN/networking/timestamping.rst-515-\n--\ndrivers/infiniband/ulp/ipoib/ipoib_main.c=1829=static int ipoib_hwtstamp_get(struct net_device *dev,\n--\ndrivers/infiniband/ulp/ipoib/ipoib_main.c-1833-\ndrivers/infiniband/ulp/ipoib/ipoib_main.c:1834:\tif (!priv-\u003ern_ops-\u003endo_hwtstamp_get)\ndrivers/infiniband/ulp/ipoib/ipoib_main.c-1835-\t\treturn -EOPNOTSUPP;\ndrivers/infiniband/ulp/ipoib/ipoib_main.c-1836-\ndrivers/infiniband/ulp/ipoib/ipoib_main.c:1837:\treturn priv-\u003ern_ops-\u003endo_hwtstamp_get(dev, config);\ndrivers/infiniband/ulp/ipoib/ipoib_main.c-1838-}\n--\ndrivers/infiniband/ulp/ipoib/ipoib_main.c=2157=static const struct net_device_ops ipoib_netdev_ops_pf = {\n--\ndrivers/infiniband/ulp/ipoib/ipoib_main.c-2175-\t.ndo_eth_ioctl\t\t = ipoib_ioctl,\ndrivers/infiniband/ulp/ipoib/ipoib_main.c:2176:\t.ndo_hwtstamp_get\t = ipoib_hwtstamp_get,\ndrivers/infiniband/ulp/ipoib/ipoib_main.c-2177-\t.ndo_hwtstamp_set\t = ipoib_hwtstamp_set,\n--\ndrivers/infiniband/ulp/ipoib/ipoib_main.c=2180=static const struct net_device_ops ipoib_netdev_ops_vf = {\n--\ndrivers/infiniband/ulp/ipoib/ipoib_main.c-2192-\t.ndo_eth_ioctl\t\t = ipoib_ioctl,\ndrivers/infiniband/ulp/ipoib/ipoib_main.c:2193:\t.ndo_hwtstamp_get\t = ipoib_hwtstamp_get,\ndrivers/infiniband/ulp/ipoib/ipoib_main.c-2194-\t.ndo_hwtstamp_set\t = ipoib_hwtstamp_set,\n--\ndrivers/net/bonding/bond_main.c=5944=static const struct net_device_ops bond_netdev_ops = {\n--\ndrivers/net/bonding/bond_main.c-5975-\t.ndo_xdp_get_xmit_slave = bond_xdp_get_xmit_slave,\ndrivers/net/bonding/bond_main.c:5976:\t.ndo_hwtstamp_get\t= bond_hwtstamp_get,\ndrivers/net/bonding/bond_main.c-5977-\t.ndo_hwtstamp_set\t= bond_hwtstamp_set,\n--\ndrivers/net/can/dev/dev.c=424=EXPORT_SYMBOL_GPL(can_set_static_ctrlmode);\ndrivers/net/can/dev/dev.c-425-\ndrivers/net/can/dev/dev.c:426:/* generic implementation of netdev_ops::ndo_hwtstamp_get for CAN devices\ndrivers/net/can/dev/dev.c-427- * supporting hardware timestamps\n--\ndrivers/net/can/esd/esd_402_pci-core.c=85=static const struct net_device_ops pci402_acc_netdev_ops = {\n--\ndrivers/net/can/esd/esd_402_pci-core.c-88-\t.ndo_start_xmit = acc_start_xmit,\ndrivers/net/can/esd/esd_402_pci-core.c:89:\t.ndo_hwtstamp_get = can_hwtstamp_get,\ndrivers/net/can/esd/esd_402_pci-core.c-90-\t.ndo_hwtstamp_set = can_hwtstamp_set,\n--\ndrivers/net/can/kvaser_pciefd/kvaser_pciefd_core.c=902=static const struct net_device_ops kvaser_pciefd_netdev_ops = {\n--\ndrivers/net/can/kvaser_pciefd/kvaser_pciefd_core.c-905-\t.ndo_start_xmit = kvaser_pciefd_start_xmit,\ndrivers/net/can/kvaser_pciefd/kvaser_pciefd_core.c:906:\t.ndo_hwtstamp_get = can_hwtstamp_get,\ndrivers/net/can/kvaser_pciefd/kvaser_pciefd_core.c-907-\t.ndo_hwtstamp_set = can_hwtstamp_set,\n--\ndrivers/net/can/peak_canfd/peak_canfd.c=767=static const struct net_device_ops peak_canfd_netdev_ops = {\n--\ndrivers/net/can/peak_canfd/peak_canfd.c-770-\t.ndo_start_xmit = peak_canfd_start_xmit,\ndrivers/net/can/peak_canfd/peak_canfd.c:771:\t.ndo_hwtstamp_get = peak_eth_hwtstamp_get,\ndrivers/net/can/peak_canfd/peak_canfd.c-772-\t.ndo_hwtstamp_set = peak_eth_hwtstamp_set,\n--\ndrivers/net/can/spi/mcp251xfd/mcp251xfd-core.c=1732=static const struct net_device_ops mcp251xfd_netdev_ops = {\n--\ndrivers/net/can/spi/mcp251xfd/mcp251xfd-core.c-1735-\t.ndo_start_xmit\t= mcp251xfd_start_xmit,\ndrivers/net/can/spi/mcp251xfd/mcp251xfd-core.c:1736:\t.ndo_hwtstamp_get = can_hwtstamp_get,\ndrivers/net/can/spi/mcp251xfd/mcp251xfd-core.c-1737-\t.ndo_hwtstamp_set = can_hwtstamp_set,\n--\ndrivers/net/can/usb/etas_es58x/es58x_core.c=1980=static const struct net_device_ops es58x_netdev_ops = {\n--\ndrivers/net/can/usb/etas_es58x/es58x_core.c-1983-\t.ndo_start_xmit = es58x_start_xmit,\ndrivers/net/can/usb/etas_es58x/es58x_core.c:1984:\t.ndo_hwtstamp_get = can_hwtstamp_get,\ndrivers/net/can/usb/etas_es58x/es58x_core.c-1985-\t.ndo_hwtstamp_set = can_hwtstamp_set,\n--\ndrivers/net/can/usb/gs_usb.c=1208=static const struct net_device_ops gs_usb_netdev_ops = {\n--\ndrivers/net/can/usb/gs_usb.c-1211-\t.ndo_start_xmit = gs_can_start_xmit,\ndrivers/net/can/usb/gs_usb.c:1212:\t.ndo_hwtstamp_get = gs_can_hwtstamp_get,\ndrivers/net/can/usb/gs_usb.c-1213-\t.ndo_hwtstamp_set = gs_can_hwtstamp_set,\n--\ndrivers/net/can/usb/kvaser_usb/kvaser_usb_core.c=791=static const struct net_device_ops kvaser_usb_netdev_ops = {\n--\ndrivers/net/can/usb/kvaser_usb/kvaser_usb_core.c-794-\t.ndo_start_xmit = kvaser_usb_start_xmit,\ndrivers/net/can/usb/kvaser_usb/kvaser_usb_core.c:795:\t.ndo_hwtstamp_get = can_hwtstamp_get,\ndrivers/net/can/usb/kvaser_usb/kvaser_usb_core.c-796-\t.ndo_hwtstamp_set = can_hwtstamp_set,\n--\ndrivers/net/can/usb/peak_usb/pcan_usb_core.c=807=static const struct net_device_ops peak_usb_netdev_ops = {\n--\ndrivers/net/can/usb/peak_usb/pcan_usb_core.c-810-\t.ndo_start_xmit = peak_usb_ndo_start_xmit,\ndrivers/net/can/usb/peak_usb/pcan_usb_core.c:811:\t.ndo_hwtstamp_get = peak_hwtstamp_get,\ndrivers/net/can/usb/peak_usb/pcan_usb_core.c-812-\t.ndo_hwtstamp_set = peak_hwtstamp_set,\n--\ndrivers/net/ethernet/amd/xgbe/xgbe-drv.c=2037=static const struct net_device_ops xgbe_netdev_ops = {\n--\ndrivers/net/ethernet/amd/xgbe/xgbe-drv.c-2055-\t.ndo_features_check\t= xgbe_features_check,\ndrivers/net/ethernet/amd/xgbe/xgbe-drv.c:2056:\t.ndo_hwtstamp_get\t= xgbe_get_hwtstamp_settings,\ndrivers/net/ethernet/amd/xgbe/xgbe-drv.c-2057-\t.ndo_hwtstamp_set\t= xgbe_set_hwtstamp_settings,\n--\ndrivers/net/ethernet/aquantia/atlantic/aq_main.c=459=static const struct net_device_ops aq_ndev_ops = {\n--\ndrivers/net/ethernet/aquantia/atlantic/aq_main.c-472-\t.ndo_xdp_xmit = aq_xdp_xmit,\ndrivers/net/ethernet/aquantia/atlantic/aq_main.c:473:\t.ndo_hwtstamp_get = aq_ndev_hwtstamp_get,\ndrivers/net/ethernet/aquantia/atlantic/aq_main.c-474-\t.ndo_hwtstamp_set = aq_ndev_hwtstamp_set,\n--\ndrivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c=13007=static const struct net_device_ops bnx2x_netdev_ops = {\n--\ndrivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c-13035-\t.ndo_features_check\t= bnx2x_features_check,\ndrivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c:13036:\t.ndo_hwtstamp_get\t= bnx2x_hwtstamp_get,\ndrivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c-13037-\t.ndo_hwtstamp_set\t= bnx2x_hwtstamp_set,\n--\ndrivers/net/ethernet/broadcom/bnxt/bnxt.c=16076=static const struct net_device_ops bnxt_netdev_ops = {\n--\ndrivers/net/ethernet/broadcom/bnxt/bnxt.c-16106-\t.ndo_bridge_setlink\t= bnxt_bridge_setlink,\ndrivers/net/ethernet/broadcom/bnxt/bnxt.c:16107:\t.ndo_hwtstamp_get\t= bnxt_hwtstamp_get,\ndrivers/net/ethernet/broadcom/bnxt/bnxt.c-16108-\t.ndo_hwtstamp_set\t= bnxt_hwtstamp_set,\n--\ndrivers/net/ethernet/broadcom/tg3.c=14368=static const struct net_device_ops tg3_netdev_ops = {\n--\ndrivers/net/ethernet/broadcom/tg3.c-14383-#endif\ndrivers/net/ethernet/broadcom/tg3.c:14384:\t.ndo_hwtstamp_get\t= tg3_hwtstamp_get,\ndrivers/net/ethernet/broadcom/tg3.c-14385-\t.ndo_hwtstamp_set\t= tg3_hwtstamp_set,\n--\ndrivers/net/ethernet/cadence/macb_main.c=4549=static const struct net_device_ops macb_netdev_ops = {\n--\ndrivers/net/ethernet/cadence/macb_main.c-4564-\t.ndo_hwtstamp_set\t= macb_hwtstamp_set,\ndrivers/net/ethernet/cadence/macb_main.c:4565:\t.ndo_hwtstamp_get\t= macb_hwtstamp_get,\ndrivers/net/ethernet/cadence/macb_main.c-4566-\t.ndo_setup_tc\t\t= macb_setup_tc,\n--\ndrivers/net/ethernet/cadence/macb_main.c=5274=static const struct net_device_ops at91ether_netdev_ops = {\n--\ndrivers/net/ethernet/cadence/macb_main.c-5286-\t.ndo_hwtstamp_set\t= macb_hwtstamp_set,\ndrivers/net/ethernet/cadence/macb_main.c:5287:\t.ndo_hwtstamp_get\t= macb_hwtstamp_get,\ndrivers/net/ethernet/cadence/macb_main.c-5288-};\n--\ndrivers/net/ethernet/cavium/liquidio/lio_main.c=3205=static const struct net_device_ops lionetdevops = {\n--\ndrivers/net/ethernet/cavium/liquidio/lio_main.c-3226-\t.ndo_get_port_parent_id\t= liquidio_get_port_parent_id,\ndrivers/net/ethernet/cavium/liquidio/lio_main.c:3227:\t.ndo_hwtstamp_get\t= liquidio_hwtstamp_get,\ndrivers/net/ethernet/cavium/liquidio/lio_main.c-3228-\t.ndo_hwtstamp_set\t= liquidio_hwtstamp_set,\n--\ndrivers/net/ethernet/cavium/liquidio/lio_vf_main.c=1859=static const struct net_device_ops lionetdevops = {\n--\ndrivers/net/ethernet/cavium/liquidio/lio_vf_main.c-1871-\t.ndo_set_features\t= liquidio_set_features,\ndrivers/net/ethernet/cavium/liquidio/lio_vf_main.c:1872:\t.ndo_hwtstamp_get\t= liquidio_hwtstamp_get,\ndrivers/net/ethernet/cavium/liquidio/lio_vf_main.c-1873-\t.ndo_hwtstamp_set\t= liquidio_hwtstamp_set,\n--\ndrivers/net/ethernet/cavium/octeon/octeon_mgmt.c=1367=static const struct net_device_ops octeon_mgmt_ops = {\n--\ndrivers/net/ethernet/cavium/octeon/octeon_mgmt.c-1377-#endif\ndrivers/net/ethernet/cavium/octeon/octeon_mgmt.c:1378:\t.ndo_hwtstamp_get =\t\tocteon_mgmt_hwtstamp_get,\ndrivers/net/ethernet/cavium/octeon/octeon_mgmt.c-1379-\t.ndo_hwtstamp_set =\t\tocteon_mgmt_hwtstamp_set,\n--\ndrivers/net/ethernet/cavium/thunder/nicvf_main.c=2077=static const struct net_device_ops nicvf_netdev_ops = {\n--\ndrivers/net/ethernet/cavium/thunder/nicvf_main.c-2088-\t.ndo_set_rx_mode        = nicvf_set_rx_mode,\ndrivers/net/ethernet/cavium/thunder/nicvf_main.c:2089:\t.ndo_hwtstamp_get\t= nicvf_hwtstamp_get,\ndrivers/net/ethernet/cavium/thunder/nicvf_main.c-2090-\t.ndo_hwtstamp_set\t= nicvf_hwtstamp_set,\n--\ndrivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c=3855=static const struct net_device_ops cxgb4_netdev_ops = {\n--\ndrivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c-3877-\t.ndo_fix_features     = cxgb_fix_features,\ndrivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c:3878:\t.ndo_hwtstamp_get     = cxgb_hwtstamp_get,\ndrivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c-3879-\t.ndo_hwtstamp_set     = cxgb_hwtstamp_set,\n--\ndrivers/net/ethernet/engleder/tsnep_main.c=2371=static const struct net_device_ops tsnep_netdev_ops = {\n--\ndrivers/net/ethernet/engleder/tsnep_main.c-2384-\t.ndo_xsk_wakeup = tsnep_netdev_xsk_wakeup,\ndrivers/net/ethernet/engleder/tsnep_main.c:2385:\t.ndo_hwtstamp_get = tsnep_ptp_hwtstamp_get,\ndrivers/net/ethernet/engleder/tsnep_main.c-2386-\t.ndo_hwtstamp_set = tsnep_ptp_hwtstamp_set,\n--\ndrivers/net/ethernet/freescale/dpaa/dpaa_eth.c=3145=static const struct net_device_ops dpaa_ops = {\n--\ndrivers/net/ethernet/freescale/dpaa/dpaa_eth.c-3158-\t.ndo_xdp_xmit = dpaa_xdp_xmit,\ndrivers/net/ethernet/freescale/dpaa/dpaa_eth.c:3159:\t.ndo_hwtstamp_get = dpaa_hwtstamp_get,\ndrivers/net/ethernet/freescale/dpaa/dpaa_eth.c-3160-\t.ndo_hwtstamp_set = dpaa_hwtstamp_set,\n--\ndrivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c=3030=static const struct net_device_ops dpaa2_eth_ops = {\n--\ndrivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c-3045-\t.ndo_vlan_rx_kill_vid = dpaa2_eth_rx_kill_vid,\ndrivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c:3046:\t.ndo_hwtstamp_get = dpaa2_eth_hwtstamp_get,\ndrivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c-3047-\t.ndo_hwtstamp_set = dpaa2_eth_hwtstamp_set,\n--\ndrivers/net/ethernet/freescale/enetc/enetc4_pf.c=564=static const struct net_device_ops enetc4_ndev_ops = {\n--\ndrivers/net/ethernet/freescale/enetc/enetc4_pf.c-574-\t.ndo_eth_ioctl\t\t= enetc_ioctl,\ndrivers/net/ethernet/freescale/enetc/enetc4_pf.c:575:\t.ndo_hwtstamp_get\t= enetc_hwtstamp_get,\ndrivers/net/ethernet/freescale/enetc/enetc4_pf.c-576-\t.ndo_hwtstamp_set\t= enetc_hwtstamp_set,\n--\ndrivers/net/ethernet/freescale/enetc/enetc_pf.c=482=static const struct net_device_ops enetc_ndev_ops = {\n--\ndrivers/net/ethernet/freescale/enetc/enetc_pf.c-498-\t.ndo_xdp_xmit\t\t= enetc_xdp_xmit,\ndrivers/net/ethernet/freescale/enetc/enetc_pf.c:499:\t.ndo_hwtstamp_get\t= enetc_hwtstamp_get,\ndrivers/net/ethernet/freescale/enetc/enetc_pf.c-500-\t.ndo_hwtstamp_set\t= enetc_hwtstamp_set,\n--\ndrivers/net/ethernet/freescale/enetc/enetc_vf.c=213=static const struct net_device_ops enetc_ndev_ops = {\n--\ndrivers/net/ethernet/freescale/enetc/enetc_vf.c-221-\t.ndo_setup_tc\t\t= enetc_vf_setup_tc,\ndrivers/net/ethernet/freescale/enetc/enetc_vf.c:222:\t.ndo_hwtstamp_get\t= enetc_hwtstamp_get,\ndrivers/net/ethernet/freescale/enetc/enetc_vf.c-223-\t.ndo_hwtstamp_set\t= enetc_hwtstamp_set,\n--\ndrivers/net/ethernet/freescale/fec_main.c=4887=static const struct net_device_ops fec_netdev_ops = {\n--\ndrivers/net/ethernet/freescale/fec_main.c-4901-\t.ndo_xsk_wakeup\t\t= fec_enet_xsk_wakeup,\ndrivers/net/ethernet/freescale/fec_main.c:4902:\t.ndo_hwtstamp_get\t= fec_hwtstamp_get,\ndrivers/net/ethernet/freescale/fec_main.c-4903-\t.ndo_hwtstamp_set\t= fec_hwtstamp_set,\n--\ndrivers/net/ethernet/freescale/gianfar.c=3134=static const struct net_device_ops gfar_netdev_ops = {\n--\ndrivers/net/ethernet/freescale/gianfar.c-3149-#endif\ndrivers/net/ethernet/freescale/gianfar.c:3150:\t.ndo_hwtstamp_get = gfar_hwtstamp_get,\ndrivers/net/ethernet/freescale/gianfar.c-3151-\t.ndo_hwtstamp_set = gfar_hwtstamp_set,\n--\ndrivers/net/ethernet/fungible/funeth/funeth_main.c=1322=static const struct net_device_ops fun_netdev_ops = {\n--\ndrivers/net/ethernet/fungible/funeth/funeth_main.c-1336-\t.ndo_get_vf_config\t= fun_get_vf_config,\ndrivers/net/ethernet/fungible/funeth/funeth_main.c:1337:\t.ndo_hwtstamp_get\t= fun_hwtstamp_get,\ndrivers/net/ethernet/fungible/funeth/funeth_main.c-1338-\t.ndo_hwtstamp_set\t= fun_hwtstamp_set,\n--\ndrivers/net/ethernet/google/gve/gve_main.c=2244=static const struct net_device_ops gve_netdev_ops = {\n--\ndrivers/net/ethernet/google/gve/gve_main.c-2254-\t.ndo_xsk_wakeup\t\t=\tgve_xsk_wakeup,\ndrivers/net/ethernet/google/gve/gve_main.c:2255:\t.ndo_hwtstamp_get\t=\tgve_get_ts_config,\ndrivers/net/ethernet/google/gve/gve_main.c-2256-\t.ndo_hwtstamp_set\t=\tgve_set_ts_config,\n--\ndrivers/net/ethernet/hisilicon/hns3/hns3_enet.c=3071=static const struct net_device_ops hns3_nic_netdev_ops = {\n--\ndrivers/net/ethernet/hisilicon/hns3/hns3_enet.c-3096-\t.ndo_select_queue\t= hns3_nic_select_queue,\ndrivers/net/ethernet/hisilicon/hns3/hns3_enet.c:3097:\t.ndo_hwtstamp_get\t= hns3_nic_hwtstamp_get,\ndrivers/net/ethernet/hisilicon/hns3/hns3_enet.c-3098-\t.ndo_hwtstamp_set\t= hns3_nic_hwtstamp_set,\n--\ndrivers/net/ethernet/intel/e1000e/netdev.c=7346=static const struct net_device_ops e1000e_netdev_ops = {\n--\ndrivers/net/ethernet/intel/e1000e/netdev.c-7365-\t.ndo_features_check\t= passthru_features_check,\ndrivers/net/ethernet/intel/e1000e/netdev.c:7366:\t.ndo_hwtstamp_get\t= e1000e_hwtstamp_get,\ndrivers/net/ethernet/intel/e1000e/netdev.c-7367-\t.ndo_hwtstamp_set\t= e1000e_hwtstamp_set,\n--\ndrivers/net/ethernet/intel/i40e/i40e_main.c=13585=static const struct net_device_ops i40e_netdev_ops = {\n--\ndrivers/net/ethernet/intel/i40e/i40e_main.c-13620-\t.ndo_dfwd_del_station\t= i40e_fwd_del,\ndrivers/net/ethernet/intel/i40e/i40e_main.c:13621:\t.ndo_hwtstamp_get\t= i40e_ptp_hwtstamp_get,\ndrivers/net/ethernet/intel/i40e/i40e_main.c-13622-\t.ndo_hwtstamp_set\t= i40e_ptp_hwtstamp_set,\n--\ndrivers/net/ethernet/intel/iavf/iavf_main.c=5134=static const struct net_device_ops iavf_netdev_ops = {\n--\ndrivers/net/ethernet/intel/iavf/iavf_main.c-5149-\t.net_shaper_ops\t\t= \u0026iavf_shaper_ops,\ndrivers/net/ethernet/intel/iavf/iavf_main.c:5150:\t.ndo_hwtstamp_get\t= iavf_hwstamp_get,\ndrivers/net/ethernet/intel/iavf/iavf_main.c-5151-\t.ndo_hwtstamp_set\t= iavf_hwstamp_set,\n--\ndrivers/net/ethernet/intel/ice/ice_main.c=9787=static const struct net_device_ops ice_netdev_ops = {\n--\ndrivers/net/ethernet/intel/ice/ice_main.c-9822-\t.ndo_xsk_wakeup = ice_xsk_wakeup,\ndrivers/net/ethernet/intel/ice/ice_main.c:9823:\t.ndo_hwtstamp_get = ice_ptp_hwtstamp_get,\ndrivers/net/ethernet/intel/ice/ice_main.c-9824-\t.ndo_hwtstamp_set = ice_ptp_hwtstamp_set,\n--\ndrivers/net/ethernet/intel/idpf/idpf_lib.c=2665=static const struct net_device_ops idpf_netdev_ops = {\n--\ndrivers/net/ethernet/intel/idpf/idpf_lib.c-2676-\t.ndo_tx_timeout = idpf_tx_timeout,\ndrivers/net/ethernet/intel/idpf/idpf_lib.c:2677:\t.ndo_hwtstamp_get = idpf_hwtstamp_get,\ndrivers/net/ethernet/intel/idpf/idpf_lib.c-2678-\t.ndo_hwtstamp_set = idpf_hwtstamp_set,\n--\ndrivers/net/ethernet/intel/igb/igb_main.c=3036=static const struct net_device_ops igb_netdev_ops = {\n--\ndrivers/net/ethernet/intel/igb/igb_main.c-3062-\t.ndo_xsk_wakeup         = igb_xsk_wakeup,\ndrivers/net/ethernet/intel/igb/igb_main.c:3063:\t.ndo_hwtstamp_get\t= igb_ptp_hwtstamp_get,\ndrivers/net/ethernet/intel/igb/igb_main.c-3064-\t.ndo_hwtstamp_set\t= igb_ptp_hwtstamp_set,\n--\ndrivers/net/ethernet/intel/igc/igc_main.c=6981=static const struct net_device_ops igc_netdev_ops = {\n--\ndrivers/net/ethernet/intel/igc/igc_main.c-6997-\t.ndo_get_tstamp\t\t= igc_get_tstamp,\ndrivers/net/ethernet/intel/igc/igc_main.c:6998:\t.ndo_hwtstamp_get\t= igc_ptp_hwtstamp_get,\ndrivers/net/ethernet/intel/igc/igc_main.c-6999-\t.ndo_hwtstamp_set\t= igc_ptp_hwtstamp_set,\n--\ndrivers/net/ethernet/intel/ixgbe/ixgbe_main.c=11071=static const struct net_device_ops ixgbe_netdev_ops = {\n--\ndrivers/net/ethernet/intel/ixgbe/ixgbe_main.c-11115-\t.ndo_xsk_wakeup         = ixgbe_xsk_wakeup,\ndrivers/net/ethernet/intel/ixgbe/ixgbe_main.c:11116:\t.ndo_hwtstamp_get\t= ixgbe_ptp_hwtstamp_get,\ndrivers/net/ethernet/intel/ixgbe/ixgbe_main.c-11117-\t.ndo_hwtstamp_set\t= ixgbe_ptp_hwtstamp_set,\n--\ndrivers/net/ethernet/marvell/mvpp2/mvpp2_main.c=5810=static const struct net_device_ops mvpp2_netdev_ops = {\n--\ndrivers/net/ethernet/marvell/mvpp2/mvpp2_main.c-5823-\t.ndo_xdp_xmit\t\t= mvpp2_xdp_xmit,\ndrivers/net/ethernet/marvell/mvpp2/mvpp2_main.c:5824:\t.ndo_hwtstamp_get\t= mvpp2_hwtstamp_get,\ndrivers/net/ethernet/marvell/mvpp2/mvpp2_main.c-5825-\t.ndo_hwtstamp_set\t= mvpp2_hwtstamp_set,\n--\ndrivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c=2951=static const struct net_device_ops otx2_netdev_ops = {\n--\ndrivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c-2970-\t.ndo_set_vf_trust\t= otx2_ndo_set_vf_trust,\ndrivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c:2971:\t.ndo_hwtstamp_get\t= otx2_config_hwtstamp_get,\ndrivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c-2972-\t.ndo_hwtstamp_set\t= otx2_config_hwtstamp_set,\n--\ndrivers/net/ethernet/marvell/octeontx2/nic/otx2_vf.c=524=static const struct net_device_ops otx2vf_netdev_ops = {\n--\ndrivers/net/ethernet/marvell/octeontx2/nic/otx2_vf.c-535-\t.ndo_setup_tc = otx2_setup_tc,\ndrivers/net/ethernet/marvell/octeontx2/nic/otx2_vf.c:536:\t.ndo_hwtstamp_get = otx2_config_hwtstamp_get,\ndrivers/net/ethernet/marvell/octeontx2/nic/otx2_vf.c-537-\t.ndo_hwtstamp_set = otx2_config_hwtstamp_set,\n--\ndrivers/net/ethernet/mellanox/mlx4/en_netdev.c=2823=static const struct net_device_ops mlx4_netdev_ops = {\n--\ndrivers/net/ethernet/mellanox/mlx4/en_netdev.c-2845-\t.ndo_bpf\t\t= mlx4_xdp,\ndrivers/net/ethernet/mellanox/mlx4/en_netdev.c:2846:\t.ndo_hwtstamp_get\t= mlx4_en_hwtstamp_get,\ndrivers/net/ethernet/mellanox/mlx4/en_netdev.c-2847-\t.ndo_hwtstamp_set\t= mlx4_en_hwtstamp_set,\n--\ndrivers/net/ethernet/mellanox/mlx5/core/en_main.c=5324=const struct net_device_ops mlx5e_netdev_ops = {\n--\ndrivers/net/ethernet/mellanox/mlx5/core/en_main.c-5343-\t.ndo_xsk_wakeup          = mlx5e_xsk_wakeup,\ndrivers/net/ethernet/mellanox/mlx5/core/en_main.c:5344:\t.ndo_hwtstamp_get        = mlx5e_hwtstamp_get_ndo,\ndrivers/net/ethernet/mellanox/mlx5/core/en_main.c-5345-\t.ndo_hwtstamp_set        = mlx5e_hwtstamp_set_ndo,\n--\ndrivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib.c=65=static const struct net_device_ops mlx5i_netdev_ops = {\n--\ndrivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib.c-71-\t.ndo_change_mtu          = mlx5i_change_mtu,\ndrivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib.c:72:\t.ndo_hwtstamp_get        = mlx5i_hwtstamp_get,\ndrivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib.c-73-\t.ndo_hwtstamp_set        = mlx5i_hwtstamp_set,\n--\ndrivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib_vlan.c=144=static const struct net_device_ops mlx5i_pkey_netdev_ops = {\n--\ndrivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib_vlan.c-150-\t.ndo_change_mtu          = mlx5i_pkey_change_mtu,\ndrivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib_vlan.c:151:\t.ndo_hwtstamp_get        = mlx5i_hwtstamp_get,\ndrivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib_vlan.c-152-\t.ndo_hwtstamp_set        = mlx5i_hwtstamp_set,\n--\ndrivers/net/ethernet/mellanox/mlxsw/spectrum.c=1192=static const struct net_device_ops mlxsw_sp_port_netdev_ops = {\n--\ndrivers/net/ethernet/mellanox/mlxsw/spectrum.c-1205-\t.ndo_set_features\t= mlxsw_sp_set_features,\ndrivers/net/ethernet/mellanox/mlxsw/spectrum.c:1206:\t.ndo_hwtstamp_get\t= mlxsw_sp_port_hwtstamp_get,\ndrivers/net/ethernet/mellanox/mlxsw/spectrum.c-1207-\t.ndo_hwtstamp_set\t= mlxsw_sp_port_hwtstamp_set,\n--\ndrivers/net/ethernet/meta/fbnic/fbnic_netdev.c=559=static const struct net_device_ops fbnic_netdev_ops = {\n--\ndrivers/net/ethernet/meta/fbnic/fbnic_netdev.c-569-\t.ndo_bpf\t\t= fbnic_bpf,\ndrivers/net/ethernet/meta/fbnic/fbnic_netdev.c:570:\t.ndo_hwtstamp_get\t= fbnic_hwtstamp_get,\ndrivers/net/ethernet/meta/fbnic/fbnic_netdev.c-571-\t.ndo_hwtstamp_set\t= fbnic_hwtstamp_set,\n--\ndrivers/net/ethernet/microchip/lan743x_main.c=3496=static const struct net_device_ops lan743x_netdev_ops = {\n--\ndrivers/net/ethernet/microchip/lan743x_main.c-3504-\t.ndo_set_mac_address\t= lan743x_netdev_set_mac_address,\ndrivers/net/ethernet/microchip/lan743x_main.c:3505:\t.ndo_hwtstamp_get\t= lan743x_ptp_hwtstamp_get,\ndrivers/net/ethernet/microchip/lan743x_main.c-3506-\t.ndo_hwtstamp_set\t= lan743x_ptp_hwtstamp_set,\n--\ndrivers/net/ethernet/microchip/lan966x/lan966x_main.c=501=static const struct net_device_ops lan966x_port_netdev_ops = {\n--\ndrivers/net/ethernet/microchip/lan966x/lan966x_main.c-514-\t.ndo_xdp_xmit\t\t\t= lan966x_xdp_xmit,\ndrivers/net/ethernet/microchip/lan966x/lan966x_main.c:515:\t.ndo_hwtstamp_get\t\t= lan966x_port_hwtstamp_get,\ndrivers/net/ethernet/microchip/lan966x/lan966x_main.c-516-\t.ndo_hwtstamp_set\t\t= lan966x_port_hwtstamp_set,\n--\ndrivers/net/ethernet/microchip/sparx5/sparx5_netdev.c=248=static const struct net_device_ops sparx5_port_netdev_ops = {\n--\ndrivers/net/ethernet/microchip/sparx5/sparx5_netdev.c-259-\t.ndo_setup_tc           = sparx5_port_setup_tc,\ndrivers/net/ethernet/microchip/sparx5/sparx5_netdev.c:260:\t.ndo_hwtstamp_get       = sparx5_port_hwtstamp_get,\ndrivers/net/ethernet/microchip/sparx5/sparx5_netdev.c-261-\t.ndo_hwtstamp_set       = sparx5_port_hwtstamp_set,\n--\ndrivers/net/ethernet/mscc/ocelot_net.c=948=static const struct net_device_ops ocelot_port_netdev_ops = {\n--\ndrivers/net/ethernet/mscc/ocelot_net.c-963-\t.ndo_eth_ioctl\t\t\t= ocelot_ioctl,\ndrivers/net/ethernet/mscc/ocelot_net.c:964:\t.ndo_hwtstamp_get\t\t= ocelot_port_hwtstamp_get,\ndrivers/net/ethernet/mscc/ocelot_net.c-965-\t.ndo_hwtstamp_set\t\t= ocelot_port_hwtstamp_set,\n--\ndrivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c=2344=static const struct net_device_ops pch_gbe_netdev_ops = {\n--\ndrivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c-2356-#endif\ndrivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c:2357:\t.ndo_hwtstamp_get = pch_gbe_hwtstamp_get,\ndrivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c-2358-\t.ndo_hwtstamp_set = pch_gbe_hwtstamp_set,\n--\ndrivers/net/ethernet/pensando/ionic/ionic_lif.c=2805=static const struct net_device_ops ionic_netdev_ops = {\n--\ndrivers/net/ethernet/pensando/ionic/ionic_lif.c-2827-\t.ndo_get_vf_stats       = ionic_get_vf_stats,\ndrivers/net/ethernet/pensando/ionic/ionic_lif.c:2828:\t.ndo_hwtstamp_get\t= ionic_hwstamp_get,\ndrivers/net/ethernet/pensando/ionic/ionic_lif.c-2829-\t.ndo_hwtstamp_set\t= ionic_hwstamp_set,\n--\ndrivers/net/ethernet/qlogic/qede/qede_main.c=692=static const struct net_device_ops qede_netdev_ops = {\n--\ndrivers/net/ethernet/qlogic/qede/qede_main.c-724-\t.ndo_setup_tc\t\t= qede_setup_tc_offload,\ndrivers/net/ethernet/qlogic/qede/qede_main.c:725:\t.ndo_hwtstamp_get\t= qede_hwtstamp_get,\ndrivers/net/ethernet/qlogic/qede/qede_main.c-726-\t.ndo_hwtstamp_set\t= qede_hwtstamp_set,\n--\ndrivers/net/ethernet/renesas/ravb_main.c=2605=static const struct net_device_ops ravb_netdev_ops = {\n--\ndrivers/net/ethernet/renesas/ravb_main.c-2617-\t.ndo_set_features\t= ravb_set_features,\ndrivers/net/ethernet/renesas/ravb_main.c:2618:\t.ndo_hwtstamp_get\t= ravb_hwtstamp_get,\ndrivers/net/ethernet/renesas/ravb_main.c-2619-\t.ndo_hwtstamp_set\t= ravb_hwtstamp_set,\n--\ndrivers/net/ethernet/renesas/rswitch_main.c=1871=static const struct net_device_ops rswitch_netdev_ops = {\n--\ndrivers/net/ethernet/renesas/rswitch_main.c-1880-\t.ndo_set_mac_address = eth_mac_addr,\ndrivers/net/ethernet/renesas/rswitch_main.c:1881:\t.ndo_hwtstamp_get = rswitch_hwstamp_get,\ndrivers/net/ethernet/renesas/rswitch_main.c-1882-\t.ndo_hwtstamp_set = rswitch_hwstamp_set,\n--\ndrivers/net/ethernet/renesas/rtsn.c=1173=static const struct net_device_ops rtsn_netdev_ops = {\n--\ndrivers/net/ethernet/renesas/rtsn.c-1181-\t.ndo_hwtstamp_set\t= rtsn_hwtstamp_set,\ndrivers/net/ethernet/renesas/rtsn.c:1182:\t.ndo_hwtstamp_get\t= rtsn_hwtstamp_get,\ndrivers/net/ethernet/renesas/rtsn.c-1183-};\n--\ndrivers/net/ethernet/sfc/efx.c=568=static const struct net_device_ops efx_netdev_ops = {\n--\ndrivers/net/ethernet/sfc/efx.c-582-\t.ndo_hwtstamp_set\t= efx_hwtstamp_set,\ndrivers/net/ethernet/sfc/efx.c:583:\t.ndo_hwtstamp_get\t= efx_hwtstamp_get,\ndrivers/net/ethernet/sfc/efx.c-584-#ifdef CONFIG_SFC_SRIOV\n--\ndrivers/net/ethernet/sfc/siena/efx.c=594=static const struct net_device_ops efx_netdev_ops = {\n--\ndrivers/net/ethernet/sfc/siena/efx.c-609-\t.ndo_hwtstamp_set\t= efx_siena_hwtstamp_set,\ndrivers/net/ethernet/sfc/siena/efx.c:610:\t.ndo_hwtstamp_get\t= efx_siena_hwtstamp_get,\ndrivers/net/ethernet/sfc/siena/efx.c-611-#ifdef CONFIG_SFC_SIENA_SRIOV\n--\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c=7304=static const struct net_device_ops stmmac_netdev_ops = {\n--\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c-7323-\t.ndo_xsk_wakeup = stmmac_xsk_wakeup,\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c:7324:\t.ndo_hwtstamp_get = stmmac_hwtstamp_get,\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c-7325-\t.ndo_hwtstamp_set = stmmac_hwtstamp_set,\n--\ndrivers/net/ethernet/ti/am65-cpsw-nuss.c=1972=static const struct net_device_ops am65_cpsw_nuss_netdev_ops = {\n--\ndrivers/net/ethernet/ti/am65-cpsw-nuss.c-1987-\t.ndo_xdp_xmit\t\t= am65_cpsw_ndo_xdp_xmit,\ndrivers/net/ethernet/ti/am65-cpsw-nuss.c:1988:\t.ndo_hwtstamp_get       = am65_cpsw_nuss_hwtstamp_get,\ndrivers/net/ethernet/ti/am65-cpsw-nuss.c-1989-\t.ndo_hwtstamp_set       = am65_cpsw_nuss_hwtstamp_set,\n--\ndrivers/net/ethernet/ti/cpsw.c=1199=static const struct net_device_ops cpsw_netdev_ops = {\n--\ndrivers/net/ethernet/ti/cpsw.c-1216-\t.ndo_xdp_xmit\t\t= cpsw_ndo_xdp_xmit,\ndrivers/net/ethernet/ti/cpsw.c:1217:\t.ndo_hwtstamp_get\t= cpsw_hwtstamp_get,\ndrivers/net/ethernet/ti/cpsw.c-1218-\t.ndo_hwtstamp_set\t= cpsw_hwtstamp_set,\n--\ndrivers/net/ethernet/ti/cpsw_new.c=1148=static const struct net_device_ops cpsw_netdev_ops = {\n--\ndrivers/net/ethernet/ti/cpsw_new.c-1167-\t.ndo_get_port_parent_id\t= cpsw_get_port_parent_id,\ndrivers/net/ethernet/ti/cpsw_new.c:1168:\t.ndo_hwtstamp_get\t= cpsw_hwtstamp_get,\ndrivers/net/ethernet/ti/cpsw_new.c-1169-\t.ndo_hwtstamp_set\t= cpsw_hwtstamp_set,\n--\ndrivers/net/ethernet/ti/icssg/icssg_prueth.c=1636=static const struct net_device_ops emac_netdev_ops = {\n--\ndrivers/net/ethernet/ti/icssg/icssg_prueth.c-1651-\t.ndo_xdp_xmit = emac_xdp_xmit,\ndrivers/net/ethernet/ti/icssg/icssg_prueth.c:1652:\t.ndo_hwtstamp_get = icssg_ndo_get_ts_config,\ndrivers/net/ethernet/ti/icssg/icssg_prueth.c-1653-\t.ndo_hwtstamp_set = icssg_ndo_set_ts_config,\n--\ndrivers/net/ethernet/ti/icssg/icssg_prueth_sr1.c=742=static const struct net_device_ops emac_netdev_ops = {\n--\ndrivers/net/ethernet/ti/icssg/icssg_prueth_sr1.c-752-\t.ndo_get_phys_port_name = icssg_ndo_get_phys_port_name,\ndrivers/net/ethernet/ti/icssg/icssg_prueth_sr1.c:753:\t.ndo_hwtstamp_get = icssg_ndo_get_ts_config,\ndrivers/net/ethernet/ti/icssg/icssg_prueth_sr1.c-754-\t.ndo_hwtstamp_set = icssg_ndo_set_ts_config,\n--\ndrivers/net/ethernet/ti/netcp_core.c=1744=static int netcp_ndo_stop(struct net_device *ndev)\n--\ndrivers/net/ethernet/ti/netcp_core.c-1783-\ndrivers/net/ethernet/ti/netcp_core.c:1784:static int netcp_ndo_hwtstamp_get(struct net_device *ndev,\ndrivers/net/ethernet/ti/netcp_core.c-1785-\t\t\t\t  struct kernel_hwtstamp_config *config)\n--\ndrivers/net/ethernet/ti/netcp_core.c=1997=static const struct net_device_ops netcp_netdev_ops = {\n--\ndrivers/net/ethernet/ti/netcp_core.c-2010-\t.ndo_setup_tc\t\t= netcp_setup_tc,\ndrivers/net/ethernet/ti/netcp_core.c:2011:\t.ndo_hwtstamp_get\t= netcp_ndo_hwtstamp_get,\ndrivers/net/ethernet/ti/netcp_core.c-2012-\t.ndo_hwtstamp_set\t= netcp_ndo_hwtstamp_set,\n--\ndrivers/net/ethernet/wangxun/ngbe/ngbe_main.c=670=static const struct net_device_ops ngbe_netdev_ops = {\n--\ndrivers/net/ethernet/wangxun/ngbe/ngbe_main.c-685-\t.ndo_hwtstamp_set       = wx_hwtstamp_set,\ndrivers/net/ethernet/wangxun/ngbe/ngbe_main.c:686:\t.ndo_hwtstamp_get       = wx_hwtstamp_get,\ndrivers/net/ethernet/wangxun/ngbe/ngbe_main.c-687-};\n--\ndrivers/net/ethernet/wangxun/txgbe/txgbe_main.c=696=static const struct net_device_ops txgbe_netdev_ops = {\n--\ndrivers/net/ethernet/wangxun/txgbe/txgbe_main.c-711-\t.ndo_hwtstamp_set       = wx_hwtstamp_set,\ndrivers/net/ethernet/wangxun/txgbe/txgbe_main.c:712:\t.ndo_hwtstamp_get       = wx_hwtstamp_get,\ndrivers/net/ethernet/wangxun/txgbe/txgbe_main.c-713-};\n--\ndrivers/net/ethernet/xscale/ixp4xx_eth.c=1422=static const struct net_device_ops ixp4xx_netdev_ops = {\n--\ndrivers/net/ethernet/xscale/ixp4xx_eth.c-1430-\t.ndo_validate_addr = eth_validate_addr,\ndrivers/net/ethernet/xscale/ixp4xx_eth.c:1431:\t.ndo_hwtstamp_get = ixp4xx_hwtstamp_get,\ndrivers/net/ethernet/xscale/ixp4xx_eth.c-1432-\t.ndo_hwtstamp_set = ixp4xx_hwtstamp_set,\n--\ndrivers/net/macvlan.c=1191=static const struct net_device_ops macvlan_netdev_ops = {\n--\ndrivers/net/macvlan.c-1215-\t.ndo_features_check\t= passthru_features_check,\ndrivers/net/macvlan.c:1216:\t.ndo_hwtstamp_get\t= macvlan_hwtstamp_get,\ndrivers/net/macvlan.c-1217-\t.ndo_hwtstamp_set\t= macvlan_hwtstamp_set,\n--\ndrivers/net/netdevsim/netdev.c=732=static const struct net_device_ops nsim_netdev_ops = {\n--\ndrivers/net/netdevsim/netdev.c-754-\t.net_shaper_ops\t\t= \u0026nsim_shaper_ops,\ndrivers/net/netdevsim/netdev.c:755:\t.ndo_hwtstamp_get\t= nsim_get_ts_config,\ndrivers/net/netdevsim/netdev.c-756-\t.ndo_hwtstamp_set\t= nsim_set_ts_config,\n--\ninclude/linux/netdevice.h=1065=struct netdev_net_notifier {\n--\ninclude/linux/netdevice.h-1438- *\ninclude/linux/netdevice.h:1439: * int (*ndo_hwtstamp_get)(struct net_device *dev,\ninclude/linux/netdevice.h-1440- *\t\t\t   struct kernel_hwtstamp_config *kernel_config);\n--\ninclude/linux/netdevice.h=1449=struct net_device_ops {\n--\ninclude/linux/netdevice.h-1695-\t\t\t\t\t\t  bool cycles);\ninclude/linux/netdevice.h:1696:\tint\t\t\t(*ndo_hwtstamp_get)(struct net_device *dev,\ninclude/linux/netdevice.h-1697-\t\t\t\t\t\t    struct kernel_hwtstamp_config *kernel_config);\n--\nnet/8021q/vlan_dev.c=1078=static const struct net_device_ops vlan_netdev_ops = {\n--\nnet/8021q/vlan_dev.c-1110-\t.ndo_fill_forward_path\t= vlan_dev_fill_forward_path,\nnet/8021q/vlan_dev.c:1111:\t.ndo_hwtstamp_get\t= vlan_hwtstamp_get,\nnet/8021q/vlan_dev.c-1112-\t.ndo_hwtstamp_set\t= vlan_hwtstamp_set,\n--\nnet/core/dev_ioctl.c=258=int dev_get_hwtstamp_phylib(struct net_device *dev,\n--\nnet/core/dev_ioctl.c-270-\t\tif (hwprov-\u003esource == HWTSTAMP_SOURCE_NETDEV)\nnet/core/dev_ioctl.c:271:\t\t\treturn dev-\u003enetdev_ops-\u003endo_hwtstamp_get(dev, cfg);\n\n"
}

25/3 2026/08/13 22:54 llm kmsan-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 23827
							output: 21
							thoughts: 38
						

Thoughts:
Here's my summary, as the expert:

**Investigating Hardware Timestamp Retrieval in the Kernel**

Okay, so I'm diving into the kernel code related to hardware timestamping, specifically to see how timestamping data is pulled. Given the context, my initial thought is to zero in on `net/core/dev_ioctl.c`, and I'm going to look closely at the functions responsible for retrieving the hardware timestamp information. I suspect either `dev_get_hwtstamp_phylib` or `dev_get_hwtstamp` will hold the key to understanding the retrieval mechanism, and how it interfaces with the physical layer (phylib) if applicable. These ioctl handlers seem like the logical place to start. Let's see what these functions reveal!



26/3 2026/08/13 22:54 tool grepper
0m Args:
{
  "Expression": "dev_get_hwtstamp"
}

Results:
{
  "Output": "net/core/dev.h=404=int dev_set_hwtstamp_phylib(struct net_device *dev,\n--\nnet/core/dev.h-406-\t\t\t    struct netlink_ext_ack *extack);\nnet/core/dev.h:407:int dev_get_hwtstamp_phylib(struct net_device *dev,\nnet/core/dev.h-408-\t\t\t    struct kernel_hwtstamp_config *cfg);\n--\nnet/core/dev_ioctl.c=189=int net_hwtstamp_validate(const struct kernel_hwtstamp_config *cfg)\n--\nnet/core/dev_ioctl.c-244-/**\nnet/core/dev_ioctl.c:245: * dev_get_hwtstamp_phylib() - Get hardware timestamping settings of NIC\nnet/core/dev_ioctl.c-246- *\tor of attached phylib PHY\n--\nnet/core/dev_ioctl.c-257- */\nnet/core/dev_ioctl.c:258:int dev_get_hwtstamp_phylib(struct net_device *dev,\nnet/core/dev_ioctl.c-259-\t\t\t    struct kernel_hwtstamp_config *cfg)\n--\nnet/core/dev_ioctl.c-281-\nnet/core/dev_ioctl.c:282:static int dev_get_hwtstamp(struct net_device *dev, struct ifreq *ifr)\nnet/core/dev_ioctl.c-283-{\n--\nnet/core/dev_ioctl.c-296-\tnetdev_lock_ops(dev);\nnet/core/dev_ioctl.c:297:\terr = dev_get_hwtstamp_phylib(dev, \u0026kernel_cfg);\nnet/core/dev_ioctl.c-298-\tnetdev_unlock_ops(dev);\n--\nnet/core/dev_ioctl.c=441=int generic_hwtstamp_get_lower(struct net_device *dev,\n--\nnet/core/dev_ioctl.c-453-\tnetdev_lock_ops(dev);\nnet/core/dev_ioctl.c:454:\terr = dev_get_hwtstamp_phylib(dev, kernel_cfg);\nnet/core/dev_ioctl.c-455-\tnetdev_unlock_ops(dev);\n--\nnet/core/dev_ioctl.c=541=static int dev_ifsioc(struct net *net, struct ifreq *ifr, void __user *data,\n--\nnet/core/dev_ioctl.c-630-\tcase SIOCGHWTSTAMP:\nnet/core/dev_ioctl.c:631:\t\treturn dev_get_hwtstamp(dev, ifr);\nnet/core/dev_ioctl.c-632-\n--\nnet/ethtool/tsconfig.c=35=static int tsconfig_prepare_data(const struct ethnl_req_info *req_base,\n--\nnet/ethtool/tsconfig.c-51-\nnet/ethtool/tsconfig.c:52:\tret = dev_get_hwtstamp_phylib(dev, \u0026cfg);\nnet/ethtool/tsconfig.c-53-\tif (ret)\n--\nnet/ethtool/tsconfig.c=303=static int ethnl_set_tsconfig(struct ethnl_req_info *req_base,\n--\nnet/ethtool/tsconfig.c-343-\tif (!hwprov_mod) {\nnet/ethtool/tsconfig.c:344:\t\tret = dev_get_hwtstamp_phylib(dev, \u0026hwtst_config);\nnet/ethtool/tsconfig.c-345-\t\tif (ret \u003c 0 \u0026\u0026 ret != -EOPNOTSUPP)\n"
}

27/3 2026/08/13 22:54 llm kmsan-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 25006
							output: 37
							thoughts: 25
						

Thoughts:
Here's my take on the thought process, as if it were my own:

**Investigating Hardware Timestamping Retrieval**

Okay, so I need to dig into how hardware timestamps are being retrieved. My first instinct is to go directly to the source. Let's see... the `dev_get_hwtstamp` function should be the key, and that's probably hanging out in `net/core/dev_ioctl.c`. That's where I would expect to find the relevant device control interaction code. Let's see what it has to tell me.



28/3 2026/08/13 22:54 tool read-file
0m Args:
{
  "File": "net/core/dev_ioctl.c",
  "FirstLine": 280,
  "LineCount": 50
}

Results:
{
  "Contents": " 280:\t}\n 281:\t\n 282:\tstatic int dev_get_hwtstamp(struct net_device *dev, struct ifreq *ifr)\n 283:\t{\n 284:\t\tconst struct net_device_ops *ops = dev-\u003enetdev_ops;\n 285:\t\tstruct kernel_hwtstamp_config kernel_cfg = {};\n 286:\t\tstruct hwtstamp_config cfg;\n 287:\t\tint err;\n 288:\t\n 289:\t\tif (!ops-\u003endo_hwtstamp_get)\n 290:\t\t\treturn -EOPNOTSUPP;\n 291:\t\n 292:\t\tif (!netif_device_present(dev))\n 293:\t\t\treturn -ENODEV;\n 294:\t\n 295:\t\tkernel_cfg.ifr = ifr;\n 296:\t\tnetdev_lock_ops(dev);\n 297:\t\terr = dev_get_hwtstamp_phylib(dev, \u0026kernel_cfg);\n 298:\t\tnetdev_unlock_ops(dev);\n 299:\t\tif (err)\n 300:\t\t\treturn err;\n 301:\t\n 302:\t\t/* If the request was resolved through an unconverted driver, omit\n 303:\t\t * the copy_to_user(), since the implementation has already done that\n 304:\t\t */\n 305:\t\tif (!kernel_cfg.copied_to_user) {\n 306:\t\t\thwtstamp_config_from_kernel(\u0026cfg, \u0026kernel_cfg);\n 307:\t\n 308:\t\t\tif (copy_to_user(ifr-\u003eifr_data, \u0026cfg, sizeof(cfg)))\n 309:\t\t\t\treturn -EFAULT;\n 310:\t\t}\n 311:\t\n 312:\t\treturn 0;\n 313:\t}\n 314:\t\n 315:\t/**\n 316:\t * dev_set_hwtstamp_phylib() - Change hardware timestamping of NIC\n 317:\t *\tor of attached phylib PHY\n 318:\t * @dev: Network device\n 319:\t * @cfg: Timestamping configuration structure\n 320:\t * @extack: Netlink extended ack message structure, for error reporting\n 321:\t *\n 322:\t * Helper for enforcing a common policy that phylib timestamping, if available,\n 323:\t * should take precedence in front of hardware timestamping provided by the\n 324:\t * netdev. If the netdev driver needs to perform specific actions even for PHY\n 325:\t * timestamping to work properly (a switch port must trap the timestamped\n 326:\t * frames and not forward them), it must set dev-\u003esee_all_hwtstamp_requests.\n 327:\t */\n 328:\tint dev_set_hwtstamp_phylib(struct net_device *dev,\n 329:\t\t\t\t    struct kernel_hwtstamp_config *cfg,\n"
}

29/3 2026/08/13 22:54 llm kmsan-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 25973
							output: 23
							thoughts: 102
						

Thoughts:
**Analyzing the Hardware Timestamp Configuration Flow**

Okay, so I'm looking at this `dev_get_hwtstamp` function. My initial observation is that `kernel_cfg` is initialized as an empty struct, `{}`. Right, makes sense – a fresh start for configuring the hardware timestamp. Next, `dev_get_hwtstamp_phylib` is called. That's a good clue, likely where the actual PHY-specific configurations are gathered. After that, we hit `hwtstamp_config_from_kernel`. Now, *that* is the core of what I'm interested in. I need to understand how the system translates what it gets from the PHY and any kernel-level settings into the final configuration. Finally, the gathered configuration in `cfg` is copied to user space. It seems straightforward: gather, translate, then provide the information to the user. My immediate focus, however, is on that `hwtstamp_config_from_kernel` function – it's the crucial mapping between the low-level and what the user sees. I want to dive into it immediately. Let's see how that function works.



30/3 2026/08/13 22:54 tool grepper
0m Args:
{
  "Expression": "hwtstamp_config_from_kernel"
}

Results:
{
  "Output": "drivers/net/phy/phy.c=310=int phy_mii_ioctl(struct phy_device *phydev, struct ifreq *ifr, int cmd)\n--\ndrivers/net/phy/phy.c-418-\ndrivers/net/phy/phy.c:419:\t\t\thwtstamp_config_from_kernel(\u0026cfg, \u0026kernel_cfg);\ndrivers/net/phy/phy.c-420-\t\t\tif (copy_to_user(ifr-\u003eifr_data, \u0026cfg, sizeof(cfg)))\n--\ninclude/linux/net_tstamp.h=72=static inline void hwtstamp_config_to_kernel(struct kernel_hwtstamp_config *kernel_cfg,\n--\ninclude/linux/net_tstamp.h-79-\ninclude/linux/net_tstamp.h:80:static inline void hwtstamp_config_from_kernel(struct hwtstamp_config *cfg,\ninclude/linux/net_tstamp.h-81-\t\t\t\t\t       const struct kernel_hwtstamp_config *kernel_cfg)\n--\nnet/core/dev_ioctl.c=282=static int dev_get_hwtstamp(struct net_device *dev, struct ifreq *ifr)\n--\nnet/core/dev_ioctl.c-305-\tif (!kernel_cfg.copied_to_user) {\nnet/core/dev_ioctl.c:306:\t\thwtstamp_config_from_kernel(\u0026cfg, \u0026kernel_cfg);\nnet/core/dev_ioctl.c-307-\n--\nnet/core/dev_ioctl.c=391=static int dev_set_hwtstamp(struct net_device *dev, struct ifreq *ifr)\n--\nnet/core/dev_ioctl.c-431-\tif (!kernel_cfg.copied_to_user) {\nnet/core/dev_ioctl.c:432:\t\thwtstamp_config_from_kernel(\u0026cfg, \u0026kernel_cfg);\nnet/core/dev_ioctl.c-433-\n"
}

31/3 2026/08/13 22:54 llm kmsan-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 26845
							output: 37
							thoughts: 28
						

Thoughts:
Here's my take on those thoughts, tailored for an expert audience:

**Analyzing `hwtstamp_config_from_kernel`**

Okay, time to dive into `include/linux/net_tstamp.h`. I need to refresh my memory on how the kernel is handling hardware timestamp configurations. Specifically, I'm zeroing in on `hwtstamp_config_from_kernel`. I'm guessing it's the function that's responsible for translating the kernel's internal representation of hardware timestamping settings into something usable by user-space applications. I'll need to check the function signature, its arguments, and what data structures it's interacting with. Likely, it's dealing with some sort of `hwtstamp_config` struct, but I want to confirm the details. I'm looking for the specifics of how the kernel exposes and controls hardware timestamping capabilities. Are we talking about PTP clocks? Raw Ethernet timestamps? What parameters can the kernel configure, and how does that influence the available features for applications? The devil's always in the details, so I need to understand the nuances of this function to fully grasp the kernel's timestamping interface.



32/3 2026/08/13 22:54 tool read-file
0m Args:
{
  "File": "include/linux/net_tstamp.h",
  "FirstLine": 70,
  "LineCount": 30
}

Results:
{
  "Contents": "  70:\t};\n  71:\t\n  72:\tstatic inline void hwtstamp_config_to_kernel(struct kernel_hwtstamp_config *kernel_cfg,\n  73:\t\t\t\t\t\t     const struct hwtstamp_config *cfg)\n  74:\t{\n  75:\t\tkernel_cfg-\u003eflags = cfg-\u003eflags;\n  76:\t\tkernel_cfg-\u003etx_type = cfg-\u003etx_type;\n  77:\t\tkernel_cfg-\u003erx_filter = cfg-\u003erx_filter;\n  78:\t}\n  79:\t\n  80:\tstatic inline void hwtstamp_config_from_kernel(struct hwtstamp_config *cfg,\n  81:\t\t\t\t\t\t       const struct kernel_hwtstamp_config *kernel_cfg)\n  82:\t{\n  83:\t\tcfg-\u003eflags = kernel_cfg-\u003eflags;\n  84:\t\tcfg-\u003etx_type = kernel_cfg-\u003etx_type;\n  85:\t\tcfg-\u003erx_filter = kernel_cfg-\u003erx_filter;\n  86:\t}\n  87:\t\n  88:\tstatic inline bool kernel_hwtstamp_config_changed(const struct kernel_hwtstamp_config *a,\n  89:\t\t\t\t\t\t\t  const struct kernel_hwtstamp_config *b)\n  90:\t{\n  91:\t\treturn a-\u003eflags != b-\u003eflags ||\n  92:\t\t       a-\u003etx_type != b-\u003etx_type ||\n  93:\t\t       a-\u003erx_filter != b-\u003erx_filter;\n  94:\t}\n  95:\t\n  96:\t#endif /* _LINUX_NET_TIMESTAMPING_H_ */\n"
}

33/3 2026/08/13 22:54 llm kmsan-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 27580
							output: 21
							thoughts: 29
						

Thoughts:
**Examining the Potential for Padding in `hwtstamp_config`**

Okay, hold on a minute. I'm just considering this `struct hwtstamp_config` we're working with here, and a thought just popped into my head: I bet there's some padding in there. Given how structures are typically laid out in memory, and considering the data types likely used within it, padding is a very common optimization. Let's not assume anything though. I need to verify this assumption before I go any further, especially if I'm doing something with alignment or offsets. Time to check the actual definition of `struct hwtstamp_config` itself and confirm. Gotta go double-check the source code or header file.



34/3 2026/08/13 22:54 tool grepper
0m Args:
{
  "Expression": "struct hwtstamp_config \\{"
}

Results:
{
  "Output": "Documentation/networking/timestamping.rst=541=include/uapi/linux/net_tstamp.h as::\nDocumentation/networking/timestamping.rst-542-\nDocumentation/networking/timestamping.rst:543:\tstruct hwtstamp_config {\nDocumentation/networking/timestamping.rst-544-\t\tint flags;\t/* no flags defined right now, must be zero */\n--\nDocumentation/translations/zh_CN/networking/timestamping.rst=427=scm_timestamping 中的三个字段含义隐式定义。ts[0] 在设置时包含软件\n--\nDocumentation/translations/zh_CN/networking/timestamping.rst-436-\nDocumentation/translations/zh_CN/networking/timestamping.rst:437:\tstruct hwtstamp_config {\nDocumentation/translations/zh_CN/networking/timestamping.rst-438-\t\tint flags;\t/* 目前没有定义的标志,必须为零 */\n--\ninclude/uapi/linux/net_tstamp.h=72=struct so_timestamping {\n--\ninclude/uapi/linux/net_tstamp.h-89- */\ninclude/uapi/linux/net_tstamp.h:90:struct hwtstamp_config {\ninclude/uapi/linux/net_tstamp.h-91-\tint flags;\n"
}

35/3 2026/08/13 22:55 llm kmsan-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 28114
							output: 40
							thoughts: 25
						

Thoughts:
Here's my summary, as if I were thinking these thoughts:

**Examining net_tstamp.h's Core Structures**

Okay, time to dive in. I need to understand how the timestamping mechanisms work in the Linux kernel, so I'm going to start by looking at `include/uapi/linux/net_tstamp.h`. Specifically, I'll focus around line 90. I know this file defines the user-space interfaces for accessing hardware timestamping features, so this should give me a good handle on the fundamental data structures and ioctls involved. I'm especially interested in how the various timestamping options are configured and what the underlying data representation looks like. Let's dig in and see what's what.



36/3 2026/08/13 22:55 tool read-file
0m Args:
{
  "File": "include/uapi/linux/net_tstamp.h",
  "FirstLine": 85,
  "LineCount": 20
}

Results:
{
  "Contents": "  85:\t * ifr_data pointer to this structure.  For %SIOCSHWTSTAMP, if the\n  86:\t * driver or hardware does not support the requested @rx_filter value,\n  87:\t * the driver may use a more general filter mode.  In this case\n  88:\t * @rx_filter will indicate the actual mode on return.\n  89:\t */\n  90:\tstruct hwtstamp_config {\n  91:\t\tint flags;\n  92:\t\tint tx_type;\n  93:\t\tint rx_filter;\n  94:\t};\n  95:\t\n  96:\t/* possible values for hwtstamp_config-\u003eflags */\n  97:\tenum hwtstamp_flags {\n  98:\t\t/*\n  99:\t\t * With this flag, the user could get bond active interface's\n 100:\t\t * PHC index. Note this PHC index is not stable as when there\n 101:\t\t * is a failover, the bond active interface will be changed, so\n 102:\t\t * will be the PHC index.\n 103:\t\t */\n 104:\t\tHWTSTAMP_FLAG_BONDED_PHC_INDEX = (1\u003c\u003c0),\n"
}

37/3 2026/08/13 22:55 llm kmsan-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 28660
							output: 25
							thoughts: 1653
						

Thoughts:
**Analyzing Potential Uninitialized Memory Issues in the Hardware Timestamping Code**

Okay, let's break this down systematically. I'm focusing on the potential for uninitialized memory usage, particularly within the hardware timestamping (HWTSTAMP) functionality.

First, I examined the `struct hwtstamp_config`. It has three `int` fields: `flags`, `tx_type`, and `rx_filter`, totaling 12 bytes. There's no padding, which is good.  `hwtstamp_config_from_kernel` initializes all 12 bytes when copying data from the kernel to user space, eliminating any immediate concerns there.

Then, I looked at `nsim_get_ts_config`. It retrieves the timestamp configuration. The `ns->tstamp_config` variable, which is a `struct kernel_hwtstamp_config`, is being copied directly to the `config` struct. Importantly, `netdev_priv(netdev)` is zeroed out by `alloc_netdev`, and so `ns->tstamp_config` is initialized to zero when the net device is allocated.  This means the data copied is initialized before the copy happens. The `kernel_cfg` in `dev_get_hwtstamp` is initialized to `{}`. `hwtstamp_config_from_kernel` copies `flags`, `tx_type`, `rx_filter` from `kernel_cfg` to `cfg`. Finally, `copy_to_user` copies `cfg` to user space.  Since everything's initialized, no uninitialized memory leaks are present.

Next, I investigated `nsim_set_ts_config`. I noted that the `ns->tstamp_config.rx_filter` is assigned a value in the `switch` statement, and that the `ns->tstamp_config.tx_type` is written using `WRITE_ONCE`. However, `ns->tstamp_config.flags` remains at its initial zero value. However, because the structure is zero initialized, it is fully initialized.

Now, let's move on to the `nsim_start_xmit` function. Here, a `struct skb_shared_hwtstamps shhwtstamps = {};` is declared and initialized to zero. I saw `tx_ts` and `rx_ts` being uninitialized initially, but the crucial point is that, if `ptp_info_tx` or `ptp_info_rx` are true, those variables are fully initialized via `ptp_info->gettime64`. And because the gettime64 function populates `tx_ts` and `rx_ts`, which is what I saw in `mock_phc_gettime64`, the `struct timespec64` is filled and they are initialized. `ns_to_timespec64` returns a fully initialized `struct timespec64`. So, `shhwtstamps` gets the time and then it is copied to the skb. No uninitialized memory gets used. And lastly, `skb_hwtstamps(skb)->hwtstamp = timespec64_to_ktime(rx_ts);` assigns a value to the `hwtstamp` member of `skb_shinfo(skb)->hwtstamps`. In short, I'm confirming that the timestamps are properly populated before being used, regardless of whether TX or RX timestamping is enabled.

I've carefully examined all the code paths where these timestamp structures are used, and I'm confident that there are no uninitialized memory access issues. All of the variables are properly initialized before being read or copied.



38/3 2026/08/13 22:55 tool grepper
0m Args:
{
  "Expression": "struct skb_shared_hwtstamps \\{"
}

Results:
{
  "Output": "Documentation/networking/timestamping.rst=636=set the time stamps in the structure::\nDocumentation/networking/timestamping.rst-637-\nDocumentation/networking/timestamping.rst:638:    struct skb_shared_hwtstamps {\nDocumentation/networking/timestamping.rst-639-\t    /* hardware time stamp transformed into duration\n--\nDocumentation/translations/zh_CN/networking/timestamping.rst=517=skb_hwtstamps()。然后设置结构中的时间戳::\nDocumentation/translations/zh_CN/networking/timestamping.rst-518-\nDocumentation/translations/zh_CN/networking/timestamping.rst:519:    struct skb_shared_hwtstamps {\nDocumentation/translations/zh_CN/networking/timestamping.rst-520-\t    /* 硬件时间戳转换为自任意时间点的持续时间\n--\ninclude/linux/skbuff.h=410=static inline bool skb_frag_must_loop(struct page *p)\n--\ninclude/linux/skbuff.h-461- */\ninclude/linux/skbuff.h:462:struct skb_shared_hwtstamps {\ninclude/linux/skbuff.h-463-\tunion {\n"
}

39/3 2026/08/13 22:55 llm kmsan-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 31441
							output: 36
							thoughts: 21
						

Thoughts:
Here's a summary of my thinking, expressed in the first person:

**Diving into the Network Packet Core**

Okay, time to dig into the heart of the network stack. I'm going to focus on the `include/linux/skbuff.h` file, specifically around line 462. This section is likely where a core data structure for network packets, the `sk_buff` structure, is defined, or where crucial manipulation functions are declared. I expect to see the basic building blocks of network packet representation and how the kernel handles them. My gut tells me this will give me a good handle on memory layout, how headers are added and removed, and the overall lifecycle of a packet as it traverses the kernel. This is probably a good spot to re-familiarize myself with the basics before tackling a more specific issue I'm working on.



40/3 2026/08/13 22:55 tool read-file
0m Args:
{
  "File": "include/linux/skbuff.h",
  "FirstLine": 455,
  "LineCount": 20
}

Results:
{
  "Contents": " 455:\t *\n 456:\t * hwtstamps can only be compared against other hwtstamps from\n 457:\t * the same device.\n 458:\t *\n 459:\t * This structure is attached to packets as part of the\n 460:\t * \u0026skb_shared_info. Use skb_hwtstamps() to get a pointer.\n 461:\t */\n 462:\tstruct skb_shared_hwtstamps {\n 463:\t\tunion {\n 464:\t\t\tktime_t\thwtstamp;\n 465:\t\t\tvoid *netdev_data;\n 466:\t\t};\n 467:\t};\n 468:\t\n 469:\t/* Definitions for tx_flags in struct skb_shared_info */\n 470:\tenum {\n 471:\t\t/* generate hardware time stamp */\n 472:\t\tSKBTX_HW_TSTAMP_NOBPF = 1 \u003c\u003c 0,\n 473:\t\n 474:\t\t/* generate software time stamp when queueing packet to NIC */\n"
}

41/3 2026/08/13 22:55 llm kmsan-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 31975
							output: 25
							thoughts: 385
						

Thoughts:
**Analyzing Hardware Timestamping in Network Device Simulation**

Okay, so I'm looking at this `skb_shared_hwtstamps` struct. It's pretty straightforward – just a union containing a `ktime_t` and a `void *`, making it 8 bytes total. No wasted space or uninitialized memory, which is good. That's a nice, simple structure.

Now, let's dive into `nsim_get_ts_info`. It takes a `net_device` and a `kernel_ethtool_ts_info` as input. I see it calls `ethtool_op_get_ts_info` first – so that presumably handles the initial setup of `info`. I need to remember to look at what that does. After that, it checks for a `phc` within `ns`. If there's no PHC it returns with `phc_index` of -1. Otherwise, it calls `mock_phc_index` to get the PHC index. A negative return from that function also causes an early return.

Assuming we get past that, it sets the timestamping flags in `info` to indicate hardware support for TX and RX, including raw hardware timestamps. Then, it sets the TX types to include both TX off and TX on. And the RX filters allow everything. Looks like a pretty standard setup for a simulated hardware timestamping device. I'll need to check how `ethtool_op_get_ts_info` fills the struct to get a complete picture, but this part gives me a good overview of how the device reports its capabilities.



42/3 2026/08/13 22:55 tool grepper
0m Args:
{
  "Expression": "ethtool_op_get_ts_info"
}

Results:
{
  "Output": "\nFull output is too long, showing 500 out of 628 lines.\nUse more precise expression if possible.\n\narch/um/drivers/vector_kern.c=1503=static const struct ethtool_ops vector_net_ethtool_ops = {\n--\narch/um/drivers/vector_kern.c-1506-\t.get_link\t= ethtool_op_get_link,\narch/um/drivers/vector_kern.c:1507:\t.get_ts_info\t= ethtool_op_get_ts_info,\narch/um/drivers/vector_kern.c-1508-\t.get_ringparam\t= vector_get_ringparam,\n--\ndrivers/net/can/at91_can.c=953=static const struct ethtool_ops at91_ethtool_ops = {\ndrivers/net/can/at91_can.c:954:\t.get_ts_info = ethtool_op_get_ts_info,\ndrivers/net/can/at91_can.c-955-};\n--\ndrivers/net/can/bxcan.c=886=static const struct ethtool_ops bxcan_ethtool_ops = {\ndrivers/net/can/bxcan.c:887:\t.get_ts_info = ethtool_op_get_ts_info,\ndrivers/net/can/bxcan.c-888-};\n--\ndrivers/net/can/c_can/c_can_ethtool.c=27=const struct ethtool_ops c_can_ethtool_ops = {\ndrivers/net/can/c_can/c_can_ethtool.c-28-\t.get_ringparam = c_can_get_ringparam,\ndrivers/net/can/c_can/c_can_ethtool.c:29:\t.get_ts_info = ethtool_op_get_ts_info,\ndrivers/net/can/c_can/c_can_ethtool.c-30-};\n--\ndrivers/net/can/can327.c=855=static const struct ethtool_ops can327_ethtool_ops = {\ndrivers/net/can/can327.c:856:\t.get_ts_info = ethtool_op_get_ts_info,\ndrivers/net/can/can327.c-857-};\n--\ndrivers/net/can/cc770/cc770.c=839=static const struct ethtool_ops cc770_ethtool_ops = {\ndrivers/net/can/cc770/cc770.c:840:\t.get_ts_info = ethtool_op_get_ts_info,\ndrivers/net/can/cc770/cc770.c-841-};\n--\ndrivers/net/can/ctucanfd/ctucanfd_base.c=1310=static const struct ethtool_ops ctucan_ethtool_ops = {\ndrivers/net/can/ctucanfd/ctucanfd_base.c:1311:\t.get_ts_info = ethtool_op_get_ts_info,\ndrivers/net/can/ctucanfd/ctucanfd_base.c-1312-};\n--\ndrivers/net/can/dev/dev.c=452=EXPORT_SYMBOL(can_hwtstamp_set);\n--\ndrivers/net/can/dev/dev.c-456- */\ndrivers/net/can/dev/dev.c:457:int can_ethtool_op_get_ts_info_hwts(struct net_device *dev,\ndrivers/net/can/dev/dev.c-458-\t\t\t\t    struct kernel_ethtool_ts_info *info)\n--\ndrivers/net/can/dev/dev.c-469-}\ndrivers/net/can/dev/dev.c:470:EXPORT_SYMBOL(can_ethtool_op_get_ts_info_hwts);\ndrivers/net/can/dev/dev.c-471-\n--\ndrivers/net/can/dummy_can.c=228=static const struct ethtool_ops dummy_can_ethtool_ops = {\ndrivers/net/can/dummy_can.c:229:\t.get_ts_info = ethtool_op_get_ts_info,\ndrivers/net/can/dummy_can.c-230-};\n--\ndrivers/net/can/esd/esd_402_pci-core.c=93=static const struct ethtool_ops pci402_acc_ethtool_ops = {\ndrivers/net/can/esd/esd_402_pci-core.c:94:\t.get_ts_info = can_ethtool_op_get_ts_info_hwts,\ndrivers/net/can/esd/esd_402_pci-core.c-95-};\n--\ndrivers/net/can/flexcan/flexcan-ethtool.c=103=const struct ethtool_ops flexcan_ethtool_ops = {\n--\ndrivers/net/can/flexcan/flexcan-ethtool.c-108-\t.get_sset_count = flexcan_get_sset_count,\ndrivers/net/can/flexcan/flexcan-ethtool.c:109:\t.get_ts_info = ethtool_op_get_ts_info,\ndrivers/net/can/flexcan/flexcan-ethtool.c-110-};\n--\ndrivers/net/can/grcan.c=1565=static const struct ethtool_ops grcan_ethtool_ops = {\ndrivers/net/can/grcan.c:1566:\t.get_ts_info = ethtool_op_get_ts_info,\ndrivers/net/can/grcan.c-1567-};\n--\ndrivers/net/can/ifi_canfd/ifi_canfd.c=949=static const struct ethtool_ops ifi_canfd_ethtool_ops = {\ndrivers/net/can/ifi_canfd/ifi_canfd.c:950:\t.get_ts_info = ethtool_op_get_ts_info,\ndrivers/net/can/ifi_canfd/ifi_canfd.c-951-};\n--\ndrivers/net/can/janz-ican3.c=1757=static const struct ethtool_ops ican3_ethtool_ops = {\ndrivers/net/can/janz-ican3.c:1758:\t.get_ts_info = ethtool_op_get_ts_info,\ndrivers/net/can/janz-ican3.c-1759-};\n--\ndrivers/net/can/kvaser_pciefd/kvaser_pciefd_core.c=933=static const struct ethtool_ops kvaser_pciefd_ethtool_ops = {\ndrivers/net/can/kvaser_pciefd/kvaser_pciefd_core.c:934:\t.get_ts_info = can_ethtool_op_get_ts_info_hwts,\ndrivers/net/can/kvaser_pciefd/kvaser_pciefd_core.c-935-\t.set_phys_id = kvaser_pciefd_set_phys_id,\n--\ndrivers/net/can/m_can/m_can.c=2310=static const struct ethtool_ops m_can_ethtool_ops_coalescing = {\n--\ndrivers/net/can/m_can/m_can.c-2315-\t\tETHTOOL_COALESCE_TX_MAX_FRAMES_IRQ,\ndrivers/net/can/m_can/m_can.c:2316:\t.get_ts_info = ethtool_op_get_ts_info,\ndrivers/net/can/m_can/m_can.c-2317-\t.get_coalesce = m_can_get_coalesce,\n--\ndrivers/net/can/m_can/m_can.c=2323=static const struct ethtool_ops m_can_ethtool_ops = {\ndrivers/net/can/m_can/m_can.c:2324:\t.get_ts_info = ethtool_op_get_ts_info,\ndrivers/net/can/m_can/m_can.c-2325-\t.get_wol = m_can_get_wol,\n--\ndrivers/net/can/mscan/mscan.c=612=static const struct ethtool_ops mscan_ethtool_ops = {\ndrivers/net/can/mscan/mscan.c:613:\t.get_ts_info = ethtool_op_get_ts_info,\ndrivers/net/can/mscan/mscan.c-614-};\n--\ndrivers/net/can/rcar/rcar_can.c=639=static const struct ethtool_ops rcar_can_ethtool_ops = {\ndrivers/net/can/rcar/rcar_can.c:640:\t.get_ts_info = ethtool_op_get_ts_info,\ndrivers/net/can/rcar/rcar_can.c-641-};\n--\ndrivers/net/can/rcar/rcar_canfd.c=1859=static const struct ethtool_ops rcar_canfd_ethtool_ops = {\ndrivers/net/can/rcar/rcar_canfd.c:1860:\t.get_ts_info = ethtool_op_get_ts_info,\ndrivers/net/can/rcar/rcar_canfd.c-1861-};\n--\ndrivers/net/can/rockchip/rockchip_canfd-ethtool.c=61=static const struct ethtool_ops rkcanfd_ethtool_ops = {\ndrivers/net/can/rockchip/rockchip_canfd-ethtool.c:62:\t.get_ts_info = can_ethtool_op_get_ts_info_hwts,\ndrivers/net/can/rockchip/rockchip_canfd-ethtool.c-63-\t.get_strings = rkcanfd_ethtool_get_strings,\n--\ndrivers/net/can/sja1000/sja1000.c=682=static const struct ethtool_ops sja1000_ethtool_ops = {\ndrivers/net/can/sja1000/sja1000.c:683:\t.get_ts_info = ethtool_op_get_ts_info,\ndrivers/net/can/sja1000/sja1000.c-684-};\n--\ndrivers/net/can/slcan/slcan-ethtool.c=55=const struct ethtool_ops slcan_ethtool_ops = {\n--\ndrivers/net/can/slcan/slcan-ethtool.c-59-\t.get_sset_count = slcan_get_sset_count,\ndrivers/net/can/slcan/slcan-ethtool.c:60:\t.get_ts_info = ethtool_op_get_ts_info,\ndrivers/net/can/slcan/slcan-ethtool.c-61-};\n--\ndrivers/net/can/softing/softing_main.c=614=static const struct ethtool_ops softing_ethtool_ops = {\ndrivers/net/can/softing/softing_main.c:615:\t.get_ts_info = ethtool_op_get_ts_info,\ndrivers/net/can/softing/softing_main.c-616-};\n--\ndrivers/net/can/spi/hi311x.c=806=static const struct ethtool_ops hi3110_ethtool_ops = {\ndrivers/net/can/spi/hi311x.c:807:\t.get_ts_info = ethtool_op_get_ts_info,\ndrivers/net/can/spi/hi311x.c-808-};\n--\ndrivers/net/can/spi/mcp251x.c=1293=static const struct ethtool_ops mcp251x_ethtool_ops = {\ndrivers/net/can/spi/mcp251x.c:1294:\t.get_ts_info = ethtool_op_get_ts_info,\ndrivers/net/can/spi/mcp251x.c-1295-};\n--\ndrivers/net/can/spi/mcp251xfd/mcp251xfd-ethtool.c=119=static const struct ethtool_ops mcp251xfd_ethtool_ops = {\n--\ndrivers/net/can/spi/mcp251xfd/mcp251xfd-ethtool.c-127-\t.set_coalesce = mcp251xfd_ring_set_coalesce,\ndrivers/net/can/spi/mcp251xfd/mcp251xfd-ethtool.c:128:\t.get_ts_info = can_ethtool_op_get_ts_info_hwts,\ndrivers/net/can/spi/mcp251xfd/mcp251xfd-ethtool.c-129-};\n--\ndrivers/net/can/sun4i_can.c=773=static const struct ethtool_ops sun4ican_ethtool_ops = {\ndrivers/net/can/sun4i_can.c:774:\t.get_ts_info = ethtool_op_get_ts_info,\ndrivers/net/can/sun4i_can.c-775-};\n--\ndrivers/net/can/ti_hecc.c=834=static const struct ethtool_ops ti_hecc_ethtool_ops = {\ndrivers/net/can/ti_hecc.c:835:\t.get_ts_info = ethtool_op_get_ts_info,\ndrivers/net/can/ti_hecc.c-836-};\n--\ndrivers/net/can/usb/ems_usb.c=944=static const struct ethtool_ops ems_usb_ethtool_ops = {\ndrivers/net/can/usb/ems_usb.c:945:\t.get_ts_info = ethtool_op_get_ts_info,\ndrivers/net/can/usb/ems_usb.c-946-};\n--\ndrivers/net/can/usb/esd_usb.c=1019=static const struct ethtool_ops esd_usb_ethtool_ops = {\ndrivers/net/can/usb/esd_usb.c:1020:\t.get_ts_info = ethtool_op_get_ts_info,\ndrivers/net/can/usb/esd_usb.c-1021-};\n--\ndrivers/net/can/usb/etas_es58x/es58x_core.c=1988=static const struct ethtool_ops es58x_ethtool_ops = {\ndrivers/net/can/usb/etas_es58x/es58x_core.c:1989:\t.get_ts_info = can_ethtool_op_get_ts_info_hwts,\ndrivers/net/can/usb/etas_es58x/es58x_core.c-1990-};\n--\ndrivers/net/can/usb/f81604.c=126=static const struct ethtool_ops f81604_ethtool_ops = {\ndrivers/net/can/usb/f81604.c:127:\t.get_ts_info = ethtool_op_get_ts_info,\ndrivers/net/can/usb/f81604.c-128-};\n--\ndrivers/net/can/usb/gs_usb.c=1256=static int gs_usb_get_ts_info(struct net_device *netdev,\n--\ndrivers/net/can/usb/gs_usb.c-1262-\tif (dev-\u003efeature \u0026 GS_CAN_FEATURE_HW_TIMESTAMP)\ndrivers/net/can/usb/gs_usb.c:1263:\t\treturn can_ethtool_op_get_ts_info_hwts(netdev, info);\ndrivers/net/can/usb/gs_usb.c-1264-\ndrivers/net/can/usb/gs_usb.c:1265:\treturn ethtool_op_get_ts_info(netdev, info);\ndrivers/net/can/usb/gs_usb.c-1266-}\n--\ndrivers/net/can/usb/kvaser_usb/kvaser_usb_core.c=799=static const struct ethtool_ops kvaser_usb_ethtool_ops = {\ndrivers/net/can/usb/kvaser_usb/kvaser_usb_core.c:800:\t.get_ts_info = can_ethtool_op_get_ts_info_hwts,\ndrivers/net/can/usb/kvaser_usb/kvaser_usb_core.c-801-\t.set_phys_id = kvaser_usb_set_phys_id,\n--\ndrivers/net/can/usb/mcba_usb.c=772=static const struct ethtool_ops mcba_ethtool_ops = {\ndrivers/net/can/usb/mcba_usb.c:773:\t.get_ts_info = ethtool_op_get_ts_info,\ndrivers/net/can/usb/mcba_usb.c-774-};\n--\ndrivers/net/can/usb/nct6694_canfd.c=695=static const struct ethtool_ops nct6694_canfd_ethtool_ops = {\ndrivers/net/can/usb/nct6694_canfd.c:696:\t.get_ts_info = ethtool_op_get_ts_info,\ndrivers/net/can/usb/nct6694_canfd.c-697-};\n--\ndrivers/net/can/usb/ucan.c=1237=static const struct ethtool_ops ucan_ethtool_ops = {\ndrivers/net/can/usb/ucan.c:1238:\t.get_ts_info = ethtool_op_get_ts_info,\ndrivers/net/can/usb/ucan.c-1239-};\n--\ndrivers/net/can/usb/usb_8dev.c=879=static const struct ethtool_ops usb_8dev_ethtool_ops = {\ndrivers/net/can/usb/usb_8dev.c:880:\t.get_ts_info = ethtool_op_get_ts_info,\ndrivers/net/can/usb/usb_8dev.c-881-};\n--\ndrivers/net/can/vcan.c=166=static const struct ethtool_ops vcan_ethtool_ops = {\ndrivers/net/can/vcan.c:167:\t.get_ts_info = ethtool_op_get_ts_info,\ndrivers/net/can/vcan.c-168-};\n--\ndrivers/net/can/vxcan.c=177=static const struct ethtool_ops vxcan_ethtool_ops = {\ndrivers/net/can/vxcan.c:178:\t.get_ts_info = ethtool_op_get_ts_info,\ndrivers/net/can/vxcan.c-179-};\n--\ndrivers/net/can/xilinx_can.c=1707=static const struct ethtool_ops xcan_ethtool_ops = {\ndrivers/net/can/xilinx_can.c:1708:\t.get_ts_info = ethtool_op_get_ts_info,\ndrivers/net/can/xilinx_can.c-1709-\t.get_strings = xcan_get_strings,\n--\ndrivers/net/dummy.c=99=static const struct ethtool_ops dummy_ethtool_ops = {\ndrivers/net/dummy.c:100:\t.get_ts_info\t\t= ethtool_op_get_ts_info,\ndrivers/net/dummy.c-101-};\n--\ndrivers/net/ethernet/3com/3c59x.c=3009=static const struct ethtool_ops vortex_ethtool_ops = {\n--\ndrivers/net/ethernet/3com/3c59x.c-3019-\t.set_wol                = vortex_set_wol,\ndrivers/net/ethernet/3com/3c59x.c:3020:\t.get_ts_info\t\t= ethtool_op_get_ts_info,\ndrivers/net/ethernet/3com/3c59x.c-3021-\t.get_link_ksettings     = vortex_get_link_ksettings,\n--\ndrivers/net/ethernet/8390/ax88796.c=601=static const struct ethtool_ops ax_ethtool_ops = {\n--\ndrivers/net/ethernet/8390/ax88796.c-603-\t.get_link\t\t= ethtool_op_get_link,\ndrivers/net/ethernet/8390/ax88796.c:604:\t.get_ts_info\t\t= ethtool_op_get_ts_info,\ndrivers/net/ethernet/8390/ax88796.c-605-\t.get_msglevel\t\t= ax_get_msglevel,\n--\ndrivers/net/ethernet/8390/etherh.c=624=static const struct ethtool_ops etherh_ethtool_ops = {\ndrivers/net/ethernet/8390/etherh.c-625-\t.get_drvinfo\t\t= etherh_get_drvinfo,\ndrivers/net/ethernet/8390/etherh.c:626:\t.get_ts_info\t\t= ethtool_op_get_ts_info,\ndrivers/net/ethernet/8390/etherh.c-627-\t.get_msglevel\t\t= etherh_get_msglevel,\n--\ndrivers/net/ethernet/altera/altera_tse_ethtool.c=240=static const struct ethtool_ops tse_ethtool_ops = {\n--\ndrivers/net/ethernet/altera/altera_tse_ethtool.c-251-\t.set_link_ksettings = tse_ethtool_set_link_ksettings,\ndrivers/net/ethernet/altera/altera_tse_ethtool.c:252:\t.get_ts_info = ethtool_op_get_ts_info,\ndrivers/net/ethernet/altera/altera_tse_ethtool.c-253-};\n--\ndrivers/net/ethernet/aquantia/atlantic/aq_ethtool.c=653=static int aq_ethtool_get_ts_info(struct net_device *ndev,\n--\ndrivers/net/ethernet/aquantia/atlantic/aq_ethtool.c-657-\ndrivers/net/ethernet/aquantia/atlantic/aq_ethtool.c:658:\tethtool_op_get_ts_info(ndev, info);\ndrivers/net/ethernet/aquantia/atlantic/aq_ethtool.c-659-\n--\ndrivers/net/ethernet/atheros/ag71xx.c=542=static const struct ethtool_ops ag71xx_ethtool_ops = {\n--\ndrivers/net/ethernet/atheros/ag71xx.c-544-\t.get_link\t\t\t= ethtool_op_get_link,\ndrivers/net/ethernet/atheros/ag71xx.c:545:\t.get_ts_info\t\t\t= ethtool_op_get_ts_info,\ndrivers/net/ethernet/atheros/ag71xx.c-546-\t.get_link_ksettings\t\t= ag71xx_get_link_ksettings,\n--\ndrivers/net/ethernet/broadcom/asp2/bcmasp_ethtool.c=443=const struct ethtool_ops bcmasp_ethtool_ops = {\n--\ndrivers/net/ethernet/broadcom/asp2/bcmasp_ethtool.c-461-\t.get_sset_count\t\t= bcmasp_get_sset_count,\ndrivers/net/ethernet/broadcom/asp2/bcmasp_ethtool.c:462:\t.get_ts_info\t\t= ethtool_op_get_ts_info,\ndrivers/net/ethernet/broadcom/asp2/bcmasp_ethtool.c-463-\t.nway_reset\t\t= phy_ethtool_nway_reset,\n--\ndrivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c=3613=static int bnx2x_get_ts_info(struct net_device *dev,\n--\ndrivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c-3636-\ndrivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c:3637:\treturn ethtool_op_get_ts_info(dev, info);\ndrivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c-3638-}\n--\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c=1678=static const struct ethtool_ops bcmgenet_ethtool_ops = {\n--\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c-1699-\t.set_link_ksettings\t= bcmgenet_set_link_ksettings,\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c:1700:\t.get_ts_info\t\t= ethtool_op_get_ts_info,\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c-1701-\t.get_rxnfc\t\t= bcmgenet_get_rxnfc,\n--\ndrivers/net/ethernet/brocade/bna/bnad_ethtool.c=1069=static const struct ethtool_ops bnad_ethtool_ops = {\n--\ndrivers/net/ethernet/brocade/bna/bnad_ethtool.c-1088-\t.flash_device = bnad_flash_device,\ndrivers/net/ethernet/brocade/bna/bnad_ethtool.c:1089:\t.get_ts_info = ethtool_op_get_ts_info,\ndrivers/net/ethernet/brocade/bna/bnad_ethtool.c-1090-\t.get_link_ksettings = bnad_get_link_ksettings,\n--\ndrivers/net/ethernet/cadence/macb_main.c=3774=static int gem_get_ts_info(struct net_device *dev,\n--\ndrivers/net/ethernet/cadence/macb_main.c-3779-\tif (!macb_dma_ptp(bp)) {\ndrivers/net/ethernet/cadence/macb_main.c:3780:\t\tethtool_op_get_ts_info(dev, info);\ndrivers/net/ethernet/cadence/macb_main.c-3781-\t\treturn 0;\n--\ndrivers/net/ethernet/cadence/macb_main.c=3814=static int macb_get_ts_info(struct net_device *netdev,\n--\ndrivers/net/ethernet/cadence/macb_main.c-3821-\ndrivers/net/ethernet/cadence/macb_main.c:3822:\treturn ethtool_op_get_ts_info(netdev, info);\ndrivers/net/ethernet/cadence/macb_main.c-3823-}\n--\ndrivers/net/ethernet/cadence/macb_main.c=4140=static const struct ethtool_ops macb_ethtool_ops = {\n--\ndrivers/net/ethernet/cadence/macb_main.c-4143-\t.get_link\t\t= ethtool_op_get_link,\ndrivers/net/ethernet/cadence/macb_main.c:4144:\t.get_ts_info\t\t= ethtool_op_get_ts_info,\ndrivers/net/ethernet/cadence/macb_main.c-4145-\t.get_pause_stats\t= macb_get_pause_stats,\n--\ndrivers/net/ethernet/cavium/thunder/nicvf_ethtool.c=818=static int nicvf_get_ts_info(struct net_device *netdev,\n--\ndrivers/net/ethernet/cavium/thunder/nicvf_ethtool.c-823-\tif (!nic-\u003eptp_clock)\ndrivers/net/ethernet/cavium/thunder/nicvf_ethtool.c:824:\t\treturn ethtool_op_get_ts_info(netdev, info);\ndrivers/net/ethernet/cavium/thunder/nicvf_ethtool.c-825-\n--\ndrivers/net/ethernet/ethoc.c=997=static const struct ethtool_ops ethoc_ethtool_ops = {\n--\ndrivers/net/ethernet/ethoc.c-1003-\t.set_ringparam = ethoc_set_ringparam,\ndrivers/net/ethernet/ethoc.c:1004:\t.get_ts_info = ethtool_op_get_ts_info,\ndrivers/net/ethernet/ethoc.c-1005-\t.get_link_ksettings = phy_ethtool_get_link_ksettings,\n--\ndrivers/net/ethernet/freescale/dpaa2/dpaa2-ethtool.c=805=static int dpaa2_eth_get_ts_info(struct net_device *dev,\n--\ndrivers/net/ethernet/freescale/dpaa2/dpaa2-ethtool.c-808-\tif (!dpaa2_ptp)\ndrivers/net/ethernet/freescale/dpaa2/dpaa2-ethtool.c:809:\t\treturn ethtool_op_get_ts_info(dev, info);\ndrivers/net/ethernet/freescale/dpaa2/dpaa2-ethtool.c-810-\n--\ndrivers/net/ethernet/freescale/fec_main.c=3329=static int fec_enet_get_ts_info(struct net_device *ndev,\n--\ndrivers/net/ethernet/freescale/fec_main.c-3349-\t} else {\ndrivers/net/ethernet/freescale/fec_main.c:3350:\t\treturn ethtool_op_get_ts_info(ndev, info);\ndrivers/net/ethernet/freescale/fec_main.c-3351-\t}\n--\ndrivers/net/ethernet/freescale/fec_mpc52xx.c=781=static const struct ethtool_ops mpc52xx_fec_ethtool_ops = {\n--\ndrivers/net/ethernet/freescale/fec_mpc52xx.c-784-\t.set_msglevel = mpc52xx_fec_set_msglevel,\ndrivers/net/ethernet/freescale/fec_mpc52xx.c:785:\t.get_ts_info = ethtool_op_get_ts_info,\ndrivers/net/ethernet/freescale/fec_mpc52xx.c-786-\t.get_link_ksettings = phy_ethtool_get_link_ksettings,\n--\ndrivers/net/ethernet/freescale/fs_enet/fs_enet-main.c=812=static const struct ethtool_ops fs_ethtool_ops = {\n--\ndrivers/net/ethernet/freescale/fs_enet/fs_enet-main.c-819-\t.get_regs = fs_get_regs,\ndrivers/net/ethernet/freescale/fs_enet/fs_enet-main.c:820:\t.get_ts_info = ethtool_op_get_ts_info,\ndrivers/net/ethernet/freescale/fs_enet/fs_enet-main.c-821-\t.get_link_ksettings = fs_ethtool_get_link_ksettings,\n--\ndrivers/net/ethernet/freescale/ucc_geth_ethtool.c=359=static const struct ethtool_ops uec_ethtool_ops = {\n--\ndrivers/net/ethernet/freescale/ucc_geth_ethtool.c-375-\t.set_wol\t\t= uec_set_wol,\ndrivers/net/ethernet/freescale/ucc_geth_ethtool.c:376:\t.get_ts_info\t\t= ethtool_op_get_ts_info,\ndrivers/net/ethernet/freescale/ucc_geth_ethtool.c-377-\t.get_link_ksettings\t= uec_get_ksettings,\n--\ndrivers/net/ethernet/google/gve/gve_ethtool.c=961=static int gve_get_ts_info(struct net_device *netdev,\n--\ndrivers/net/ethernet/google/gve/gve_ethtool.c-965-\ndrivers/net/ethernet/google/gve/gve_ethtool.c:966:\tethtool_op_get_ts_info(netdev, info);\ndrivers/net/ethernet/google/gve/gve_ethtool.c-967-\n--\ndrivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c=2054=static int hns3_get_ts_info(struct net_device *netdev,\n--\ndrivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c-2061-\ndrivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c:2062:\treturn ethtool_op_get_ts_info(netdev, info);\ndrivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c-2063-}\n--\ndrivers/net/ethernet/intel/e100.c=2736=static const struct ethtool_ops e100_ethtool_ops = {\n--\ndrivers/net/ethernet/intel/e100.c-2755-\t.get_sset_count\t\t= e100_get_sset_count,\ndrivers/net/ethernet/intel/e100.c:2756:\t.get_ts_info\t\t= ethtool_op_get_ts_info,\ndrivers/net/ethernet/intel/e100.c-2757-\t.get_link_ksettings\t= e100_get_link_ksettings,\n--\ndrivers/net/ethernet/intel/e1000/e1000_ethtool.c=1864=static const struct ethtool_ops e1000_ethtool_ops = {\n--\ndrivers/net/ethernet/intel/e1000/e1000_ethtool.c-1888-\t.set_coalesce\t\t= e1000_set_coalesce,\ndrivers/net/ethernet/intel/e1000/e1000_ethtool.c:1889:\t.get_ts_info\t\t= ethtool_op_get_ts_info,\ndrivers/net/ethernet/intel/e1000/e1000_ethtool.c-1890-\t.get_link_ksettings\t= e1000_get_link_ksettings,\n--\ndrivers/net/ethernet/intel/e1000e/ethtool.c=2263=static int e1000e_get_ts_info(struct net_device *netdev,\n--\ndrivers/net/ethernet/intel/e1000e/ethtool.c-2267-\ndrivers/net/ethernet/intel/e1000e/ethtool.c:2268:\tethtool_op_get_ts_info(netdev, info);\ndrivers/net/ethernet/intel/e1000e/ethtool.c-2269-\n--\ndrivers/net/ethernet/intel/fm10k/fm10k_ethtool.c=1136=static const struct ethtool_ops fm10k_ethtool_ops = {\n--\ndrivers/net/ethernet/intel/fm10k/fm10k_ethtool.c-1165-\t.set_channels\t\t= fm10k_set_channels,\ndrivers/net/ethernet/intel/fm10k/fm10k_ethtool.c:1166:\t.get_ts_info\t\t= ethtool_op_get_ts_info,\ndrivers/net/ethernet/intel/fm10k/fm10k_ethtool.c-1167-};\n--\ndrivers/net/ethernet/intel/i40e/i40e_ethtool.c=2538=static int i40e_get_ts_info(struct net_device *dev,\n--\ndrivers/net/ethernet/intel/i40e/i40e_ethtool.c-2544-\tif (!test_bit(I40E_FLAG_PTP_ENA, pf-\u003eflags))\ndrivers/net/ethernet/intel/i40e/i40e_ethtool.c:2545:\t\treturn ethtool_op_get_ts_info(dev, info);\ndrivers/net/ethernet/intel/i40e/i40e_ethtool.c-2546-\n--\ndrivers/net/ethernet/intel/ice/ice_ethtool.c=3767=ice_get_ts_info(struct net_device *dev, struct kernel_ethtool_ts_info *info)\n--\ndrivers/net/ethernet/intel/ice/ice_ethtool.c-3772-\tif (pf-\u003eptp.state != ICE_PTP_READY)\ndrivers/net/ethernet/intel/ice/ice_ethtool.c:3773:\t\treturn ethtool_op_get_ts_info(dev, info);\ndrivers/net/ethernet/intel/ice/ice_ethtool.c-3774-\n--\ndrivers/net/ethernet/intel/idpf/idpf_ethtool.c=1712=static int idpf_get_ts_info(struct net_device *netdev,\n--\ndrivers/net/ethernet/intel/idpf/idpf_ethtool.c-1734-\t\tpci_dbg(vport-\u003eadapter-\u003epdev, \"PTP clock not detected\\n\");\ndrivers/net/ethernet/intel/idpf/idpf_ethtool.c:1735:\t\terr = ethtool_op_get_ts_info(netdev, info);\ndrivers/net/ethernet/intel/idpf/idpf_ethtool.c-1736-\t}\n--\ndrivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c=3306=static int ixgbe_get_ts_info(struct net_device *dev,\n--\ndrivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c-3328-\tdefault:\ndrivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c:3329:\t\treturn ethtool_op_get_ts_info(dev, info);\ndrivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c-3330-\t}\n--\ndrivers/net/ethernet/marvell/mv643xx_eth.c=1741=static const struct ethtool_ops mv643xx_eth_ethtool_ops = {\n--\ndrivers/net/ethernet/marvell/mv643xx_eth.c-1752-\t.get_sset_count\t\t= mv643xx_eth_get_sset_count,\ndrivers/net/ethernet/marvell/mv643xx_eth.c:1753:\t.get_ts_info\t\t= ethtool_op_get_ts_info,\ndrivers/net/ethernet/marvell/mv643xx_eth.c-1754-\t.get_wol                = mv643xx_eth_get_wol,\n--\ndrivers/net/ethernet/marvell/mvneta.c=5335=static const struct ethtool_ops mvneta_eth_tool_ops = {\n--\ndrivers/net/ethernet/marvell/mvneta.c-5357-\t.set_wol        = mvneta_ethtool_set_wol,\ndrivers/net/ethernet/marvell/mvneta.c:5358:\t.get_ts_info\t= ethtool_op_get_ts_info,\ndrivers/net/ethernet/marvell/mvneta.c-5359-\t.get_eee\t= mvneta_ethtool_get_eee,\n--\ndrivers/net/ethernet/marvell/mvpp2/mvpp2_main.c=5265=static int mvpp2_ethtool_get_ts_info(struct net_device *dev,\n--\ndrivers/net/ethernet/marvell/mvpp2/mvpp2_main.c-5269-\ndrivers/net/ethernet/marvell/mvpp2/mvpp2_main.c:5270:\tethtool_op_get_ts_info(dev, info);\ndrivers/net/ethernet/marvell/mvpp2/mvpp2_main.c-5271-\tif (!port-\u003ehwtstamp)\n--\ndrivers/net/ethernet/marvell/octeontx2/nic/otx2_ethtool.c=976=static int otx2_get_ts_info(struct net_device *netdev,\n--\ndrivers/net/ethernet/marvell/octeontx2/nic/otx2_ethtool.c-981-\tif (!pfvf-\u003eptp)\ndrivers/net/ethernet/marvell/octeontx2/nic/otx2_ethtool.c:982:\t\treturn ethtool_op_get_ts_info(netdev, info);\ndrivers/net/ethernet/marvell/octeontx2/nic/otx2_ethtool.c-983-\n--\ndrivers/net/ethernet/marvell/pxa168_eth.c=1363=static const struct ethtool_ops pxa168_ethtool_ops = {\n--\ndrivers/net/ethernet/marvell/pxa168_eth.c-1366-\t.get_link\t= ethtool_op_get_link,\ndrivers/net/ethernet/marvell/pxa168_eth.c:1367:\t.get_ts_info\t= ethtool_op_get_ts_info,\ndrivers/net/ethernet/marvell/pxa168_eth.c-1368-\t.get_link_ksettings = phy_ethtool_get_link_ksettings,\n--\ndrivers/net/ethernet/mellanox/mlx4/en_ethtool.c=1890=static int mlx4_en_get_ts_info(struct net_device *dev,\n--\ndrivers/net/ethernet/mellanox/mlx4/en_ethtool.c-1896-\ndrivers/net/ethernet/mellanox/mlx4/en_ethtool.c:1897:\tret = ethtool_op_get_ts_info(dev, info);\ndrivers/net/ethernet/mellanox/mlx4/en_ethtool.c-1898-\tif (ret)\n--\ndrivers/net/ethernet/microchip/lan966x/lan966x_ethtool.c=540=static int lan966x_get_ts_info(struct net_device *dev,\n--\ndrivers/net/ethernet/microchip/lan966x/lan966x_ethtool.c-547-\tif (!lan966x-\u003eptp)\ndrivers/net/ethernet/microchip/lan966x/lan966x_ethtool.c:548:\t\treturn ethtool_op_get_ts_info(dev, info);\ndrivers/net/ethernet/microchip/lan966x/lan966x_ethtool.c-549-\n--\ndrivers/net/ethernet/microchip/sparx5/sparx5_ethtool.c=1185=static int sparx5_get_ts_info(struct net_device *dev,\n--\ndrivers/net/ethernet/microchip/sparx5/sparx5_ethtool.c-1192-\tif (!sparx5-\u003eptp \u0026\u0026 is_sparx5(sparx5))\ndrivers/net/ethernet/microchip/sparx5/sparx5_ethtool.c:1193:\t\treturn ethtool_op_get_ts_info(dev, info);\ndrivers/net/ethernet/microchip/sparx5/sparx5_ethtool.c-1194-\n--\ndrivers/net/ethernet/mscc/ocelot_net.c=1031=static int ocelot_port_get_ts_info(struct net_device *dev,\n--\ndrivers/net/ethernet/mscc/ocelot_net.c-1038-\tif (!ocelot-\u003eptp)\ndrivers/net/ethernet/mscc/ocelot_net.c:1039:\t\treturn ethtool_op_get_ts_info(dev, info);\ndrivers/net/ethernet/mscc/ocelot_net.c-1040-\n--\ndrivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c=2493=static const struct ethtool_ops nfp_net_ethtool_ops = {\n--\ndrivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c-2535-\t.set_phys_id\t\t= nfp_net_set_phys_id,\ndrivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c:2536:\t.get_ts_info\t\t= ethtool_op_get_ts_info,\ndrivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c-2537-};\n--\ndrivers/net/ethernet/nvidia/forcedeth.c=5341=static const struct ethtool_ops ops = {\n--\ndrivers/net/ethernet/nvidia/forcedeth.c-5356-\t.self_test = nv_self_test,\ndrivers/net/ethernet/nvidia/forcedeth.c:5357:\t.get_ts_info = ethtool_op_get_ts_info,\ndrivers/net/ethernet/nvidia/forcedeth.c-5358-\t.get_link_ksettings = nv_get_link_ksettings,\n--\ndrivers/net/ethernet/pensando/ionic/ionic_ethtool.c=1032=static int ionic_get_ts_info(struct net_device *netdev,\n--\ndrivers/net/ethernet/pensando/ionic/ionic_ethtool.c-1039-\tif (!lif-\u003ephc || !lif-\u003ephc-\u003eptp)\ndrivers/net/ethernet/pensando/ionic/ionic_ethtool.c:1040:\t\treturn ethtool_op_get_ts_info(netdev, info);\ndrivers/net/ethernet/pensando/ionic/ionic_ethtool.c-1041-\n--\ndrivers/net/ethernet/rdc/r6040.c=947=static const struct ethtool_ops netdev_ethtool_ops = {\n--\ndrivers/net/ethernet/rdc/r6040.c-949-\t.get_link\t\t= ethtool_op_get_link,\ndrivers/net/ethernet/rdc/r6040.c:950:\t.get_ts_info\t\t= ethtool_op_get_ts_info,\ndrivers/net/ethernet/rdc/r6040.c-951-\t.get_link_ksettings     = phy_ethtool_get_link_ksettings,\n--\ndrivers/net/ethernet/realtek/r8169_main.c=2419=static const struct ethtool_ops rtl8169_ethtool_ops = {\n--\ndrivers/net/ethernet/realtek/r8169_main.c-2432-\t.get_ethtool_stats\t= rtl8169_get_ethtool_stats,\ndrivers/net/ethernet/realtek/r8169_main.c:2433:\t.get_ts_info\t\t= ethtool_op_get_ts_info,\ndrivers/net/ethernet/realtek/r8169_main.c-2434-\t.nway_reset\t\t= phy_ethtool_nway_reset,\n--\ndrivers/net/ethernet/realtek/rtase/rtase_main.c=2080=static const struct ethtool_ops rtase_ethtool_ops = {\n--\ndrivers/net/ethernet/realtek/rtase/rtase_main.c-2085-\t.get_eth_mac_stats = rtase_get_eth_mac_stats,\ndrivers/net/ethernet/realtek/rtase/rtase_main.c:2086:\t.get_ts_info = ethtool_op_get_ts_info,\ndrivers/net/ethernet/realtek/rtase/rtase_main.c-2087-};\n--\ndrivers/net/ethernet/smsc/smsc911x.c=2131=static const struct ethtool_ops smsc911x_ethtool_ops = {\n--\ndrivers/net/ethernet/smsc/smsc911x.c-2141-\t.set_eeprom = smsc911x_ethtool_set_eeprom,\ndrivers/net/ethernet/smsc/smsc911x.c:2142:\t.get_ts_info = ethtool_op_get_ts_info,\ndrivers/net/ethernet/smsc/smsc911x.c-2143-\t.get_link_ksettings = phy_ethtool_get_link_ksettings,\n--\ndrivers/net/ethernet/smsc/smsc9420.c=388=static const struct ethtool_ops smsc9420_ethtool_ops = {\n--\ndrivers/net/ethernet/smsc/smsc9420.c-398-\t.get_regs = smsc9420_ethtool_getregs,\ndrivers/net/ethernet/smsc/smsc9420.c:399:\t.get_ts_info = ethtool_op_get_ts_info,\ndrivers/net/ethernet/smsc/smsc9420.c-400-\t.get_link_ksettings = phy_ethtool_get_link_ksettings,\n--\ndrivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c=1005=static int stmmac_get_ts_info(struct net_device *dev,\n--\ndrivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c-1036-\t} else\ndrivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c:1037:\t\treturn ethtool_op_get_ts_info(dev, info);\ndrivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c-1038-}\n--\ndrivers/net/ethernet/ti/am65-cpsw-ethtool.c=690=static int am65_cpsw_get_ethtool_ts_info(struct net_device *ndev,\n--\ndrivers/net/ethernet/ti/am65-cpsw-ethtool.c-709-\tif (!IS_ENABLED(CONFIG_TI_K3_AM65_CPTS))\ndrivers/net/ethernet/ti/am65-cpsw-ethtool.c:710:\t\treturn ethtool_op_get_ts_info(ndev, info);\ndrivers/net/ethernet/ti/am65-cpsw-ethtool.c-711-\n--\ndrivers/net/ethernet/ti/davinci_emac.c=500=static const struct ethtool_ops ethtool_ops = {\n--\ndrivers/net/ethernet/ti/davinci_emac.c-505-\t.set_coalesce =  emac_set_coalesce,\ndrivers/net/ethernet/ti/davinci_emac.c:506:\t.get_ts_info = ethtool_op_get_ts_info,\ndrivers/net/ethernet/ti/davinci_emac.c-507-\t.get_link_ksettings = phy_ethtool_get_link_ksettings,\n--\ndrivers/net/ethernet/wangxun/libwx/wx_ethtool.c=842=static const struct ethtool_ops wx_ethtool_ops_vf = {\n--\ndrivers/net/ethernet/wangxun/libwx/wx_ethtool.c-852-\t.set_coalesce\t\t= wx_set_coalesce,\ndrivers/net/ethernet/wangxun/libwx/wx_ethtool.c:853:\t.get_ts_info\t\t= ethtool_op_get_ts_info,\ndrivers/net/ethernet/wangxun/libwx/wx_ethtool.c-854-\t.get_link_ksettings\t= wx_get_link_ksettings_vf,\n--\ndrivers/net/ethernet/xilinx/ll_temac_main.c=1369=static const struct ethtool_ops temac_ethtool_ops = {\n--\n\n"
}

43/3 2026/08/13 22:55 llm kmsan-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 46856
							output: 25
							thoughts: 29
						

Thoughts:
Here's my attempt at summarizing the thought process, tailored for an expert audience:

**Diving into the Timestamp Information Retrieval**

Okay, so I need to get a handle on how timestamp information is being retrieved, specifically in the `ethtool` context. My immediate focus is on the `ethtool_op_get_ts_info` function. Let's start with `net/ethtool/common.c`. This is where the core, generic `ethtool` operations are typically implemented, and it's highly likely that the timestamp-related function will reside there, or at least be calling a function within this file. I need to understand how the ethtool interface calls this function to get timestamp information.



44/3 2026/08/13 22:55 tool grepper
0m Args:
{
  "Expression": "ethtool_op_get_ts_info"
}

Results:
{
  "Output": "\nFull output is too long, showing 500 out of 628 lines.\nUse more precise expression if possible.\n\narch/um/drivers/vector_kern.c=1503=static const struct ethtool_ops vector_net_ethtool_ops = {\n--\narch/um/drivers/vector_kern.c-1506-\t.get_link\t= ethtool_op_get_link,\narch/um/drivers/vector_kern.c:1507:\t.get_ts_info\t= ethtool_op_get_ts_info,\narch/um/drivers/vector_kern.c-1508-\t.get_ringparam\t= vector_get_ringparam,\n--\ndrivers/net/can/at91_can.c=953=static const struct ethtool_ops at91_ethtool_ops = {\ndrivers/net/can/at91_can.c:954:\t.get_ts_info = ethtool_op_get_ts_info,\ndrivers/net/can/at91_can.c-955-};\n--\ndrivers/net/can/bxcan.c=886=static const struct ethtool_ops bxcan_ethtool_ops = {\ndrivers/net/can/bxcan.c:887:\t.get_ts_info = ethtool_op_get_ts_info,\ndrivers/net/can/bxcan.c-888-};\n--\ndrivers/net/can/c_can/c_can_ethtool.c=27=const struct ethtool_ops c_can_ethtool_ops = {\ndrivers/net/can/c_can/c_can_ethtool.c-28-\t.get_ringparam = c_can_get_ringparam,\ndrivers/net/can/c_can/c_can_ethtool.c:29:\t.get_ts_info = ethtool_op_get_ts_info,\ndrivers/net/can/c_can/c_can_ethtool.c-30-};\n--\ndrivers/net/can/can327.c=855=static const struct ethtool_ops can327_ethtool_ops = {\ndrivers/net/can/can327.c:856:\t.get_ts_info = ethtool_op_get_ts_info,\ndrivers/net/can/can327.c-857-};\n--\ndrivers/net/can/cc770/cc770.c=839=static const struct ethtool_ops cc770_ethtool_ops = {\ndrivers/net/can/cc770/cc770.c:840:\t.get_ts_info = ethtool_op_get_ts_info,\ndrivers/net/can/cc770/cc770.c-841-};\n--\ndrivers/net/can/ctucanfd/ctucanfd_base.c=1310=static const struct ethtool_ops ctucan_ethtool_ops = {\ndrivers/net/can/ctucanfd/ctucanfd_base.c:1311:\t.get_ts_info = ethtool_op_get_ts_info,\ndrivers/net/can/ctucanfd/ctucanfd_base.c-1312-};\n--\ndrivers/net/can/dev/dev.c=452=EXPORT_SYMBOL(can_hwtstamp_set);\n--\ndrivers/net/can/dev/dev.c-456- */\ndrivers/net/can/dev/dev.c:457:int can_ethtool_op_get_ts_info_hwts(struct net_device *dev,\ndrivers/net/can/dev/dev.c-458-\t\t\t\t    struct kernel_ethtool_ts_info *info)\n--\ndrivers/net/can/dev/dev.c-469-}\ndrivers/net/can/dev/dev.c:470:EXPORT_SYMBOL(can_ethtool_op_get_ts_info_hwts);\ndrivers/net/can/dev/dev.c-471-\n--\ndrivers/net/can/dummy_can.c=228=static const struct ethtool_ops dummy_can_ethtool_ops = {\ndrivers/net/can/dummy_can.c:229:\t.get_ts_info = ethtool_op_get_ts_info,\ndrivers/net/can/dummy_can.c-230-};\n--\ndrivers/net/can/esd/esd_402_pci-core.c=93=static const struct ethtool_ops pci402_acc_ethtool_ops = {\ndrivers/net/can/esd/esd_402_pci-core.c:94:\t.get_ts_info = can_ethtool_op_get_ts_info_hwts,\ndrivers/net/can/esd/esd_402_pci-core.c-95-};\n--\ndrivers/net/can/flexcan/flexcan-ethtool.c=103=const struct ethtool_ops flexcan_ethtool_ops = {\n--\ndrivers/net/can/flexcan/flexcan-ethtool.c-108-\t.get_sset_count = flexcan_get_sset_count,\ndrivers/net/can/flexcan/flexcan-ethtool.c:109:\t.get_ts_info = ethtool_op_get_ts_info,\ndrivers/net/can/flexcan/flexcan-ethtool.c-110-};\n--\ndrivers/net/can/grcan.c=1565=static const struct ethtool_ops grcan_ethtool_ops = {\ndrivers/net/can/grcan.c:1566:\t.get_ts_info = ethtool_op_get_ts_info,\ndrivers/net/can/grcan.c-1567-};\n--\ndrivers/net/can/ifi_canfd/ifi_canfd.c=949=static const struct ethtool_ops ifi_canfd_ethtool_ops = {\ndrivers/net/can/ifi_canfd/ifi_canfd.c:950:\t.get_ts_info = ethtool_op_get_ts_info,\ndrivers/net/can/ifi_canfd/ifi_canfd.c-951-};\n--\ndrivers/net/can/janz-ican3.c=1757=static const struct ethtool_ops ican3_ethtool_ops = {\ndrivers/net/can/janz-ican3.c:1758:\t.get_ts_info = ethtool_op_get_ts_info,\ndrivers/net/can/janz-ican3.c-1759-};\n--\ndrivers/net/can/kvaser_pciefd/kvaser_pciefd_core.c=933=static const struct ethtool_ops kvaser_pciefd_ethtool_ops = {\ndrivers/net/can/kvaser_pciefd/kvaser_pciefd_core.c:934:\t.get_ts_info = can_ethtool_op_get_ts_info_hwts,\ndrivers/net/can/kvaser_pciefd/kvaser_pciefd_core.c-935-\t.set_phys_id = kvaser_pciefd_set_phys_id,\n--\ndrivers/net/can/m_can/m_can.c=2310=static const struct ethtool_ops m_can_ethtool_ops_coalescing = {\n--\ndrivers/net/can/m_can/m_can.c-2315-\t\tETHTOOL_COALESCE_TX_MAX_FRAMES_IRQ,\ndrivers/net/can/m_can/m_can.c:2316:\t.get_ts_info = ethtool_op_get_ts_info,\ndrivers/net/can/m_can/m_can.c-2317-\t.get_coalesce = m_can_get_coalesce,\n--\ndrivers/net/can/m_can/m_can.c=2323=static const struct ethtool_ops m_can_ethtool_ops = {\ndrivers/net/can/m_can/m_can.c:2324:\t.get_ts_info = ethtool_op_get_ts_info,\ndrivers/net/can/m_can/m_can.c-2325-\t.get_wol = m_can_get_wol,\n--\ndrivers/net/can/mscan/mscan.c=612=static const struct ethtool_ops mscan_ethtool_ops = {\ndrivers/net/can/mscan/mscan.c:613:\t.get_ts_info = ethtool_op_get_ts_info,\ndrivers/net/can/mscan/mscan.c-614-};\n--\ndrivers/net/can/rcar/rcar_can.c=639=static const struct ethtool_ops rcar_can_ethtool_ops = {\ndrivers/net/can/rcar/rcar_can.c:640:\t.get_ts_info = ethtool_op_get_ts_info,\ndrivers/net/can/rcar/rcar_can.c-641-};\n--\ndrivers/net/can/rcar/rcar_canfd.c=1859=static const struct ethtool_ops rcar_canfd_ethtool_ops = {\ndrivers/net/can/rcar/rcar_canfd.c:1860:\t.get_ts_info = ethtool_op_get_ts_info,\ndrivers/net/can/rcar/rcar_canfd.c-1861-};\n--\ndrivers/net/can/rockchip/rockchip_canfd-ethtool.c=61=static const struct ethtool_ops rkcanfd_ethtool_ops = {\ndrivers/net/can/rockchip/rockchip_canfd-ethtool.c:62:\t.get_ts_info = can_ethtool_op_get_ts_info_hwts,\ndrivers/net/can/rockchip/rockchip_canfd-ethtool.c-63-\t.get_strings = rkcanfd_ethtool_get_strings,\n--\ndrivers/net/can/sja1000/sja1000.c=682=static const struct ethtool_ops sja1000_ethtool_ops = {\ndrivers/net/can/sja1000/sja1000.c:683:\t.get_ts_info = ethtool_op_get_ts_info,\ndrivers/net/can/sja1000/sja1000.c-684-};\n--\ndrivers/net/can/slcan/slcan-ethtool.c=55=const struct ethtool_ops slcan_ethtool_ops = {\n--\ndrivers/net/can/slcan/slcan-ethtool.c-59-\t.get_sset_count = slcan_get_sset_count,\ndrivers/net/can/slcan/slcan-ethtool.c:60:\t.get_ts_info = ethtool_op_get_ts_info,\ndrivers/net/can/slcan/slcan-ethtool.c-61-};\n--\ndrivers/net/can/softing/softing_main.c=614=static const struct ethtool_ops softing_ethtool_ops = {\ndrivers/net/can/softing/softing_main.c:615:\t.get_ts_info = ethtool_op_get_ts_info,\ndrivers/net/can/softing/softing_main.c-616-};\n--\ndrivers/net/can/spi/hi311x.c=806=static const struct ethtool_ops hi3110_ethtool_ops = {\ndrivers/net/can/spi/hi311x.c:807:\t.get_ts_info = ethtool_op_get_ts_info,\ndrivers/net/can/spi/hi311x.c-808-};\n--\ndrivers/net/can/spi/mcp251x.c=1293=static const struct ethtool_ops mcp251x_ethtool_ops = {\ndrivers/net/can/spi/mcp251x.c:1294:\t.get_ts_info = ethtool_op_get_ts_info,\ndrivers/net/can/spi/mcp251x.c-1295-};\n--\ndrivers/net/can/spi/mcp251xfd/mcp251xfd-ethtool.c=119=static const struct ethtool_ops mcp251xfd_ethtool_ops = {\n--\ndrivers/net/can/spi/mcp251xfd/mcp251xfd-ethtool.c-127-\t.set_coalesce = mcp251xfd_ring_set_coalesce,\ndrivers/net/can/spi/mcp251xfd/mcp251xfd-ethtool.c:128:\t.get_ts_info = can_ethtool_op_get_ts_info_hwts,\ndrivers/net/can/spi/mcp251xfd/mcp251xfd-ethtool.c-129-};\n--\ndrivers/net/can/sun4i_can.c=773=static const struct ethtool_ops sun4ican_ethtool_ops = {\ndrivers/net/can/sun4i_can.c:774:\t.get_ts_info = ethtool_op_get_ts_info,\ndrivers/net/can/sun4i_can.c-775-};\n--\ndrivers/net/can/ti_hecc.c=834=static const struct ethtool_ops ti_hecc_ethtool_ops = {\ndrivers/net/can/ti_hecc.c:835:\t.get_ts_info = ethtool_op_get_ts_info,\ndrivers/net/can/ti_hecc.c-836-};\n--\ndrivers/net/can/usb/ems_usb.c=944=static const struct ethtool_ops ems_usb_ethtool_ops = {\ndrivers/net/can/usb/ems_usb.c:945:\t.get_ts_info = ethtool_op_get_ts_info,\ndrivers/net/can/usb/ems_usb.c-946-};\n--\ndrivers/net/can/usb/esd_usb.c=1019=static const struct ethtool_ops esd_usb_ethtool_ops = {\ndrivers/net/can/usb/esd_usb.c:1020:\t.get_ts_info = ethtool_op_get_ts_info,\ndrivers/net/can/usb/esd_usb.c-1021-};\n--\ndrivers/net/can/usb/etas_es58x/es58x_core.c=1988=static const struct ethtool_ops es58x_ethtool_ops = {\ndrivers/net/can/usb/etas_es58x/es58x_core.c:1989:\t.get_ts_info = can_ethtool_op_get_ts_info_hwts,\ndrivers/net/can/usb/etas_es58x/es58x_core.c-1990-};\n--\ndrivers/net/can/usb/f81604.c=126=static const struct ethtool_ops f81604_ethtool_ops = {\ndrivers/net/can/usb/f81604.c:127:\t.get_ts_info = ethtool_op_get_ts_info,\ndrivers/net/can/usb/f81604.c-128-};\n--\ndrivers/net/can/usb/gs_usb.c=1256=static int gs_usb_get_ts_info(struct net_device *netdev,\n--\ndrivers/net/can/usb/gs_usb.c-1262-\tif (dev-\u003efeature \u0026 GS_CAN_FEATURE_HW_TIMESTAMP)\ndrivers/net/can/usb/gs_usb.c:1263:\t\treturn can_ethtool_op_get_ts_info_hwts(netdev, info);\ndrivers/net/can/usb/gs_usb.c-1264-\ndrivers/net/can/usb/gs_usb.c:1265:\treturn ethtool_op_get_ts_info(netdev, info);\ndrivers/net/can/usb/gs_usb.c-1266-}\n--\ndrivers/net/can/usb/kvaser_usb/kvaser_usb_core.c=799=static const struct ethtool_ops kvaser_usb_ethtool_ops = {\ndrivers/net/can/usb/kvaser_usb/kvaser_usb_core.c:800:\t.get_ts_info = can_ethtool_op_get_ts_info_hwts,\ndrivers/net/can/usb/kvaser_usb/kvaser_usb_core.c-801-\t.set_phys_id = kvaser_usb_set_phys_id,\n--\ndrivers/net/can/usb/mcba_usb.c=772=static const struct ethtool_ops mcba_ethtool_ops = {\ndrivers/net/can/usb/mcba_usb.c:773:\t.get_ts_info = ethtool_op_get_ts_info,\ndrivers/net/can/usb/mcba_usb.c-774-};\n--\ndrivers/net/can/usb/nct6694_canfd.c=695=static const struct ethtool_ops nct6694_canfd_ethtool_ops = {\ndrivers/net/can/usb/nct6694_canfd.c:696:\t.get_ts_info = ethtool_op_get_ts_info,\ndrivers/net/can/usb/nct6694_canfd.c-697-};\n--\ndrivers/net/can/usb/ucan.c=1237=static const struct ethtool_ops ucan_ethtool_ops = {\ndrivers/net/can/usb/ucan.c:1238:\t.get_ts_info = ethtool_op_get_ts_info,\ndrivers/net/can/usb/ucan.c-1239-};\n--\ndrivers/net/can/usb/usb_8dev.c=879=static const struct ethtool_ops usb_8dev_ethtool_ops = {\ndrivers/net/can/usb/usb_8dev.c:880:\t.get_ts_info = ethtool_op_get_ts_info,\ndrivers/net/can/usb/usb_8dev.c-881-};\n--\ndrivers/net/can/vcan.c=166=static const struct ethtool_ops vcan_ethtool_ops = {\ndrivers/net/can/vcan.c:167:\t.get_ts_info = ethtool_op_get_ts_info,\ndrivers/net/can/vcan.c-168-};\n--\ndrivers/net/can/vxcan.c=177=static const struct ethtool_ops vxcan_ethtool_ops = {\ndrivers/net/can/vxcan.c:178:\t.get_ts_info = ethtool_op_get_ts_info,\ndrivers/net/can/vxcan.c-179-};\n--\ndrivers/net/can/xilinx_can.c=1707=static const struct ethtool_ops xcan_ethtool_ops = {\ndrivers/net/can/xilinx_can.c:1708:\t.get_ts_info = ethtool_op_get_ts_info,\ndrivers/net/can/xilinx_can.c-1709-\t.get_strings = xcan_get_strings,\n--\ndrivers/net/dummy.c=99=static const struct ethtool_ops dummy_ethtool_ops = {\ndrivers/net/dummy.c:100:\t.get_ts_info\t\t= ethtool_op_get_ts_info,\ndrivers/net/dummy.c-101-};\n--\ndrivers/net/ethernet/3com/3c59x.c=3009=static const struct ethtool_ops vortex_ethtool_ops = {\n--\ndrivers/net/ethernet/3com/3c59x.c-3019-\t.set_wol                = vortex_set_wol,\ndrivers/net/ethernet/3com/3c59x.c:3020:\t.get_ts_info\t\t= ethtool_op_get_ts_info,\ndrivers/net/ethernet/3com/3c59x.c-3021-\t.get_link_ksettings     = vortex_get_link_ksettings,\n--\ndrivers/net/ethernet/8390/ax88796.c=601=static const struct ethtool_ops ax_ethtool_ops = {\n--\ndrivers/net/ethernet/8390/ax88796.c-603-\t.get_link\t\t= ethtool_op_get_link,\ndrivers/net/ethernet/8390/ax88796.c:604:\t.get_ts_info\t\t= ethtool_op_get_ts_info,\ndrivers/net/ethernet/8390/ax88796.c-605-\t.get_msglevel\t\t= ax_get_msglevel,\n--\ndrivers/net/ethernet/8390/etherh.c=624=static const struct ethtool_ops etherh_ethtool_ops = {\ndrivers/net/ethernet/8390/etherh.c-625-\t.get_drvinfo\t\t= etherh_get_drvinfo,\ndrivers/net/ethernet/8390/etherh.c:626:\t.get_ts_info\t\t= ethtool_op_get_ts_info,\ndrivers/net/ethernet/8390/etherh.c-627-\t.get_msglevel\t\t= etherh_get_msglevel,\n--\ndrivers/net/ethernet/altera/altera_tse_ethtool.c=240=static const struct ethtool_ops tse_ethtool_ops = {\n--\ndrivers/net/ethernet/altera/altera_tse_ethtool.c-251-\t.set_link_ksettings = tse_ethtool_set_link_ksettings,\ndrivers/net/ethernet/altera/altera_tse_ethtool.c:252:\t.get_ts_info = ethtool_op_get_ts_info,\ndrivers/net/ethernet/altera/altera_tse_ethtool.c-253-};\n--\ndrivers/net/ethernet/aquantia/atlantic/aq_ethtool.c=653=static int aq_ethtool_get_ts_info(struct net_device *ndev,\n--\ndrivers/net/ethernet/aquantia/atlantic/aq_ethtool.c-657-\ndrivers/net/ethernet/aquantia/atlantic/aq_ethtool.c:658:\tethtool_op_get_ts_info(ndev, info);\ndrivers/net/ethernet/aquantia/atlantic/aq_ethtool.c-659-\n--\ndrivers/net/ethernet/atheros/ag71xx.c=542=static const struct ethtool_ops ag71xx_ethtool_ops = {\n--\ndrivers/net/ethernet/atheros/ag71xx.c-544-\t.get_link\t\t\t= ethtool_op_get_link,\ndrivers/net/ethernet/atheros/ag71xx.c:545:\t.get_ts_info\t\t\t= ethtool_op_get_ts_info,\ndrivers/net/ethernet/atheros/ag71xx.c-546-\t.get_link_ksettings\t\t= ag71xx_get_link_ksettings,\n--\ndrivers/net/ethernet/broadcom/asp2/bcmasp_ethtool.c=443=const struct ethtool_ops bcmasp_ethtool_ops = {\n--\ndrivers/net/ethernet/broadcom/asp2/bcmasp_ethtool.c-461-\t.get_sset_count\t\t= bcmasp_get_sset_count,\ndrivers/net/ethernet/broadcom/asp2/bcmasp_ethtool.c:462:\t.get_ts_info\t\t= ethtool_op_get_ts_info,\ndrivers/net/ethernet/broadcom/asp2/bcmasp_ethtool.c-463-\t.nway_reset\t\t= phy_ethtool_nway_reset,\n--\ndrivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c=3613=static int bnx2x_get_ts_info(struct net_device *dev,\n--\ndrivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c-3636-\ndrivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c:3637:\treturn ethtool_op_get_ts_info(dev, info);\ndrivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c-3638-}\n--\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c=1678=static const struct ethtool_ops bcmgenet_ethtool_ops = {\n--\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c-1699-\t.set_link_ksettings\t= bcmgenet_set_link_ksettings,\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c:1700:\t.get_ts_info\t\t= ethtool_op_get_ts_info,\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c-1701-\t.get_rxnfc\t\t= bcmgenet_get_rxnfc,\n--\ndrivers/net/ethernet/brocade/bna/bnad_ethtool.c=1069=static const struct ethtool_ops bnad_ethtool_ops = {\n--\ndrivers/net/ethernet/brocade/bna/bnad_ethtool.c-1088-\t.flash_device = bnad_flash_device,\ndrivers/net/ethernet/brocade/bna/bnad_ethtool.c:1089:\t.get_ts_info = ethtool_op_get_ts_info,\ndrivers/net/ethernet/brocade/bna/bnad_ethtool.c-1090-\t.get_link_ksettings = bnad_get_link_ksettings,\n--\ndrivers/net/ethernet/cadence/macb_main.c=3774=static int gem_get_ts_info(struct net_device *dev,\n--\ndrivers/net/ethernet/cadence/macb_main.c-3779-\tif (!macb_dma_ptp(bp)) {\ndrivers/net/ethernet/cadence/macb_main.c:3780:\t\tethtool_op_get_ts_info(dev, info);\ndrivers/net/ethernet/cadence/macb_main.c-3781-\t\treturn 0;\n--\ndrivers/net/ethernet/cadence/macb_main.c=3814=static int macb_get_ts_info(struct net_device *netdev,\n--\ndrivers/net/ethernet/cadence/macb_main.c-3821-\ndrivers/net/ethernet/cadence/macb_main.c:3822:\treturn ethtool_op_get_ts_info(netdev, info);\ndrivers/net/ethernet/cadence/macb_main.c-3823-}\n--\ndrivers/net/ethernet/cadence/macb_main.c=4140=static const struct ethtool_ops macb_ethtool_ops = {\n--\ndrivers/net/ethernet/cadence/macb_main.c-4143-\t.get_link\t\t= ethtool_op_get_link,\ndrivers/net/ethernet/cadence/macb_main.c:4144:\t.get_ts_info\t\t= ethtool_op_get_ts_info,\ndrivers/net/ethernet/cadence/macb_main.c-4145-\t.get_pause_stats\t= macb_get_pause_stats,\n--\ndrivers/net/ethernet/cavium/thunder/nicvf_ethtool.c=818=static int nicvf_get_ts_info(struct net_device *netdev,\n--\ndrivers/net/ethernet/cavium/thunder/nicvf_ethtool.c-823-\tif (!nic-\u003eptp_clock)\ndrivers/net/ethernet/cavium/thunder/nicvf_ethtool.c:824:\t\treturn ethtool_op_get_ts_info(netdev, info);\ndrivers/net/ethernet/cavium/thunder/nicvf_ethtool.c-825-\n--\ndrivers/net/ethernet/ethoc.c=997=static const struct ethtool_ops ethoc_ethtool_ops = {\n--\ndrivers/net/ethernet/ethoc.c-1003-\t.set_ringparam = ethoc_set_ringparam,\ndrivers/net/ethernet/ethoc.c:1004:\t.get_ts_info = ethtool_op_get_ts_info,\ndrivers/net/ethernet/ethoc.c-1005-\t.get_link_ksettings = phy_ethtool_get_link_ksettings,\n--\ndrivers/net/ethernet/freescale/dpaa2/dpaa2-ethtool.c=805=static int dpaa2_eth_get_ts_info(struct net_device *dev,\n--\ndrivers/net/ethernet/freescale/dpaa2/dpaa2-ethtool.c-808-\tif (!dpaa2_ptp)\ndrivers/net/ethernet/freescale/dpaa2/dpaa2-ethtool.c:809:\t\treturn ethtool_op_get_ts_info(dev, info);\ndrivers/net/ethernet/freescale/dpaa2/dpaa2-ethtool.c-810-\n--\ndrivers/net/ethernet/freescale/fec_main.c=3329=static int fec_enet_get_ts_info(struct net_device *ndev,\n--\ndrivers/net/ethernet/freescale/fec_main.c-3349-\t} else {\ndrivers/net/ethernet/freescale/fec_main.c:3350:\t\treturn ethtool_op_get_ts_info(ndev, info);\ndrivers/net/ethernet/freescale/fec_main.c-3351-\t}\n--\ndrivers/net/ethernet/freescale/fec_mpc52xx.c=781=static const struct ethtool_ops mpc52xx_fec_ethtool_ops = {\n--\ndrivers/net/ethernet/freescale/fec_mpc52xx.c-784-\t.set_msglevel = mpc52xx_fec_set_msglevel,\ndrivers/net/ethernet/freescale/fec_mpc52xx.c:785:\t.get_ts_info = ethtool_op_get_ts_info,\ndrivers/net/ethernet/freescale/fec_mpc52xx.c-786-\t.get_link_ksettings = phy_ethtool_get_link_ksettings,\n--\ndrivers/net/ethernet/freescale/fs_enet/fs_enet-main.c=812=static const struct ethtool_ops fs_ethtool_ops = {\n--\ndrivers/net/ethernet/freescale/fs_enet/fs_enet-main.c-819-\t.get_regs = fs_get_regs,\ndrivers/net/ethernet/freescale/fs_enet/fs_enet-main.c:820:\t.get_ts_info = ethtool_op_get_ts_info,\ndrivers/net/ethernet/freescale/fs_enet/fs_enet-main.c-821-\t.get_link_ksettings = fs_ethtool_get_link_ksettings,\n--\ndrivers/net/ethernet/freescale/ucc_geth_ethtool.c=359=static const struct ethtool_ops uec_ethtool_ops = {\n--\ndrivers/net/ethernet/freescale/ucc_geth_ethtool.c-375-\t.set_wol\t\t= uec_set_wol,\ndrivers/net/ethernet/freescale/ucc_geth_ethtool.c:376:\t.get_ts_info\t\t= ethtool_op_get_ts_info,\ndrivers/net/ethernet/freescale/ucc_geth_ethtool.c-377-\t.get_link_ksettings\t= uec_get_ksettings,\n--\ndrivers/net/ethernet/google/gve/gve_ethtool.c=961=static int gve_get_ts_info(struct net_device *netdev,\n--\ndrivers/net/ethernet/google/gve/gve_ethtool.c-965-\ndrivers/net/ethernet/google/gve/gve_ethtool.c:966:\tethtool_op_get_ts_info(netdev, info);\ndrivers/net/ethernet/google/gve/gve_ethtool.c-967-\n--\ndrivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c=2054=static int hns3_get_ts_info(struct net_device *netdev,\n--\ndrivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c-2061-\ndrivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c:2062:\treturn ethtool_op_get_ts_info(netdev, info);\ndrivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c-2063-}\n--\ndrivers/net/ethernet/intel/e100.c=2736=static const struct ethtool_ops e100_ethtool_ops = {\n--\ndrivers/net/ethernet/intel/e100.c-2755-\t.get_sset_count\t\t= e100_get_sset_count,\ndrivers/net/ethernet/intel/e100.c:2756:\t.get_ts_info\t\t= ethtool_op_get_ts_info,\ndrivers/net/ethernet/intel/e100.c-2757-\t.get_link_ksettings\t= e100_get_link_ksettings,\n--\ndrivers/net/ethernet/intel/e1000/e1000_ethtool.c=1864=static const struct ethtool_ops e1000_ethtool_ops = {\n--\ndrivers/net/ethernet/intel/e1000/e1000_ethtool.c-1888-\t.set_coalesce\t\t= e1000_set_coalesce,\ndrivers/net/ethernet/intel/e1000/e1000_ethtool.c:1889:\t.get_ts_info\t\t= ethtool_op_get_ts_info,\ndrivers/net/ethernet/intel/e1000/e1000_ethtool.c-1890-\t.get_link_ksettings\t= e1000_get_link_ksettings,\n--\ndrivers/net/ethernet/intel/e1000e/ethtool.c=2263=static int e1000e_get_ts_info(struct net_device *netdev,\n--\ndrivers/net/ethernet/intel/e1000e/ethtool.c-2267-\ndrivers/net/ethernet/intel/e1000e/ethtool.c:2268:\tethtool_op_get_ts_info(netdev, info);\ndrivers/net/ethernet/intel/e1000e/ethtool.c-2269-\n--\ndrivers/net/ethernet/intel/fm10k/fm10k_ethtool.c=1136=static const struct ethtool_ops fm10k_ethtool_ops = {\n--\ndrivers/net/ethernet/intel/fm10k/fm10k_ethtool.c-1165-\t.set_channels\t\t= fm10k_set_channels,\ndrivers/net/ethernet/intel/fm10k/fm10k_ethtool.c:1166:\t.get_ts_info\t\t= ethtool_op_get_ts_info,\ndrivers/net/ethernet/intel/fm10k/fm10k_ethtool.c-1167-};\n--\ndrivers/net/ethernet/intel/i40e/i40e_ethtool.c=2538=static int i40e_get_ts_info(struct net_device *dev,\n--\ndrivers/net/ethernet/intel/i40e/i40e_ethtool.c-2544-\tif (!test_bit(I40E_FLAG_PTP_ENA, pf-\u003eflags))\ndrivers/net/ethernet/intel/i40e/i40e_ethtool.c:2545:\t\treturn ethtool_op_get_ts_info(dev, info);\ndrivers/net/ethernet/intel/i40e/i40e_ethtool.c-2546-\n--\ndrivers/net/ethernet/intel/ice/ice_ethtool.c=3767=ice_get_ts_info(struct net_device *dev, struct kernel_ethtool_ts_info *info)\n--\ndrivers/net/ethernet/intel/ice/ice_ethtool.c-3772-\tif (pf-\u003eptp.state != ICE_PTP_READY)\ndrivers/net/ethernet/intel/ice/ice_ethtool.c:3773:\t\treturn ethtool_op_get_ts_info(dev, info);\ndrivers/net/ethernet/intel/ice/ice_ethtool.c-3774-\n--\ndrivers/net/ethernet/intel/idpf/idpf_ethtool.c=1712=static int idpf_get_ts_info(struct net_device *netdev,\n--\ndrivers/net/ethernet/intel/idpf/idpf_ethtool.c-1734-\t\tpci_dbg(vport-\u003eadapter-\u003epdev, \"PTP clock not detected\\n\");\ndrivers/net/ethernet/intel/idpf/idpf_ethtool.c:1735:\t\terr = ethtool_op_get_ts_info(netdev, info);\ndrivers/net/ethernet/intel/idpf/idpf_ethtool.c-1736-\t}\n--\ndrivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c=3306=static int ixgbe_get_ts_info(struct net_device *dev,\n--\ndrivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c-3328-\tdefault:\ndrivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c:3329:\t\treturn ethtool_op_get_ts_info(dev, info);\ndrivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c-3330-\t}\n--\ndrivers/net/ethernet/marvell/mv643xx_eth.c=1741=static const struct ethtool_ops mv643xx_eth_ethtool_ops = {\n--\ndrivers/net/ethernet/marvell/mv643xx_eth.c-1752-\t.get_sset_count\t\t= mv643xx_eth_get_sset_count,\ndrivers/net/ethernet/marvell/mv643xx_eth.c:1753:\t.get_ts_info\t\t= ethtool_op_get_ts_info,\ndrivers/net/ethernet/marvell/mv643xx_eth.c-1754-\t.get_wol                = mv643xx_eth_get_wol,\n--\ndrivers/net/ethernet/marvell/mvneta.c=5335=static const struct ethtool_ops mvneta_eth_tool_ops = {\n--\ndrivers/net/ethernet/marvell/mvneta.c-5357-\t.set_wol        = mvneta_ethtool_set_wol,\ndrivers/net/ethernet/marvell/mvneta.c:5358:\t.get_ts_info\t= ethtool_op_get_ts_info,\ndrivers/net/ethernet/marvell/mvneta.c-5359-\t.get_eee\t= mvneta_ethtool_get_eee,\n--\ndrivers/net/ethernet/marvell/mvpp2/mvpp2_main.c=5265=static int mvpp2_ethtool_get_ts_info(struct net_device *dev,\n--\ndrivers/net/ethernet/marvell/mvpp2/mvpp2_main.c-5269-\ndrivers/net/ethernet/marvell/mvpp2/mvpp2_main.c:5270:\tethtool_op_get_ts_info(dev, info);\ndrivers/net/ethernet/marvell/mvpp2/mvpp2_main.c-5271-\tif (!port-\u003ehwtstamp)\n--\ndrivers/net/ethernet/marvell/octeontx2/nic/otx2_ethtool.c=976=static int otx2_get_ts_info(struct net_device *netdev,\n--\ndrivers/net/ethernet/marvell/octeontx2/nic/otx2_ethtool.c-981-\tif (!pfvf-\u003eptp)\ndrivers/net/ethernet/marvell/octeontx2/nic/otx2_ethtool.c:982:\t\treturn ethtool_op_get_ts_info(netdev, info);\ndrivers/net/ethernet/marvell/octeontx2/nic/otx2_ethtool.c-983-\n--\ndrivers/net/ethernet/marvell/pxa168_eth.c=1363=static const struct ethtool_ops pxa168_ethtool_ops = {\n--\ndrivers/net/ethernet/marvell/pxa168_eth.c-1366-\t.get_link\t= ethtool_op_get_link,\ndrivers/net/ethernet/marvell/pxa168_eth.c:1367:\t.get_ts_info\t= ethtool_op_get_ts_info,\ndrivers/net/ethernet/marvell/pxa168_eth.c-1368-\t.get_link_ksettings = phy_ethtool_get_link_ksettings,\n--\ndrivers/net/ethernet/mellanox/mlx4/en_ethtool.c=1890=static int mlx4_en_get_ts_info(struct net_device *dev,\n--\ndrivers/net/ethernet/mellanox/mlx4/en_ethtool.c-1896-\ndrivers/net/ethernet/mellanox/mlx4/en_ethtool.c:1897:\tret = ethtool_op_get_ts_info(dev, info);\ndrivers/net/ethernet/mellanox/mlx4/en_ethtool.c-1898-\tif (ret)\n--\ndrivers/net/ethernet/microchip/lan966x/lan966x_ethtool.c=540=static int lan966x_get_ts_info(struct net_device *dev,\n--\ndrivers/net/ethernet/microchip/lan966x/lan966x_ethtool.c-547-\tif (!lan966x-\u003eptp)\ndrivers/net/ethernet/microchip/lan966x/lan966x_ethtool.c:548:\t\treturn ethtool_op_get_ts_info(dev, info);\ndrivers/net/ethernet/microchip/lan966x/lan966x_ethtool.c-549-\n--\ndrivers/net/ethernet/microchip/sparx5/sparx5_ethtool.c=1185=static int sparx5_get_ts_info(struct net_device *dev,\n--\ndrivers/net/ethernet/microchip/sparx5/sparx5_ethtool.c-1192-\tif (!sparx5-\u003eptp \u0026\u0026 is_sparx5(sparx5))\ndrivers/net/ethernet/microchip/sparx5/sparx5_ethtool.c:1193:\t\treturn ethtool_op_get_ts_info(dev, info);\ndrivers/net/ethernet/microchip/sparx5/sparx5_ethtool.c-1194-\n--\ndrivers/net/ethernet/mscc/ocelot_net.c=1031=static int ocelot_port_get_ts_info(struct net_device *dev,\n--\ndrivers/net/ethernet/mscc/ocelot_net.c-1038-\tif (!ocelot-\u003eptp)\ndrivers/net/ethernet/mscc/ocelot_net.c:1039:\t\treturn ethtool_op_get_ts_info(dev, info);\ndrivers/net/ethernet/mscc/ocelot_net.c-1040-\n--\ndrivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c=2493=static const struct ethtool_ops nfp_net_ethtool_ops = {\n--\ndrivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c-2535-\t.set_phys_id\t\t= nfp_net_set_phys_id,\ndrivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c:2536:\t.get_ts_info\t\t= ethtool_op_get_ts_info,\ndrivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c-2537-};\n--\ndrivers/net/ethernet/nvidia/forcedeth.c=5341=static const struct ethtool_ops ops = {\n--\ndrivers/net/ethernet/nvidia/forcedeth.c-5356-\t.self_test = nv_self_test,\ndrivers/net/ethernet/nvidia/forcedeth.c:5357:\t.get_ts_info = ethtool_op_get_ts_info,\ndrivers/net/ethernet/nvidia/forcedeth.c-5358-\t.get_link_ksettings = nv_get_link_ksettings,\n--\ndrivers/net/ethernet/pensando/ionic/ionic_ethtool.c=1032=static int ionic_get_ts_info(struct net_device *netdev,\n--\ndrivers/net/ethernet/pensando/ionic/ionic_ethtool.c-1039-\tif (!lif-\u003ephc || !lif-\u003ephc-\u003eptp)\ndrivers/net/ethernet/pensando/ionic/ionic_ethtool.c:1040:\t\treturn ethtool_op_get_ts_info(netdev, info);\ndrivers/net/ethernet/pensando/ionic/ionic_ethtool.c-1041-\n--\ndrivers/net/ethernet/rdc/r6040.c=947=static const struct ethtool_ops netdev_ethtool_ops = {\n--\ndrivers/net/ethernet/rdc/r6040.c-949-\t.get_link\t\t= ethtool_op_get_link,\ndrivers/net/ethernet/rdc/r6040.c:950:\t.get_ts_info\t\t= ethtool_op_get_ts_info,\ndrivers/net/ethernet/rdc/r6040.c-951-\t.get_link_ksettings     = phy_ethtool_get_link_ksettings,\n--\ndrivers/net/ethernet/realtek/r8169_main.c=2419=static const struct ethtool_ops rtl8169_ethtool_ops = {\n--\ndrivers/net/ethernet/realtek/r8169_main.c-2432-\t.get_ethtool_stats\t= rtl8169_get_ethtool_stats,\ndrivers/net/ethernet/realtek/r8169_main.c:2433:\t.get_ts_info\t\t= ethtool_op_get_ts_info,\ndrivers/net/ethernet/realtek/r8169_main.c-2434-\t.nway_reset\t\t= phy_ethtool_nway_reset,\n--\ndrivers/net/ethernet/realtek/rtase/rtase_main.c=2080=static const struct ethtool_ops rtase_ethtool_ops = {\n--\ndrivers/net/ethernet/realtek/rtase/rtase_main.c-2085-\t.get_eth_mac_stats = rtase_get_eth_mac_stats,\ndrivers/net/ethernet/realtek/rtase/rtase_main.c:2086:\t.get_ts_info = ethtool_op_get_ts_info,\ndrivers/net/ethernet/realtek/rtase/rtase_main.c-2087-};\n--\ndrivers/net/ethernet/smsc/smsc911x.c=2131=static const struct ethtool_ops smsc911x_ethtool_ops = {\n--\ndrivers/net/ethernet/smsc/smsc911x.c-2141-\t.set_eeprom = smsc911x_ethtool_set_eeprom,\ndrivers/net/ethernet/smsc/smsc911x.c:2142:\t.get_ts_info = ethtool_op_get_ts_info,\ndrivers/net/ethernet/smsc/smsc911x.c-2143-\t.get_link_ksettings = phy_ethtool_get_link_ksettings,\n--\ndrivers/net/ethernet/smsc/smsc9420.c=388=static const struct ethtool_ops smsc9420_ethtool_ops = {\n--\ndrivers/net/ethernet/smsc/smsc9420.c-398-\t.get_regs = smsc9420_ethtool_getregs,\ndrivers/net/ethernet/smsc/smsc9420.c:399:\t.get_ts_info = ethtool_op_get_ts_info,\ndrivers/net/ethernet/smsc/smsc9420.c-400-\t.get_link_ksettings = phy_ethtool_get_link_ksettings,\n--\ndrivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c=1005=static int stmmac_get_ts_info(struct net_device *dev,\n--\ndrivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c-1036-\t} else\ndrivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c:1037:\t\treturn ethtool_op_get_ts_info(dev, info);\ndrivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c-1038-}\n--\ndrivers/net/ethernet/ti/am65-cpsw-ethtool.c=690=static int am65_cpsw_get_ethtool_ts_info(struct net_device *ndev,\n--\ndrivers/net/ethernet/ti/am65-cpsw-ethtool.c-709-\tif (!IS_ENABLED(CONFIG_TI_K3_AM65_CPTS))\ndrivers/net/ethernet/ti/am65-cpsw-ethtool.c:710:\t\treturn ethtool_op_get_ts_info(ndev, info);\ndrivers/net/ethernet/ti/am65-cpsw-ethtool.c-711-\n--\ndrivers/net/ethernet/ti/davinci_emac.c=500=static const struct ethtool_ops ethtool_ops = {\n--\ndrivers/net/ethernet/ti/davinci_emac.c-505-\t.set_coalesce =  emac_set_coalesce,\ndrivers/net/ethernet/ti/davinci_emac.c:506:\t.get_ts_info = ethtool_op_get_ts_info,\ndrivers/net/ethernet/ti/davinci_emac.c-507-\t.get_link_ksettings = phy_ethtool_get_link_ksettings,\n--\ndrivers/net/ethernet/wangxun/libwx/wx_ethtool.c=842=static const struct ethtool_ops wx_ethtool_ops_vf = {\n--\ndrivers/net/ethernet/wangxun/libwx/wx_ethtool.c-852-\t.set_coalesce\t\t= wx_set_coalesce,\ndrivers/net/ethernet/wangxun/libwx/wx_ethtool.c:853:\t.get_ts_info\t\t= ethtool_op_get_ts_info,\ndrivers/net/ethernet/wangxun/libwx/wx_ethtool.c-854-\t.get_link_ksettings\t= wx_get_link_ksettings_vf,\n--\ndrivers/net/ethernet/xilinx/ll_temac_main.c=1369=static const struct ethtool_ops temac_ethtool_ops = {\n--\n\n"
}

45/3 2026/08/13 22:55 llm kmsan-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 61189
							output: 26
							thoughts: 29
						

Thoughts:
Here's my take on the thought process, summarized as you requested:

**Diving into the Timestamp Information Retrieval**

Okay, so I need to understand how timestamp information is being retrieved, specifically in the context of `ethtool`. My first step is to zero in on the relevant code, so I'm going to look at the `ethtool_op_get_ts_info` function. This likely lives within the `net/ethtool/common.c` file. That's the logical starting point for understanding how this timestamp data is pulled. Time to crack open that file and get to work. Let's see what we've got in there.



46/3 2026/08/13 22:55 tool grepper
0m Args:
{
  "Expression": "int ethtool_op_get_ts_info"
}

Results:
{
  "Output": "include/linux/ethtool.h=1464=u32 ethtool_op_get_link(struct net_device *dev);\ninclude/linux/ethtool.h:1465:int ethtool_op_get_ts_info(struct net_device *dev,\ninclude/linux/ethtool.h-1466-\t\t\t   struct kernel_ethtool_ts_info *eti);\n--\nnet/ethtool/ioctl.c=68=EXPORT_SYMBOL(ethtool_op_get_link);\nnet/ethtool/ioctl.c-69-\nnet/ethtool/ioctl.c:70:int ethtool_op_get_ts_info(struct net_device *dev,\nnet/ethtool/ioctl.c-71-\t\t\t   struct kernel_ethtool_ts_info *info)\n"
}

47/3 2026/08/13 22:55 llm kmsan-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 61610
							output: 36
							thoughts: 21
						

Thoughts:
Here's a summary of my thought process, as requested:

**Diving into `ethtool/ioctl.c`**

Okay, time to get to the heart of the matter. Let's start by looking at `net/ethtool/ioctl.c`, and I'm going to zero in on the area around line 70. This should be a good starting point for understanding how the ethtool interface interacts with the kernel. I'm expecting to find the core handling logic for the ioctls, likely the entry point for commands that set and get interface parameters. Need to understand how these commands are parsed, validated and then dispatched and executed. Lets find the ioctl numbers and how their mapping works for a starting point.



48/3 2026/08/13 22:55 tool read-file
0m Args:
{
  "File": "net/ethtool/ioctl.c",
  "FirstLine": 65,
  "LineCount": 20
}

Results:
{
  "Contents": "  65:\t\n  66:\t\treturn netif_carrier_ok(dev) ? 1 : 0;\n  67:\t}\n  68:\tEXPORT_SYMBOL(ethtool_op_get_link);\n  69:\t\n  70:\tint ethtool_op_get_ts_info(struct net_device *dev,\n  71:\t\t\t\t   struct kernel_ethtool_ts_info *info)\n  72:\t{\n  73:\t\tinfo-\u003eso_timestamping =\n  74:\t\t\tSOF_TIMESTAMPING_TX_SOFTWARE |\n  75:\t\t\tSOF_TIMESTAMPING_RX_SOFTWARE |\n  76:\t\t\tSOF_TIMESTAMPING_SOFTWARE;\n  77:\t\tinfo-\u003ephc_index = -1;\n  78:\t\treturn 0;\n  79:\t}\n  80:\tEXPORT_SYMBOL(ethtool_op_get_ts_info);\n  81:\t\n  82:\t/* Handlers for each ethtool command */\n  83:\t\n  84:\tstatic int ethtool_get_features(struct net_device *dev, void __user *useraddr)\n"
}

49/3 2026/08/13 22:55 llm kmsan-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 62125
							output: 19
							thoughts: 77
						

Thoughts:
**My Initial Thoughts on Ethtool Timestamping Information**

Okay, so `ethtool_op_get_ts_info` is setting the `so_timestamping` and `phc_index` fields. That's straightforward enough. But hold on a second... what about the `tx_types` and `rx_filters` fields? Are those being initialized anywhere before we get to this point? I need to be sure we aren't relying on undefined behavior or just garbage values here. It's crucial for the integrity of the data. I need to trace back where the `kernel_ethtool_ts_info` structure itself is initialized. Before we even *call* `.get_ts_info`, I need to confirm that these crucial elements, like `tx_types` and `rx_filters`, are properly set up. It's a quick but necessary step to make sure the timestamp information returned is actually valid.



50/3 2026/08/13 22:55 tool grepper
0m Args:
{
  "Expression": "get_ts_info"
}

Results:
{
  "Output": "\nFull output is too long, showing 500 out of 1915 lines.\nUse more precise expression if possible.\n\narch/um/drivers/vector_kern.c=1503=static const struct ethtool_ops vector_net_ethtool_ops = {\n--\narch/um/drivers/vector_kern.c-1506-\t.get_link\t= ethtool_op_get_link,\narch/um/drivers/vector_kern.c:1507:\t.get_ts_info\t= ethtool_op_get_ts_info,\narch/um/drivers/vector_kern.c-1508-\t.get_ringparam\t= vector_get_ringparam,\n--\ndrivers/net/bonding/bond_main.c=5888=static void bond_ethtool_get_drvinfo(struct net_device *bond_dev,\n--\ndrivers/net/bonding/bond_main.c-5895-\ndrivers/net/bonding/bond_main.c:5896:static int bond_ethtool_get_ts_info(struct net_device *bond_dev,\ndrivers/net/bonding/bond_main.c-5897-\t\t\t\t    struct kernel_ethtool_ts_info *info)\n--\ndrivers/net/bonding/bond_main.c-5912-\tif (real_dev) {\ndrivers/net/bonding/bond_main.c:5913:\t\tret = ethtool_get_ts_info_by_layer(real_dev, info);\ndrivers/net/bonding/bond_main.c-5914-\t} else {\n--\ndrivers/net/bonding/bond_main.c-5917-\t\tbond_for_each_slave_rcu(bond, slave, iter) {\ndrivers/net/bonding/bond_main.c:5918:\t\t\tret = ethtool_get_ts_info_by_layer(slave-\u003edev, \u0026ts_info);\ndrivers/net/bonding/bond_main.c-5919-\t\t\tif (!ret \u0026\u0026 (ts_info.so_timestamping \u0026 SOF_TIMESTAMPING_TX_SOFTWARE)) {\n--\ndrivers/net/bonding/bond_main.c=5937=static const struct ethtool_ops bond_ethtool_ops = {\n--\ndrivers/net/bonding/bond_main.c-5940-\t.get_link_ksettings\t= bond_ethtool_get_link_ksettings,\ndrivers/net/bonding/bond_main.c:5941:\t.get_ts_info\t\t= bond_ethtool_get_ts_info,\ndrivers/net/bonding/bond_main.c-5942-};\n--\ndrivers/net/can/at91_can.c=953=static const struct ethtool_ops at91_ethtool_ops = {\ndrivers/net/can/at91_can.c:954:\t.get_ts_info = ethtool_op_get_ts_info,\ndrivers/net/can/at91_can.c-955-};\n--\ndrivers/net/can/bxcan.c=886=static const struct ethtool_ops bxcan_ethtool_ops = {\ndrivers/net/can/bxcan.c:887:\t.get_ts_info = ethtool_op_get_ts_info,\ndrivers/net/can/bxcan.c-888-};\n--\ndrivers/net/can/c_can/c_can_ethtool.c=27=const struct ethtool_ops c_can_ethtool_ops = {\ndrivers/net/can/c_can/c_can_ethtool.c-28-\t.get_ringparam = c_can_get_ringparam,\ndrivers/net/can/c_can/c_can_ethtool.c:29:\t.get_ts_info = ethtool_op_get_ts_info,\ndrivers/net/can/c_can/c_can_ethtool.c-30-};\n--\ndrivers/net/can/can327.c=855=static const struct ethtool_ops can327_ethtool_ops = {\ndrivers/net/can/can327.c:856:\t.get_ts_info = ethtool_op_get_ts_info,\ndrivers/net/can/can327.c-857-};\n--\ndrivers/net/can/cc770/cc770.c=839=static const struct ethtool_ops cc770_ethtool_ops = {\ndrivers/net/can/cc770/cc770.c:840:\t.get_ts_info = ethtool_op_get_ts_info,\ndrivers/net/can/cc770/cc770.c-841-};\n--\ndrivers/net/can/ctucanfd/ctucanfd_base.c=1310=static const struct ethtool_ops ctucan_ethtool_ops = {\ndrivers/net/can/ctucanfd/ctucanfd_base.c:1311:\t.get_ts_info = ethtool_op_get_ts_info,\ndrivers/net/can/ctucanfd/ctucanfd_base.c-1312-};\n--\ndrivers/net/can/dev/dev.c=452=EXPORT_SYMBOL(can_hwtstamp_set);\ndrivers/net/can/dev/dev.c-453-\ndrivers/net/can/dev/dev.c:454:/* generic implementation of ethtool_ops::get_ts_info for CAN devices\ndrivers/net/can/dev/dev.c-455- * supporting hardware timestamps\ndrivers/net/can/dev/dev.c-456- */\ndrivers/net/can/dev/dev.c:457:int can_ethtool_op_get_ts_info_hwts(struct net_device *dev,\ndrivers/net/can/dev/dev.c-458-\t\t\t\t    struct kernel_ethtool_ts_info *info)\n--\ndrivers/net/can/dev/dev.c-469-}\ndrivers/net/can/dev/dev.c:470:EXPORT_SYMBOL(can_ethtool_op_get_ts_info_hwts);\ndrivers/net/can/dev/dev.c-471-\n--\ndrivers/net/can/dummy_can.c=228=static const struct ethtool_ops dummy_can_ethtool_ops = {\ndrivers/net/can/dummy_can.c:229:\t.get_ts_info = ethtool_op_get_ts_info,\ndrivers/net/can/dummy_can.c-230-};\n--\ndrivers/net/can/esd/esd_402_pci-core.c=93=static const struct ethtool_ops pci402_acc_ethtool_ops = {\ndrivers/net/can/esd/esd_402_pci-core.c:94:\t.get_ts_info = can_ethtool_op_get_ts_info_hwts,\ndrivers/net/can/esd/esd_402_pci-core.c-95-};\n--\ndrivers/net/can/flexcan/flexcan-ethtool.c=103=const struct ethtool_ops flexcan_ethtool_ops = {\n--\ndrivers/net/can/flexcan/flexcan-ethtool.c-108-\t.get_sset_count = flexcan_get_sset_count,\ndrivers/net/can/flexcan/flexcan-ethtool.c:109:\t.get_ts_info = ethtool_op_get_ts_info,\ndrivers/net/can/flexcan/flexcan-ethtool.c-110-};\n--\ndrivers/net/can/grcan.c=1565=static const struct ethtool_ops grcan_ethtool_ops = {\ndrivers/net/can/grcan.c:1566:\t.get_ts_info = ethtool_op_get_ts_info,\ndrivers/net/can/grcan.c-1567-};\n--\ndrivers/net/can/ifi_canfd/ifi_canfd.c=949=static const struct ethtool_ops ifi_canfd_ethtool_ops = {\ndrivers/net/can/ifi_canfd/ifi_canfd.c:950:\t.get_ts_info = ethtool_op_get_ts_info,\ndrivers/net/can/ifi_canfd/ifi_canfd.c-951-};\n--\ndrivers/net/can/janz-ican3.c=1757=static const struct ethtool_ops ican3_ethtool_ops = {\ndrivers/net/can/janz-ican3.c:1758:\t.get_ts_info = ethtool_op_get_ts_info,\ndrivers/net/can/janz-ican3.c-1759-};\n--\ndrivers/net/can/kvaser_pciefd/kvaser_pciefd_core.c=933=static const struct ethtool_ops kvaser_pciefd_ethtool_ops = {\ndrivers/net/can/kvaser_pciefd/kvaser_pciefd_core.c:934:\t.get_ts_info = can_ethtool_op_get_ts_info_hwts,\ndrivers/net/can/kvaser_pciefd/kvaser_pciefd_core.c-935-\t.set_phys_id = kvaser_pciefd_set_phys_id,\n--\ndrivers/net/can/m_can/m_can.c=2310=static const struct ethtool_ops m_can_ethtool_ops_coalescing = {\n--\ndrivers/net/can/m_can/m_can.c-2315-\t\tETHTOOL_COALESCE_TX_MAX_FRAMES_IRQ,\ndrivers/net/can/m_can/m_can.c:2316:\t.get_ts_info = ethtool_op_get_ts_info,\ndrivers/net/can/m_can/m_can.c-2317-\t.get_coalesce = m_can_get_coalesce,\n--\ndrivers/net/can/m_can/m_can.c=2323=static const struct ethtool_ops m_can_ethtool_ops = {\ndrivers/net/can/m_can/m_can.c:2324:\t.get_ts_info = ethtool_op_get_ts_info,\ndrivers/net/can/m_can/m_can.c-2325-\t.get_wol = m_can_get_wol,\n--\ndrivers/net/can/mscan/mscan.c=612=static const struct ethtool_ops mscan_ethtool_ops = {\ndrivers/net/can/mscan/mscan.c:613:\t.get_ts_info = ethtool_op_get_ts_info,\ndrivers/net/can/mscan/mscan.c-614-};\n--\ndrivers/net/can/peak_canfd/peak_canfd.c=767=static const struct net_device_ops peak_canfd_netdev_ops = {\n--\ndrivers/net/can/peak_canfd/peak_canfd.c-774-\ndrivers/net/can/peak_canfd/peak_canfd.c:775:static int peak_get_ts_info(struct net_device *dev,\ndrivers/net/can/peak_canfd/peak_canfd.c-776-\t\t\t    struct kernel_ethtool_ts_info *info)\n--\ndrivers/net/can/peak_canfd/peak_canfd.c=788=static const struct ethtool_ops peak_canfd_ethtool_ops = {\ndrivers/net/can/peak_canfd/peak_canfd.c:789:\t.get_ts_info = peak_get_ts_info,\ndrivers/net/can/peak_canfd/peak_canfd.c-790-};\n--\ndrivers/net/can/rcar/rcar_can.c=639=static const struct ethtool_ops rcar_can_ethtool_ops = {\ndrivers/net/can/rcar/rcar_can.c:640:\t.get_ts_info = ethtool_op_get_ts_info,\ndrivers/net/can/rcar/rcar_can.c-641-};\n--\ndrivers/net/can/rcar/rcar_canfd.c=1859=static const struct ethtool_ops rcar_canfd_ethtool_ops = {\ndrivers/net/can/rcar/rcar_canfd.c:1860:\t.get_ts_info = ethtool_op_get_ts_info,\ndrivers/net/can/rcar/rcar_canfd.c-1861-};\n--\ndrivers/net/can/rockchip/rockchip_canfd-ethtool.c=61=static const struct ethtool_ops rkcanfd_ethtool_ops = {\ndrivers/net/can/rockchip/rockchip_canfd-ethtool.c:62:\t.get_ts_info = can_ethtool_op_get_ts_info_hwts,\ndrivers/net/can/rockchip/rockchip_canfd-ethtool.c-63-\t.get_strings = rkcanfd_ethtool_get_strings,\n--\ndrivers/net/can/sja1000/sja1000.c=682=static const struct ethtool_ops sja1000_ethtool_ops = {\ndrivers/net/can/sja1000/sja1000.c:683:\t.get_ts_info = ethtool_op_get_ts_info,\ndrivers/net/can/sja1000/sja1000.c-684-};\n--\ndrivers/net/can/slcan/slcan-ethtool.c=55=const struct ethtool_ops slcan_ethtool_ops = {\n--\ndrivers/net/can/slcan/slcan-ethtool.c-59-\t.get_sset_count = slcan_get_sset_count,\ndrivers/net/can/slcan/slcan-ethtool.c:60:\t.get_ts_info = ethtool_op_get_ts_info,\ndrivers/net/can/slcan/slcan-ethtool.c-61-};\n--\ndrivers/net/can/softing/softing_main.c=614=static const struct ethtool_ops softing_ethtool_ops = {\ndrivers/net/can/softing/softing_main.c:615:\t.get_ts_info = ethtool_op_get_ts_info,\ndrivers/net/can/softing/softing_main.c-616-};\n--\ndrivers/net/can/spi/hi311x.c=806=static const struct ethtool_ops hi3110_ethtool_ops = {\ndrivers/net/can/spi/hi311x.c:807:\t.get_ts_info = ethtool_op_get_ts_info,\ndrivers/net/can/spi/hi311x.c-808-};\n--\ndrivers/net/can/spi/mcp251x.c=1293=static const struct ethtool_ops mcp251x_ethtool_ops = {\ndrivers/net/can/spi/mcp251x.c:1294:\t.get_ts_info = ethtool_op_get_ts_info,\ndrivers/net/can/spi/mcp251x.c-1295-};\n--\ndrivers/net/can/spi/mcp251xfd/mcp251xfd-ethtool.c=119=static const struct ethtool_ops mcp251xfd_ethtool_ops = {\n--\ndrivers/net/can/spi/mcp251xfd/mcp251xfd-ethtool.c-127-\t.set_coalesce = mcp251xfd_ring_set_coalesce,\ndrivers/net/can/spi/mcp251xfd/mcp251xfd-ethtool.c:128:\t.get_ts_info = can_ethtool_op_get_ts_info_hwts,\ndrivers/net/can/spi/mcp251xfd/mcp251xfd-ethtool.c-129-};\n--\ndrivers/net/can/sun4i_can.c=773=static const struct ethtool_ops sun4ican_ethtool_ops = {\ndrivers/net/can/sun4i_can.c:774:\t.get_ts_info = ethtool_op_get_ts_info,\ndrivers/net/can/sun4i_can.c-775-};\n--\ndrivers/net/can/ti_hecc.c=834=static const struct ethtool_ops ti_hecc_ethtool_ops = {\ndrivers/net/can/ti_hecc.c:835:\t.get_ts_info = ethtool_op_get_ts_info,\ndrivers/net/can/ti_hecc.c-836-};\n--\ndrivers/net/can/usb/ems_usb.c=944=static const struct ethtool_ops ems_usb_ethtool_ops = {\ndrivers/net/can/usb/ems_usb.c:945:\t.get_ts_info = ethtool_op_get_ts_info,\ndrivers/net/can/usb/ems_usb.c-946-};\n--\ndrivers/net/can/usb/esd_usb.c=1019=static const struct ethtool_ops esd_usb_ethtool_ops = {\ndrivers/net/can/usb/esd_usb.c:1020:\t.get_ts_info = ethtool_op_get_ts_info,\ndrivers/net/can/usb/esd_usb.c-1021-};\n--\ndrivers/net/can/usb/etas_es58x/es58x_core.c=1988=static const struct ethtool_ops es58x_ethtool_ops = {\ndrivers/net/can/usb/etas_es58x/es58x_core.c:1989:\t.get_ts_info = can_ethtool_op_get_ts_info_hwts,\ndrivers/net/can/usb/etas_es58x/es58x_core.c-1990-};\n--\ndrivers/net/can/usb/f81604.c=126=static const struct ethtool_ops f81604_ethtool_ops = {\ndrivers/net/can/usb/f81604.c:127:\t.get_ts_info = ethtool_op_get_ts_info,\ndrivers/net/can/usb/f81604.c-128-};\n--\ndrivers/net/can/usb/gs_usb.c=1233=static int gs_usb_set_phys_id(struct net_device *netdev,\n--\ndrivers/net/can/usb/gs_usb.c-1255-\ndrivers/net/can/usb/gs_usb.c:1256:static int gs_usb_get_ts_info(struct net_device *netdev,\ndrivers/net/can/usb/gs_usb.c-1257-\t\t\t      struct kernel_ethtool_ts_info *info)\n--\ndrivers/net/can/usb/gs_usb.c-1262-\tif (dev-\u003efeature \u0026 GS_CAN_FEATURE_HW_TIMESTAMP)\ndrivers/net/can/usb/gs_usb.c:1263:\t\treturn can_ethtool_op_get_ts_info_hwts(netdev, info);\ndrivers/net/can/usb/gs_usb.c-1264-\ndrivers/net/can/usb/gs_usb.c:1265:\treturn ethtool_op_get_ts_info(netdev, info);\ndrivers/net/can/usb/gs_usb.c-1266-}\n--\ndrivers/net/can/usb/gs_usb.c=1268=static const struct ethtool_ops gs_usb_ethtool_ops = {\ndrivers/net/can/usb/gs_usb.c-1269-\t.set_phys_id = gs_usb_set_phys_id,\ndrivers/net/can/usb/gs_usb.c:1270:\t.get_ts_info = gs_usb_get_ts_info,\ndrivers/net/can/usb/gs_usb.c-1271-};\n--\ndrivers/net/can/usb/kvaser_usb/kvaser_usb_core.c=799=static const struct ethtool_ops kvaser_usb_ethtool_ops = {\ndrivers/net/can/usb/kvaser_usb/kvaser_usb_core.c:800:\t.get_ts_info = can_ethtool_op_get_ts_info_hwts,\ndrivers/net/can/usb/kvaser_usb/kvaser_usb_core.c-801-\t.set_phys_id = kvaser_usb_set_phys_id,\n--\ndrivers/net/can/usb/mcba_usb.c=772=static const struct ethtool_ops mcba_ethtool_ops = {\ndrivers/net/can/usb/mcba_usb.c:773:\t.get_ts_info = ethtool_op_get_ts_info,\ndrivers/net/can/usb/mcba_usb.c-774-};\n--\ndrivers/net/can/usb/nct6694_canfd.c=695=static const struct ethtool_ops nct6694_canfd_ethtool_ops = {\ndrivers/net/can/usb/nct6694_canfd.c:696:\t.get_ts_info = ethtool_op_get_ts_info,\ndrivers/net/can/usb/nct6694_canfd.c-697-};\n--\ndrivers/net/can/usb/peak_usb/pcan_usb.c=992=static const struct ethtool_ops pcan_usb_ethtool_ops = {\ndrivers/net/can/usb/peak_usb/pcan_usb.c-993-\t.set_phys_id = pcan_usb_set_phys_id,\ndrivers/net/can/usb/peak_usb/pcan_usb.c:994:\t.get_ts_info = pcan_get_ts_info,\ndrivers/net/can/usb/peak_usb/pcan_usb.c-995-\t.get_eeprom_len\t= pcan_usb_get_eeprom_len,\n--\ndrivers/net/can/usb/peak_usb/pcan_usb_core.c=855=int peak_usb_set_eeprom(struct net_device *netdev,\n--\ndrivers/net/can/usb/peak_usb/pcan_usb_core.c-894-\ndrivers/net/can/usb/peak_usb/pcan_usb_core.c:895:int pcan_get_ts_info(struct net_device *dev, struct kernel_ethtool_ts_info *info)\ndrivers/net/can/usb/peak_usb/pcan_usb_core.c-896-{\n--\ndrivers/net/can/usb/peak_usb/pcan_usb_core.h=147=void peak_usb_restart_complete(struct peak_usb_device *dev);\ndrivers/net/can/usb/peak_usb/pcan_usb_core.h:148:int pcan_get_ts_info(struct net_device *dev, struct kernel_ethtool_ts_info *info);\ndrivers/net/can/usb/peak_usb/pcan_usb_core.h-149-\n--\ndrivers/net/can/usb/peak_usb/pcan_usb_fd.c=1164=static const struct ethtool_ops pcan_usb_fd_ethtool_ops = {\ndrivers/net/can/usb/peak_usb/pcan_usb_fd.c-1165-\t.set_phys_id = pcan_usb_fd_set_phys_id,\ndrivers/net/can/usb/peak_usb/pcan_usb_fd.c:1166:\t.get_ts_info = pcan_get_ts_info,\ndrivers/net/can/usb/peak_usb/pcan_usb_fd.c-1167-\t.get_eeprom_len\t= peak_usb_get_eeprom_len,\n--\ndrivers/net/can/usb/peak_usb/pcan_usb_pro.c=1048=static const struct ethtool_ops pcan_usb_pro_ethtool_ops = {\ndrivers/net/can/usb/peak_usb/pcan_usb_pro.c-1049-\t.set_phys_id = pcan_usb_pro_set_phys_id,\ndrivers/net/can/usb/peak_usb/pcan_usb_pro.c:1050:\t.get_ts_info = pcan_get_ts_info,\ndrivers/net/can/usb/peak_usb/pcan_usb_pro.c-1051-\t.get_eeprom_len\t= peak_usb_get_eeprom_len,\n--\ndrivers/net/can/usb/ucan.c=1237=static const struct ethtool_ops ucan_ethtool_ops = {\ndrivers/net/can/usb/ucan.c:1238:\t.get_ts_info = ethtool_op_get_ts_info,\ndrivers/net/can/usb/ucan.c-1239-};\n--\ndrivers/net/can/usb/usb_8dev.c=879=static const struct ethtool_ops usb_8dev_ethtool_ops = {\ndrivers/net/can/usb/usb_8dev.c:880:\t.get_ts_info = ethtool_op_get_ts_info,\ndrivers/net/can/usb/usb_8dev.c-881-};\n--\ndrivers/net/can/vcan.c=166=static const struct ethtool_ops vcan_ethtool_ops = {\ndrivers/net/can/vcan.c:167:\t.get_ts_info = ethtool_op_get_ts_info,\ndrivers/net/can/vcan.c-168-};\n--\ndrivers/net/can/vxcan.c=177=static const struct ethtool_ops vxcan_ethtool_ops = {\ndrivers/net/can/vxcan.c:178:\t.get_ts_info = ethtool_op_get_ts_info,\ndrivers/net/can/vxcan.c-179-};\n--\ndrivers/net/can/xilinx_can.c=1707=static const struct ethtool_ops xcan_ethtool_ops = {\ndrivers/net/can/xilinx_can.c:1708:\t.get_ts_info = ethtool_op_get_ts_info,\ndrivers/net/can/xilinx_can.c-1709-\t.get_strings = xcan_get_strings,\n--\ndrivers/net/dsa/hirschmann/hellcreek.c=1900=static const struct dsa_switch_ops hellcreek_ds_ops = {\n--\ndrivers/net/dsa/hirschmann/hellcreek.c-1905-\t.get_tag_protocol      = hellcreek_get_tag_protocol,\ndrivers/net/dsa/hirschmann/hellcreek.c:1906:\t.get_ts_info\t       = hellcreek_get_ts_info,\ndrivers/net/dsa/hirschmann/hellcreek.c-1907-\t.phylink_get_caps      = hellcreek_phylink_get_caps,\n--\ndrivers/net/dsa/hirschmann/hellcreek_hwtstamp.c-17-\ndrivers/net/dsa/hirschmann/hellcreek_hwtstamp.c:18:int hellcreek_get_ts_info(struct dsa_switch *ds, int port,\ndrivers/net/dsa/hirschmann/hellcreek_hwtstamp.c-19-\t\t\t  struct kernel_ethtool_ts_info *info)\n--\ndrivers/net/dsa/hirschmann/hellcreek_hwtstamp.h=48=void hellcreek_port_txtstamp(struct dsa_switch *ds, int port,\n--\ndrivers/net/dsa/hirschmann/hellcreek_hwtstamp.h-50-\ndrivers/net/dsa/hirschmann/hellcreek_hwtstamp.h:51:int hellcreek_get_ts_info(struct dsa_switch *ds, int port,\ndrivers/net/dsa/hirschmann/hellcreek_hwtstamp.h-52-\t\t\t  struct kernel_ethtool_ts_info *info);\n--\ndrivers/net/dsa/microchip/ksz8.c=3114=const struct dsa_switch_ops ksz8463_switch_ops = {\n--\ndrivers/net/dsa/microchip/ksz8.c-3145-\t.resume\t\t\t= ksz_resume,\ndrivers/net/dsa/microchip/ksz8.c:3146:\t.get_ts_info\t\t= ksz8463_get_ts_info,\ndrivers/net/dsa/microchip/ksz8.c-3147-\t.port_hwtstamp_get\t= ksz_hwtstamp_get,\n--\ndrivers/net/dsa/microchip/ksz8.c=3161=const struct dsa_switch_ops ksz87xx_switch_ops = {\n--\ndrivers/net/dsa/microchip/ksz8.c-3195-\t.resume\t\t\t= ksz_resume,\ndrivers/net/dsa/microchip/ksz8.c:3196:\t.get_ts_info\t\t= ksz_get_ts_info,\ndrivers/net/dsa/microchip/ksz8.c-3197-\t.port_hwtstamp_get\t= ksz_hwtstamp_get,\n--\ndrivers/net/dsa/microchip/ksz8.c=3211=const struct dsa_switch_ops ksz88xx_switch_ops = {\n--\ndrivers/net/dsa/microchip/ksz8.c-3248-\t.resume\t\t\t= ksz_resume,\ndrivers/net/dsa/microchip/ksz8.c:3249:\t.get_ts_info\t\t= ksz_get_ts_info,\ndrivers/net/dsa/microchip/ksz8.c-3250-\t.port_hwtstamp_get\t= ksz_hwtstamp_get,\n--\ndrivers/net/dsa/microchip/ksz9477.c=2215=const struct dsa_switch_ops ksz9477_switch_ops = {\n--\ndrivers/net/dsa/microchip/ksz9477.c-2255-\t.resume\t\t\t= ksz_resume,\ndrivers/net/dsa/microchip/ksz9477.c:2256:\t.get_ts_info\t\t= ksz_get_ts_info,\ndrivers/net/dsa/microchip/ksz9477.c-2257-\t.port_hwtstamp_get\t= ksz_hwtstamp_get,\n--\ndrivers/net/dsa/microchip/ksz_ptp.c=271=static int ksz_ptp_enable_mode(struct ksz_device *dev)\n--\ndrivers/net/dsa/microchip/ksz_ptp.c-299-\ndrivers/net/dsa/microchip/ksz_ptp.c:300:int ksz8463_get_ts_info(struct dsa_switch *ds, int port,\ndrivers/net/dsa/microchip/ksz_ptp.c-301-\t\t\tstruct kernel_ethtool_ts_info *ts)\n--\ndrivers/net/dsa/microchip/ksz_ptp.c-327- */\ndrivers/net/dsa/microchip/ksz_ptp.c:328:int ksz_get_ts_info(struct dsa_switch *ds, int port, struct kernel_ethtool_ts_info *ts)\ndrivers/net/dsa/microchip/ksz_ptp.c-329-{\n--\ndrivers/net/dsa/microchip/ksz_ptp.h=38=void ksz_ptp_clock_unregister(struct dsa_switch *ds);\ndrivers/net/dsa/microchip/ksz_ptp.h-39-\ndrivers/net/dsa/microchip/ksz_ptp.h:40:int ksz_get_ts_info(struct dsa_switch *ds, int port,\ndrivers/net/dsa/microchip/ksz_ptp.h-41-\t\t    struct kernel_ethtool_ts_info *ts);\ndrivers/net/dsa/microchip/ksz_ptp.h:42:int ksz8463_get_ts_info(struct dsa_switch *ds, int port,\ndrivers/net/dsa/microchip/ksz_ptp.h-43-\t\t\tstruct kernel_ethtool_ts_info *ts);\n--\ndrivers/net/dsa/microchip/ksz_ptp.h=87=static inline void ksz8463_ptp_irq_free(struct dsa_switch *ds) {}\ndrivers/net/dsa/microchip/ksz_ptp.h-88-\ndrivers/net/dsa/microchip/ksz_ptp.h:89:#define ksz_get_ts_info NULL\ndrivers/net/dsa/microchip/ksz_ptp.h:90:#define ksz8463_get_ts_info NULL\ndrivers/net/dsa/microchip/ksz_ptp.h-91-\n--\ndrivers/net/dsa/microchip/lan937x_main.c=949=const struct dsa_switch_ops lan937x_switch_ops = {\n--\ndrivers/net/dsa/microchip/lan937x_main.c-984-\t.resume\t\t\t= ksz_resume,\ndrivers/net/dsa/microchip/lan937x_main.c:985:\t.get_ts_info\t\t= ksz_get_ts_info,\ndrivers/net/dsa/microchip/lan937x_main.c-986-\t.port_hwtstamp_get\t= ksz_hwtstamp_get,\n--\ndrivers/net/dsa/mv88e6xxx/chip.c=7187=static const struct dsa_switch_ops mv88e6xxx_switch_ops = {\n--\ndrivers/net/dsa/mv88e6xxx/chip.c-7238-\t.cls_flower_del         = mv88e6xxx_cls_flower_del,\ndrivers/net/dsa/mv88e6xxx/chip.c:7239:\t.get_ts_info\t\t= mv88e6xxx_get_ts_info,\ndrivers/net/dsa/mv88e6xxx/chip.c-7240-\t.devlink_param_get\t= mv88e6xxx_devlink_param_get,\n--\ndrivers/net/dsa/mv88e6xxx/hwtstamp.c=50=static int mv88e6xxx_ptp_read(struct mv88e6xxx_chip *chip, int addr,\n--\ndrivers/net/dsa/mv88e6xxx/hwtstamp.c-65-\ndrivers/net/dsa/mv88e6xxx/hwtstamp.c:66:int mv88e6xxx_get_ts_info(struct dsa_switch *ds, int port,\ndrivers/net/dsa/mv88e6xxx/hwtstamp.c-67-\t\t\t  struct kernel_ethtool_ts_info *info)\n--\ndrivers/net/dsa/mv88e6xxx/hwtstamp.h=121=void mv88e6xxx_port_txtstamp(struct dsa_switch *ds, int port,\n--\ndrivers/net/dsa/mv88e6xxx/hwtstamp.h-123-\ndrivers/net/dsa/mv88e6xxx/hwtstamp.h:124:int mv88e6xxx_get_ts_info(struct dsa_switch *ds, int port,\ndrivers/net/dsa/mv88e6xxx/hwtstamp.h-125-\t\t\t  struct kernel_ethtool_ts_info *info);\n--\ndrivers/net/dsa/mv88e6xxx/hwtstamp.h=159=static inline void mv88e6xxx_port_txtstamp(struct dsa_switch *ds, int port,\n--\ndrivers/net/dsa/mv88e6xxx/hwtstamp.h-163-\ndrivers/net/dsa/mv88e6xxx/hwtstamp.h:164:static inline int mv88e6xxx_get_ts_info(struct dsa_switch *ds, int port,\ndrivers/net/dsa/mv88e6xxx/hwtstamp.h-165-\t\t\t\t\tstruct kernel_ethtool_ts_info *info)\n--\ndrivers/net/dsa/ocelot/felix.c=1363=static int felix_get_sset_count(struct dsa_switch *ds, int port, int sset)\n--\ndrivers/net/dsa/ocelot/felix.c-1369-\ndrivers/net/dsa/ocelot/felix.c:1370:static int felix_get_ts_info(struct dsa_switch *ds, int port,\ndrivers/net/dsa/ocelot/felix.c-1371-\t\t\t     struct kernel_ethtool_ts_info *info)\n--\ndrivers/net/dsa/ocelot/felix.c-1374-\ndrivers/net/dsa/ocelot/felix.c:1375:\treturn ocelot_get_ts_info(ocelot, port, info);\ndrivers/net/dsa/ocelot/felix.c-1376-}\n--\ndrivers/net/dsa/ocelot/felix.c=2306=static const struct dsa_switch_ops felix_switch_ops = {\n--\ndrivers/net/dsa/ocelot/felix.c-2325-\t.get_sset_count\t\t\t= felix_get_sset_count,\ndrivers/net/dsa/ocelot/felix.c:2326:\t.get_ts_info\t\t\t= felix_get_ts_info,\ndrivers/net/dsa/ocelot/felix.c-2327-\t.phylink_get_caps\t\t= felix_phylink_get_caps,\n--\ndrivers/net/dsa/sja1105/sja1105_main.c=3143=static const struct dsa_switch_ops sja1105_switch_ops = {\n--\ndrivers/net/dsa/sja1105/sja1105_main.c-3154-\t.get_sset_count\t\t= sja1105_get_sset_count,\ndrivers/net/dsa/sja1105/sja1105_main.c:3155:\t.get_ts_info\t\t= sja1105_get_ts_info,\ndrivers/net/dsa/sja1105/sja1105_main.c-3156-\t.port_fdb_dump\t\t= sja1105_fdb_dump,\n--\ndrivers/net/dsa/sja1105/sja1105_ptp.c=99=int sja1105_hwtstamp_get(struct dsa_switch *ds, int port,\n--\ndrivers/net/dsa/sja1105/sja1105_ptp.c-116-\ndrivers/net/dsa/sja1105/sja1105_ptp.c:117:int sja1105_get_ts_info(struct dsa_switch *ds, int port,\ndrivers/net/dsa/sja1105/sja1105_ptp.c-118-\t\t\tstruct kernel_ethtool_ts_info *info)\n--\ndrivers/net/dsa/sja1105/sja1105_ptp.h=100=void sja1105pqrs_ptp_cmd_packing(u8 *buf, struct sja1105_ptp_cmd *cmd,\n--\ndrivers/net/dsa/sja1105/sja1105_ptp.h-102-\ndrivers/net/dsa/sja1105/sja1105_ptp.h:103:int sja1105_get_ts_info(struct dsa_switch *ds, int port,\ndrivers/net/dsa/sja1105/sja1105_ptp.h-104-\t\t\tstruct kernel_ethtool_ts_info *ts);\n--\ndrivers/net/dsa/sja1105/sja1105_ptp.h=181=static inline int sja1105_ptp_commit(struct dsa_switch *ds,\n--\ndrivers/net/dsa/sja1105/sja1105_ptp.h-191-\ndrivers/net/dsa/sja1105/sja1105_ptp.h:192:#define sja1105_get_ts_info NULL\ndrivers/net/dsa/sja1105/sja1105_ptp.h-193-\n--\ndrivers/net/dummy.c=99=static const struct ethtool_ops dummy_ethtool_ops = {\ndrivers/net/dummy.c:100:\t.get_ts_info\t\t= ethtool_op_get_ts_info,\ndrivers/net/dummy.c-101-};\n--\ndrivers/net/ethernet/3com/3c59x.c=3009=static const struct ethtool_ops vortex_ethtool_ops = {\n--\ndrivers/net/ethernet/3com/3c59x.c-3019-\t.set_wol                = vortex_set_wol,\ndrivers/net/ethernet/3com/3c59x.c:3020:\t.get_ts_info\t\t= ethtool_op_get_ts_info,\ndrivers/net/ethernet/3com/3c59x.c-3021-\t.get_link_ksettings     = vortex_get_link_ksettings,\n--\ndrivers/net/ethernet/8390/ax88796.c=601=static const struct ethtool_ops ax_ethtool_ops = {\n--\ndrivers/net/ethernet/8390/ax88796.c-603-\t.get_link\t\t= ethtool_op_get_link,\ndrivers/net/ethernet/8390/ax88796.c:604:\t.get_ts_info\t\t= ethtool_op_get_ts_info,\ndrivers/net/ethernet/8390/ax88796.c-605-\t.get_msglevel\t\t= ax_get_msglevel,\n--\ndrivers/net/ethernet/8390/etherh.c=624=static const struct ethtool_ops etherh_ethtool_ops = {\ndrivers/net/ethernet/8390/etherh.c-625-\t.get_drvinfo\t\t= etherh_get_drvinfo,\ndrivers/net/ethernet/8390/etherh.c:626:\t.get_ts_info\t\t= ethtool_op_get_ts_info,\ndrivers/net/ethernet/8390/etherh.c-627-\t.get_msglevel\t\t= etherh_get_msglevel,\n--\ndrivers/net/ethernet/altera/altera_tse_ethtool.c=240=static const struct ethtool_ops tse_ethtool_ops = {\n--\ndrivers/net/ethernet/altera/altera_tse_ethtool.c-251-\t.set_link_ksettings = tse_ethtool_set_link_ksettings,\ndrivers/net/ethernet/altera/altera_tse_ethtool.c:252:\t.get_ts_info = ethtool_op_get_ts_info,\ndrivers/net/ethernet/altera/altera_tse_ethtool.c-253-};\n--\ndrivers/net/ethernet/amazon/ena/ena_ethtool.c=294=static void ena_get_ethtool_stats(struct net_device *netdev,\n--\ndrivers/net/ethernet/amazon/ena/ena_ethtool.c-302-\ndrivers/net/ethernet/amazon/ena/ena_ethtool.c:303:static int ena_get_ts_info(struct net_device *netdev,\ndrivers/net/ethernet/amazon/ena/ena_ethtool.c-304-\t\t\t   struct kernel_ethtool_ts_info *info)\n--\ndrivers/net/ethernet/amazon/ena/ena_ethtool.c=1066=static const struct ethtool_ops ena_ethtool_ops = {\n--\ndrivers/net/ethernet/amazon/ena/ena_ethtool.c-1093-\t.set_tunable\t\t= ena_set_tunable,\ndrivers/net/ethernet/amazon/ena/ena_ethtool.c:1094:\t.get_ts_info\t\t= ena_get_ts_info,\ndrivers/net/ethernet/amazon/ena/ena_ethtool.c-1095-};\n--\ndrivers/net/ethernet/amd/xgbe/xgbe-ethtool.c=461=static int xgbe_set_rxfh(struct net_device *netdev,\n--\ndrivers/net/ethernet/amd/xgbe/xgbe-ethtool.c-489-\ndrivers/net/ethernet/amd/xgbe/xgbe-ethtool.c:490:static int xgbe_get_ts_info(struct net_device *netdev,\ndrivers/net/ethernet/amd/xgbe/xgbe-ethtool.c-491-\t\t\t    struct kernel_ethtool_ts_info *ts_info)\n--\ndrivers/net/ethernet/amd/xgbe/xgbe-ethtool.c=737=static const struct ethtool_ops xgbe_ethtool_ops = {\n--\ndrivers/net/ethernet/amd/xgbe/xgbe-ethtool.c-755-\t.set_rxfh = xgbe_set_rxfh,\ndrivers/net/ethernet/amd/xgbe/xgbe-ethtool.c:756:\t.get_ts_info = xgbe_get_ts_info,\ndrivers/net/ethernet/amd/xgbe/xgbe-ethtool.c-757-\t.get_link_ksettings = xgbe_get_link_ksettings,\n--\ndrivers/net/ethernet/aquantia/atlantic/aq_ethtool.c=633=static int aq_ethtool_set_wol(struct net_device *ndev,\n--\ndrivers/net/ethernet/aquantia/atlantic/aq_ethtool.c-652-\ndrivers/net/ethernet/aquantia/atlantic/aq_ethtool.c:653:static int aq_ethtool_get_ts_info(struct net_device *ndev,\ndrivers/net/ethernet/aquantia/atlantic/aq_ethtool.c-654-\t\t\t\t  struct kernel_ethtool_ts_info *info)\n--\ndrivers/net/ethernet/aquantia/atlantic/aq_ethtool.c-657-\ndrivers/net/ethernet/aquantia/atlantic/aq_ethtool.c:658:\tethtool_op_get_ts_info(ndev, info);\ndrivers/net/ethernet/aquantia/atlantic/aq_ethtool.c-659-\n--\ndrivers/net/ethernet/aquantia/atlantic/aq_ethtool.c=1091=const struct ethtool_ops aq_ethtool_ops = {\n--\ndrivers/net/ethernet/aquantia/atlantic/aq_ethtool.c-1125-\t.set_coalesce\t     = aq_ethtool_set_coalesce,\ndrivers/net/ethernet/aquantia/atlantic/aq_ethtool.c:1126:\t.get_ts_info         = aq_ethtool_get_ts_info,\ndrivers/net/ethernet/aquantia/atlantic/aq_ethtool.c-1127-\t.get_phy_tunable     = aq_ethtool_get_phy_tunable,\n--\ndrivers/net/ethernet/atheros/ag71xx.c=542=static const struct ethtool_ops ag71xx_ethtool_ops = {\n--\ndrivers/net/ethernet/atheros/ag71xx.c-544-\t.get_link\t\t\t= ethtool_op_get_link,\ndrivers/net/ethernet/atheros/ag71xx.c:545:\t.get_ts_info\t\t\t= ethtool_op_get_ts_info,\ndrivers/net/ethernet/atheros/ag71xx.c-546-\t.get_link_ksettings\t\t= ag71xx_get_link_ksettings,\n--\ndrivers/net/ethernet/broadcom/asp2/bcmasp_ethtool.c=443=const struct ethtool_ops bcmasp_ethtool_ops = {\n--\ndrivers/net/ethernet/broadcom/asp2/bcmasp_ethtool.c-461-\t.get_sset_count\t\t= bcmasp_get_sset_count,\ndrivers/net/ethernet/broadcom/asp2/bcmasp_ethtool.c:462:\t.get_ts_info\t\t= ethtool_op_get_ts_info,\ndrivers/net/ethernet/broadcom/asp2/bcmasp_ethtool.c-463-\t.nway_reset\t\t= phy_ethtool_nway_reset,\n--\ndrivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c=3569=static int bnx2x_set_channels(struct net_device *dev,\n--\ndrivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c-3612-\ndrivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c:3613:static int bnx2x_get_ts_info(struct net_device *dev,\ndrivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c-3614-\t\t\t     struct kernel_ethtool_ts_info *info)\n--\ndrivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c-3636-\ndrivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c:3637:\treturn ethtool_op_get_ts_info(dev, info);\ndrivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c-3638-}\n--\ndrivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c=3640=static const struct ethtool_ops bnx2x_ethtool_ops = {\n--\ndrivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c-3680-\t.set_eee\t\t= bnx2x_set_eee,\ndrivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c:3681:\t.get_ts_info\t\t= bnx2x_get_ts_info,\ndrivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c-3682-\t.get_link_ksettings\t= bnx2x_get_link_ksettings,\n--\ndrivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c=5441=static int bnxt_get_dump_data(struct net_device *dev, struct ethtool_dump *dump,\n--\ndrivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c-5454-\ndrivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c:5455:static int bnxt_get_ts_info(struct net_device *dev,\ndrivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c-5456-\t\t\t    struct kernel_ethtool_ts_info *info)\n--\ndrivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c=5727=const struct ethtool_ops bnxt_ethtool_ops = {\n--\ndrivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c-5799-\t.self_test\t\t= bnxt_self_test,\ndrivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c:5800:\t.get_ts_info\t\t= bnxt_get_ts_info,\ndrivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c-5801-\t.reset\t\t\t= bnxt_reset,\n--\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c=1678=static const struct ethtool_ops bcmgenet_ethtool_ops = {\n--\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c-1699-\t.set_link_ksettings\t= bcmgenet_set_link_ksettings,\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c:1700:\t.get_ts_info\t\t= ethtool_op_get_ts_info,\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c-1701-\t.get_rxnfc\t\t= bcmgenet_get_rxnfc,\n\n"
}

51/3 2026/08/13 22:55 llm kmsan-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 76573
							output: 27
							thoughts: 31
						

Thoughts:
Here's my attempt at summarizing the thought process, tailored for an expert audience:

**Diving into `ethtool_get_ts_info_by_layer`**

Okay, I need to understand how this timestamping information is being retrieved. Let's start by looking directly at the source. Specifically, I need to examine the `ethtool_get_ts_info_by_layer` function. It's located in `net/ethtool/common.c`, so I'll navigate there and get a handle on what's going on. I expect this function is the central point for ethtool to pull the timestamping capabilities and settings for a given network interface. I'm hoping I can see how it determines the layer-specific details (e.g., hardware versus software timestamps, protocol-specific adjustments, etc.) by looking at that function. I'll focus on how it interacts with the underlying driver data structures. I need to understand the logic flow here.



52/3 2026/08/13 22:56 tool grepper
0m Args:
{
  "Expression": "ethtool_get_ts_info_by_layer"
}

Results:
{
  "Output": "drivers/net/bonding/bond_main.c=5896=static int bond_ethtool_get_ts_info(struct net_device *bond_dev,\n--\ndrivers/net/bonding/bond_main.c-5912-\tif (real_dev) {\ndrivers/net/bonding/bond_main.c:5913:\t\tret = ethtool_get_ts_info_by_layer(real_dev, info);\ndrivers/net/bonding/bond_main.c-5914-\t} else {\n--\ndrivers/net/bonding/bond_main.c-5917-\t\tbond_for_each_slave_rcu(bond, slave, iter) {\ndrivers/net/bonding/bond_main.c:5918:\t\t\tret = ethtool_get_ts_info_by_layer(slave-\u003edev, \u0026ts_info);\ndrivers/net/bonding/bond_main.c-5919-\t\t\tif (!ret \u0026\u0026 (ts_info.so_timestamping \u0026 SOF_TIMESTAMPING_TX_SOFTWARE)) {\n--\ndrivers/net/macvlan.c=1106=static int macvlan_ethtool_get_ts_info(struct net_device *dev,\n--\ndrivers/net/macvlan.c-1110-\ndrivers/net/macvlan.c:1111:\treturn ethtool_get_ts_info_by_layer(real_dev, info);\ndrivers/net/macvlan.c-1112-}\n--\ninclude/linux/ethtool.h=1492=static inline int ethtool_mm_frag_size_min_to_add(u32 val_min, u32 *val_add,\n--\ninclude/linux/ethtool.h-1509-/**\ninclude/linux/ethtool.h:1510: * ethtool_get_ts_info_by_layer - Obtains time stamping capabilities from the MAC or PHY layer.\ninclude/linux/ethtool.h-1511- * @dev: pointer to net_device structure\n--\ninclude/linux/ethtool.h-1514- */\ninclude/linux/ethtool.h:1515:int ethtool_get_ts_info_by_layer(struct net_device *dev,\ninclude/linux/ethtool.h-1516-\t\t\t\t struct kernel_ethtool_ts_info *info);\n--\nnet/8021q/vlan_dev.c=672=static int vlan_ethtool_get_ts_info(struct net_device *dev,\n--\nnet/8021q/vlan_dev.c-675-\tconst struct vlan_dev_priv *vlan = vlan_dev_priv(dev);\nnet/8021q/vlan_dev.c:676:\treturn ethtool_get_ts_info_by_layer(vlan-\u003ereal_dev, info);\nnet/8021q/vlan_dev.c-677-}\n--\nnet/ethtool/common.c=1140=EXPORT_SYMBOL(ethtool_get_phc_vclocks);\nnet/ethtool/common.c-1141-\nnet/ethtool/common.c:1142:int ethtool_get_ts_info_by_layer(struct net_device *dev, struct kernel_ethtool_ts_info *info)\nnet/ethtool/common.c-1143-{\n--\nnet/ethtool/common.c-1145-}\nnet/ethtool/common.c:1146:EXPORT_SYMBOL(ethtool_get_ts_info_by_layer);\nnet/ethtool/common.c-1147-\n"
}

53/3 2026/08/13 22:56 llm kmsan-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 77792
							output: 38
							thoughts: 23
						

Thoughts:
Here's my attempt at summarizing the thought process, tailored for an expert audience:

**Diving into ethtool's Common Code**

Okay, time to get my hands dirty. I'm going to start digging into the `net/ethtool/common.c` file. Specifically, I need to get my bearings around line 1142. I'm hoping that specific area holds the key to figuring out [**Insert Your field of Expertise Here, in relation to ethtool**]. I have a hunch that the data structures/functions implemented there might be the critical piece for [**Insert your hypothesis**]. I need to refresh my memory on what's defined and how it functions in that part of the codebase. Let's see if this particular section reveals the details I need.



54/3 2026/08/13 22:56 tool read-file
0m Args:
{
  "File": "net/ethtool/common.c",
  "FirstLine": 1135,
  "LineCount": 20
}

Results:
{
  "Contents": "1135:\t\tif (!__ethtool_get_ts_info(dev, \u0026info))\n1136:\t\t\tnum = ptp_get_vclocks_index(info.phc_index, vclock_index);\n1137:\t\n1138:\t\treturn num;\n1139:\t}\n1140:\tEXPORT_SYMBOL(ethtool_get_phc_vclocks);\n1141:\t\n1142:\tint ethtool_get_ts_info_by_layer(struct net_device *dev, struct kernel_ethtool_ts_info *info)\n1143:\t{\n1144:\t\treturn __ethtool_get_ts_info(dev, info);\n1145:\t}\n1146:\tEXPORT_SYMBOL(ethtool_get_ts_info_by_layer);\n1147:\t\n1148:\tconst struct ethtool_phy_ops *ethtool_phy_ops;\n1149:\t\n1150:\tvoid ethtool_set_ethtool_phy_ops(const struct ethtool_phy_ops *ops)\n1151:\t{\n1152:\t\tASSERT_RTNL();\n1153:\t\tethtool_phy_ops = ops;\n1154:\t}\n"
}

55/3 2026/08/13 22:56 llm kmsan-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 78373
							output: 24
							thoughts: 28
						

Thoughts:
Here's my attempt at summarizing the thought process, tailored for an expert audience:

**Diving into ethtool Timestamping**

Alright, let's get down to brass tacks. I need to understand how ethtool is handling timestamping information. The natural starting point, as always, is digging into the code. My gut tells me that `__ethtool_get_ts_info` in `net/ethtool/common.c` is the key function to examine. It's the standard entry point for getting this kind of details, so let's start there. I'm expecting this function will be the control panel for retrieving, and probably displaying, the hardware timestamping capabilities of the NIC. I'll be looking closely at how it interacts with the underlying driver's data structures, specifically the `ethtool_ts_info` struct, and how it handles potential errors from the driver. Time to see what magic this function is pulling.



56/3 2026/08/13 22:56 tool grepper
0m Args:
{
  "Expression": "__ethtool_get_ts_info"
}

Results:
{
  "Output": "net/ethtool/common.c=1035=int ethtool_get_ts_info_by_phc(struct net_device *dev,\n--\nnet/ethtool/common.c-1066-\nnet/ethtool/common.c:1067:int __ethtool_get_ts_info(struct net_device *dev,\nnet/ethtool/common.c-1068-\t\t\t  struct kernel_ethtool_ts_info *info)\n--\nnet/ethtool/common.c=1130=int ethtool_get_phc_vclocks(struct net_device *dev, int **vclock_index)\n--\nnet/ethtool/common.c-1134-\nnet/ethtool/common.c:1135:\tif (!__ethtool_get_ts_info(dev, \u0026info))\nnet/ethtool/common.c-1136-\t\tnum = ptp_get_vclocks_index(info.phc_index, vclock_index);\n--\nnet/ethtool/common.c=1142=int ethtool_get_ts_info_by_layer(struct net_device *dev, struct kernel_ethtool_ts_info *info)\nnet/ethtool/common.c-1143-{\nnet/ethtool/common.c:1144:\treturn __ethtool_get_ts_info(dev, info);\nnet/ethtool/common.c-1145-}\n--\nnet/ethtool/common.h=57=int ethtool_get_rx_ring_count(struct net_device *dev);\nnet/ethtool/common.h-58-\nnet/ethtool/common.h:59:int __ethtool_get_ts_info(struct net_device *dev, struct kernel_ethtool_ts_info *info);\nnet/ethtool/common.h-60-int ethtool_get_ts_info_by_phc(struct net_device *dev,\n--\nnet/ethtool/ioctl.c=2842=static int ethtool_get_ts_info(struct net_device *dev, void __user *useraddr)\n--\nnet/ethtool/ioctl.c-2847-\nnet/ethtool/ioctl.c:2848:\terr = __ethtool_get_ts_info(dev, \u0026kernel_info);\nnet/ethtool/ioctl.c-2849-\tif (err)\n--\nnet/ethtool/tsconfig.c=35=static int tsconfig_prepare_data(const struct ethnl_req_info *req_base,\n--\nnet/ethtool/tsconfig.c-68-\t\tts_info.phc_index = -1;\nnet/ethtool/tsconfig.c:69:\t\tret = __ethtool_get_ts_info(dev, \u0026ts_info);\nnet/ethtool/tsconfig.c-70-\t\tif (ret)\n--\nnet/ethtool/tsinfo.c=96=static int tsinfo_prepare_data(const struct ethnl_req_info *req_base,\n--\nnet/ethtool/tsinfo.c-122-\nnet/ethtool/tsinfo.c:123:\tret = __ethtool_get_ts_info(dev, \u0026data-\u003ets_info);\nnet/ethtool/tsinfo.c-124-\tethnl_ops_complete(dev);\n"
}

57/3 2026/08/13 22:56 llm kmsan-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 79521
							output: 38
							thoughts: 23
						

Thoughts:
Here's my summary, as though I'm processing those thoughts:

**Diving into the Ethtool Code**

Alright, let's get down to brass tacks. I'm thinking we need to take a look at the `net/ethtool/common.c` file. Specifically, I'm zeroing in on the code around line 1067. That area is likely to be critical for the task at hand. Hopefully, that will give me the insights I need. I'm expecting to find the relevant implementation details around whatever is in the scope of this work.



58/3 2026/08/13 22:56 tool read-file
0m Args:
{
  "File": "net/ethtool/common.c",
  "FirstLine": 1065,
  "LineCount": 40
}

Results:
{
  "Contents": "1065:\t}\n1066:\t\n1067:\tint __ethtool_get_ts_info(struct net_device *dev,\n1068:\t\t\t\t  struct kernel_ethtool_ts_info *info)\n1069:\t{\n1070:\t\tstruct hwtstamp_provider *hwprov;\n1071:\t\tint err = 0;\n1072:\t\n1073:\t\trcu_read_lock();\n1074:\t\thwprov = rcu_dereference(dev-\u003ehwprov);\n1075:\t\t/* No provider specified, use default behavior */\n1076:\t\tif (!hwprov) {\n1077:\t\t\tconst struct ethtool_ops *ops = dev-\u003eethtool_ops;\n1078:\t\t\tstruct phy_device *phydev = dev-\u003ephydev;\n1079:\t\n1080:\t\t\tethtool_init_tsinfo(info);\n1081:\t\t\tif (phy_is_default_hwtstamp(phydev) \u0026\u0026\n1082:\t\t\t    phy_has_tsinfo(phydev)) {\n1083:\t\t\t\terr = phy_ts_info(phydev, info);\n1084:\t\t\t\t/* Report the phc source only if we have a real\n1085:\t\t\t\t * phc source with an index.\n1086:\t\t\t\t */\n1087:\t\t\t\tif (!err \u0026\u0026 info-\u003ephc_index \u003e= 0) {\n1088:\t\t\t\t\tinfo-\u003ephc_source = HWTSTAMP_SOURCE_PHYLIB;\n1089:\t\t\t\t\tinfo-\u003ephc_phyindex = phydev-\u003ephyindex;\n1090:\t\t\t\t}\n1091:\t\t\t} else if (ops-\u003eget_ts_info) {\n1092:\t\t\t\terr = ops-\u003eget_ts_info(dev, info);\n1093:\t\t\t\tif (!err \u0026\u0026 info-\u003ephc_index \u003e= 0)\n1094:\t\t\t\t\tinfo-\u003ephc_source = HWTSTAMP_SOURCE_NETDEV;\n1095:\t\t\t}\n1096:\t\n1097:\t\t\tinfo-\u003eso_timestamping |= SOF_TIMESTAMPING_RX_SOFTWARE |\n1098:\t\t\t\t\t\t SOF_TIMESTAMPING_SOFTWARE;\n1099:\t\n1100:\t\t\trcu_read_unlock();\n1101:\t\t\treturn err;\n1102:\t\t}\n1103:\t\n1104:\t\terr = ethtool_get_ts_info_by_phc(dev, info, \u0026hwprov-\u003edesc);\n"
}

59/3 2026/08/13 22:56 llm kmsan-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 80362
							output: 22
							thoughts: 46
						

Thoughts:
Okay, here's my interpretation of that thought process, as if I'm the one having it, and assuming my expertise in this area:

**Initial Timestamping Inquiry**

Right, so I'm looking at this driver initialization sequence, and it looks like `ethtool_init_tsinfo(info)` is being called *before* the driver's own `ops->get_ts_info(dev, info)` function. That's a little unusual, I need to understand why. My immediate next step is to drill down into the implementation of `ethtool_init_tsinfo`. I want to see what it's doing and understand its purpose within this flow. What initializations or default settings is it applying before the driver has a chance to provide its own timestamping information? Are there potential conflicts or redundancies here? I'm betting that the goal here is to set up a base level structure or establish some safe defaults, but I need to confirm that and understand the interplay. Let's see what's going on in that function.



60/3 2026/08/13 22:56 tool grepper
0m Args:
{
  "Expression": "ethtool_init_tsinfo"
}

Results:
{
  "Output": "net/ethtool/common.c=943=void ethtool_ringparam_get_cfg(struct net_device *dev,\n--\nnet/ethtool/common.c-958-\nnet/ethtool/common.c:959:static void ethtool_init_tsinfo(struct kernel_ethtool_ts_info *info)\nnet/ethtool/common.c-960-{\n--\nnet/ethtool/common.c=966=int ethtool_net_get_ts_info_by_phc(struct net_device *dev,\n--\nnet/ethtool/common.c-976-\t/* Does ptp comes from netdev */\nnet/ethtool/common.c:977:\tethtool_init_tsinfo(info);\nnet/ethtool/common.c-978-\tinfo-\u003ephc_qualifier = hwprov_desc-\u003equalifier;\n--\nnet/ethtool/common.c=991=ethtool_phy_get_ts_info_by_phc(struct net_device *dev,\n--\nnet/ethtool/common.c-1009-\nnet/ethtool/common.c:1010:\t\t\tethtool_init_tsinfo(info);\nnet/ethtool/common.c-1011-\t\t\terr = phy_ts_info(pdn-\u003ephy, info);\n--\nnet/ethtool/common.c-1022-\tif (phy_has_tsinfo(dev-\u003ephydev)) {\nnet/ethtool/common.c:1023:\t\tethtool_init_tsinfo(info);\nnet/ethtool/common.c-1024-\t\terr = phy_ts_info(dev-\u003ephydev, info);\n--\nnet/ethtool/common.c=1067=int __ethtool_get_ts_info(struct net_device *dev,\n--\nnet/ethtool/common.c-1079-\nnet/ethtool/common.c:1080:\t\tethtool_init_tsinfo(info);\nnet/ethtool/common.c-1081-\t\tif (phy_is_default_hwtstamp(phydev) \u0026\u0026\n"
}

61/3 2026/08/13 22:56 llm kmsan-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 81227
							output: 37
							thoughts: 26
						

Thoughts:
Here's my summary, as though I'm reading and processing the provided code reference:

**Diving into `ethtool_init_tsinfo`**

Alright, let's get into this. The task is to understand what's happening with `ethtool_init_tsinfo`, specifically the implementation in `net/ethtool/common.c`. I know this is a core piece for handling timestamping configuration within the ethtool framework. I'm expecting this function is responsible for initializing or potentially resetting the timestamping information associated with a network interface. Probably setting default values, checking for capabilities, or prepping some internal data structures. Let's see how it's done. I'm anticipating that I can quickly understand the logical flow, and identify where to potentially focus if there's an issue with timestamping config.



62/3 2026/08/13 22:56 tool read-file
0m Args:
{
  "File": "net/ethtool/common.c",
  "FirstLine": 955,
  "LineCount": 15
}

Results:
{
  "Contents": " 955:\t\tkparam-\u003etcp_data_split = dev-\u003ecfg-\u003ehds_config;\n 956:\t\tkparam-\u003ehds_thresh = dev-\u003ecfg-\u003ehds_thresh;\n 957:\t}\n 958:\t\n 959:\tstatic void ethtool_init_tsinfo(struct kernel_ethtool_ts_info *info)\n 960:\t{\n 961:\t\tmemset(info, 0, sizeof(*info));\n 962:\t\tinfo-\u003ecmd = ETHTOOL_GET_TS_INFO;\n 963:\t\tinfo-\u003ephc_index = -1;\n 964:\t}\n 965:\t\n 966:\tint ethtool_net_get_ts_info_by_phc(struct net_device *dev,\n 967:\t\t\t\t\t   struct kernel_ethtool_ts_info *info,\n 968:\t\t\t\t\t   struct hwtstamp_provider_desc *hwprov_desc)\n 969:\t{\n"
}

63/3 2026/08/13 22:56 llm kmsan-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 81739
							output: 23
							thoughts: 300
						

Thoughts:
**Analyzing Time Stamping Initialization in the Network Simulator**

Okay, so I'm looking at this initialization sequence, and it seems pretty straightforward. The `ethtool_init_tsinfo` function is calling `memset(info, 0, sizeof(*info))`. That's good; it means the `info` struct is guaranteed to be zeroed out completely before the driver's `ops->get_ts_info` function is even called. No nasty surprises with uninitialized memory here. Specifically, in the `nsim_get_ts_info` function, it first calls `ethtool_op_get_ts_info`, which sets some basic timestamping parameters like `so_timestamping` and `phc_index`. After that initial call, the code in `nsim_get_ts_info` itself modifies those very same values, plus `tx_types`, and `rx_filters` within the `info` struct. Given the prior zero-initialization, I can't see any obvious issues with uninitialized reads. It's a clean slate, and all modifications should be well-defined.

Now, let's take a look at the timestamping configuration retrieval. I need to understand how the system gets configured. The `nsim_get_ts_config` function is important for that. I'm seeing that it simply copies `ns->tstamp_config` into the provided `config` structure. So, the simulator's timestamp configuration is essentially a stored struct. I know `struct kernel_hwtstamp_config` is defined in `include/linux/net_tstamp.h`. Let's just double-check that definition to be sure.



64/3 2026/08/13 22:56 tool grepper
0m Args:
{
  "Expression": "struct kernel_hwtstamp_config \\{"
}

Results:
{
  "Output": "include/linux/net_tstamp.h=37=struct hwtstamp_provider {\n--\ninclude/linux/net_tstamp.h-61- */\ninclude/linux/net_tstamp.h:62:struct kernel_hwtstamp_config {\ninclude/linux/net_tstamp.h-63-\tint flags;\n"
}

65/3 2026/08/13 22:56 llm kmsan-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 82518
							output: 37
							thoughts: 22
						

Thoughts:
Here's a summary of my thinking, presented as if it were my thought process:

**Diving into Network Timestamping**

Alright, I need to get a better handle on how network timestamping is handled within the Linux kernel. Let's start by looking at a key header file. My instinct tells me that `include/linux/net_tstamp.h` is the right place to begin, likely around line 62. I'm expecting this section to define some fundamental structures or constants related to timestamping. I'll be looking for things like:

*   **Core Data Structures:** Definitions of structures used to store and manipulate timestamps themselves, probably involving `struct timeval` or `struct timespec` in some fashion. I'm especially keen on how they handle hardware-specific features.
*   **Error Codes and Status Flags:** Any flags or error codes related to timestamping operations are also on my radar. These are crucial for understanding how the code handles different timestamping scenarios, and whether it's software-based, hardware-assisted or a complete failure.
*   **Configuration and Control:** I'll be searching for any parameters or macros that allow enabling or disabling timestamping features. I want to know how the system is configured to respond to different sources or types of timestamps.
*   **Function Prototypes:** What functions are available for configuring and accessing timestamping features? I expect to see function prototypes for reading, writing, and synchronizing timestamps.

I want to see how these elements relate to the underlying network stack. My experience has been that there's always a connection between the timestamping mechanisms and the network device driver. I'm anticipating that line 62 will provide context for what's going on.



66/3 2026/08/13 22:56 tool read-file
0m Args:
{
  "File": "include/linux/net_tstamp.h",
  "FirstLine": 55,
  "LineCount": 20
}

Results:
{
  "Contents": "  55:\t *\tan attached phylib PHY\n  56:\t * @qualifier: qualifier of the hwtstamp provider\n  57:\t *\n  58:\t * Prefer using this structure for in-kernel processing of hardware\n  59:\t * timestamping configuration, over the inextensible struct hwtstamp_config\n  60:\t * exposed to the %SIOCGHWTSTAMP and %SIOCSHWTSTAMP ioctl UAPI.\n  61:\t */\n  62:\tstruct kernel_hwtstamp_config {\n  63:\t\tint flags;\n  64:\t\tint tx_type;\n  65:\t\tint rx_filter;\n  66:\t\tstruct ifreq *ifr;\n  67:\t\tbool copied_to_user;\n  68:\t\tenum hwtstamp_source source;\n  69:\t\tenum hwtstamp_provider_qualifier qualifier;\n  70:\t};\n  71:\t\n  72:\tstatic inline void hwtstamp_config_to_kernel(struct kernel_hwtstamp_config *kernel_cfg,\n  73:\t\t\t\t\t\t     const struct hwtstamp_config *cfg)\n  74:\t{\n"
}

67/3 2026/08/13 22:56 llm kmsan-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 83240
							output: 20
							thoughts: 1538
						

Thoughts:
**Analyzing the hwtstamp configuration flow in the `nsim` driver**

Okay, let's break this down systematically. I see a structure, `kernel_hwtstamp_config`, containing various timestamping settings, including flags, types, and filters, alongside an `ifr` pointer and boolean `copied_to_user`, plus `source` and `qualifier` enums, all pretty standard.

My immediate thought is, how is this data handled across the `get` and `set` operations?

Looking at `nsim_get_ts_config`, it simply copies the contents of `ns->tstamp_config` to the provided `config` structure. Initially, `ns->tstamp_config` is zeroed during device initialization. The subsequent calls to `nsim_set_ts_config` only modify `tx_type` and `rx_filter`. This means `ifr`, `copied_to_user`, `source`, and `qualifier` are *always* zeroed out during the `get` operation.

Now, let's step through `dev_get_hwtstamp`. Here, `kernel_cfg.ifr` is initialized *before* calling the driver's `ndo_hwtstamp_get` function, which is, in this case, `nsim_get_ts_config`. Thus `nsim_get_ts_config` overwrites this value with the `NULL` `ns->tstamp_config.ifr`, overwrites `kernel_cfg.copied_to_user` and the other fields. Crucially, the code checks `!kernel_cfg.copied_to_user`, which will now always evaluate to `true` (because it's zero). This causes a different code path to be taken.

Then `hwtstamp_config_from_kernel` gets called, which copies the `flags`, `tx_type` and `rx_filter` from `kernel_cfg` (which will be the values in `ns->tstamp_config`), into a local `cfg` structure. Since only those fields are copied, `cfg` is *fully* initialized. The code then copies this `cfg` struct to user space, so there's no uninitialized memory leak here, as the locals are guaranteed to be populated.

However, a critical point emerges with respect to `nsim_set_ts_config`. It only updates `ns->tstamp_config.rx_filter` and `ns->tstamp_config.tx_type`, but *never* updates `ns->tstamp_config.flags`. So when `nsim_get_ts_config` is called, the value of flags in user space is *always* zero.

Is this a bug? Yes, it means that the `flags` field is effectively ignored during `set` and always returned as 0 during `get`.

Is it a memory leak? No, because while it doesn't honor the user setting of the flag, it isn't an uninitialized memory leak because zero is explicitly copied. This behavior is consistent, and always returns 0.

Wait, the next step is to consider how this is handled via netlink.
Now I have to check `ethnl_set_tsconfig` and `ethnl_get_tsconfig`. I can see there is an issue with configuration propagation.



68/3 2026/08/13 22:56 tool grepper
0m Args:
{
  "Expression": "ethnl_set_tsconfig"
}

Results:
{
  "Output": "net/ethtool/tsconfig.c=199=static int tsconfig_send_reply(struct net_device *dev, struct genl_info *info)\n--\nnet/ethtool/tsconfig.c-250-\nnet/ethtool/tsconfig.c:251:static int ethnl_set_tsconfig_validate(struct ethnl_req_info *req_base,\nnet/ethtool/tsconfig.c-252-\t\t\t\t       struct genl_info *info)\n--\nnet/ethtool/tsconfig.c=263=tsconfig_set_hwprov_from_desc(struct net_device *dev,\n--\nnet/ethtool/tsconfig.c-302-\nnet/ethtool/tsconfig.c:303:static int ethnl_set_tsconfig(struct ethnl_req_info *req_base,\nnet/ethtool/tsconfig.c-304-\t\t\t      struct genl_info *info)\n--\nnet/ethtool/tsconfig.c=447=const struct ethnl_request_ops ethnl_tsconfig_request_ops = {\n--\nnet/ethtool/tsconfig.c-457-\nnet/ethtool/tsconfig.c:458:\t.set_validate\t\t= ethnl_set_tsconfig_validate,\nnet/ethtool/tsconfig.c:459:\t.set\t\t\t= ethnl_set_tsconfig,\nnet/ethtool/tsconfig.c-460-};\n"
}

69/3 2026/08/13 22:56 llm kmsan-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 85881
							output: 36
							thoughts: 21
						

Thoughts:
Here's a summary of my thought process, as requested:

**Diving into `tsconfig.c`**

Okay, let's zero in on `net/ethtool/tsconfig.c`. I need to get a better handle on the way the ethtool interface deals with configuration and the TSC (Timestamp Counter) functionality. Based on my past experience with ethtool, I have a good feeling that the core logic is near line 35. I'm guessing that will be a good starting point to identify the relevant data structures or function calls related to TSC configurations. I'll read around that line and see where it takes me. Understanding the implementation details will allow me to assess the quality of the timestamp information.



70/3 2026/08/13 22:57 tool read-file
0m Args:
{
  "File": "net/ethtool/tsconfig.c",
  "FirstLine": 30,
  "LineCount": 40
}

Results:
{
  "Contents": "  30:\tconst struct nla_policy ethnl_tsconfig_get_policy[ETHTOOL_A_TSCONFIG_HEADER + 1] = {\n  31:\t\t[ETHTOOL_A_TSCONFIG_HEADER]\t\t=\n  32:\t\t\tNLA_POLICY_NESTED(ethnl_header_policy),\n  33:\t};\n  34:\t\n  35:\tstatic int tsconfig_prepare_data(const struct ethnl_req_info *req_base,\n  36:\t\t\t\t\t struct ethnl_reply_data *reply_base,\n  37:\t\t\t\t\t const struct genl_info *info)\n  38:\t{\n  39:\t\tstruct tsconfig_reply_data *data = TSCONFIG_REPDATA(reply_base);\n  40:\t\tstruct hwtstamp_provider *hwprov = NULL;\n  41:\t\tstruct net_device *dev = reply_base-\u003edev;\n  42:\t\tstruct kernel_hwtstamp_config cfg = {};\n  43:\t\tint ret;\n  44:\t\n  45:\t\tif (!dev-\u003enetdev_ops-\u003endo_hwtstamp_get)\n  46:\t\t\treturn -EOPNOTSUPP;\n  47:\t\n  48:\t\tret = ethnl_ops_begin(dev);\n  49:\t\tif (ret \u003c 0)\n  50:\t\t\treturn ret;\n  51:\t\n  52:\t\tret = dev_get_hwtstamp_phylib(dev, \u0026cfg);\n  53:\t\tif (ret)\n  54:\t\t\tgoto out;\n  55:\t\n  56:\t\tdata-\u003ehwtst_config.tx_type = BIT(cfg.tx_type);\n  57:\t\tdata-\u003ehwtst_config.rx_filter = BIT(cfg.rx_filter);\n  58:\t\tdata-\u003ehwtst_config.flags = cfg.flags;\n  59:\t\n  60:\t\tdata-\u003ehwprov_desc.index = -1;\n  61:\t\thwprov = netdev_ops_lock_dereference(dev-\u003ehwprov, dev);\n  62:\t\tif (hwprov) {\n  63:\t\t\tdata-\u003ehwprov_desc.index = hwprov-\u003edesc.index;\n  64:\t\t\tdata-\u003ehwprov_desc.qualifier = hwprov-\u003edesc.qualifier;\n  65:\t\t} else {\n  66:\t\t\tstruct kernel_ethtool_ts_info ts_info = {};\n  67:\t\n  68:\t\t\tts_info.phc_index = -1;\n  69:\t\t\tret = __ethtool_get_ts_info(dev, \u0026ts_info);\n"
}

71/3 2026/08/13 22:57 llm kmsan-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 86756
							output: 20
							thoughts: 1933
						

Thoughts:
**Uninitialized Memory and Timestamping in the nsim Driver**

Okay, let's break this down. In `tsconfig_prepare_data`, I initialize `cfg` to an empty struct. Then I call `dev_get_hwtstamp_phylib`, which eventually calls `ndo_hwtstamp_get` through the device's netdev ops. This, in turn, calls `nsim_get_ts_config`.  `nsim_get_ts_config` copies the timestamp configuration (`ns->tstamp_config`) into `*config` (which is `cfg`). Then, the `cfg` contents are bitwise shifted and copied into `data->hwtst_config`.  Since `ns->tstamp_config` is zero-initialized at the start and later updated, `cfg` is fully initialized at this point. I'm satisfied there's no uninitialized memory here.

I'm double-checking, is `nsim_get_ts_config` called anywhere else? Nope, just through the `ndo_hwtstamp_get` call. Good.

Now, revisiting `nsim_start_xmit`, there are timestamping concerns. If `ptp_info_tx` is true, the `tx_ts` is populated.  I remember that `mock_phc_gettime64` populates `tx_ts`.  That uses `ns_to_timespec64`, which returns a `struct timespec64`.  `struct timespec64` contains `tv_sec` and `tv_nsec`. On 64-bit systems, `timespec64` is 16 bytes. However, on 32-bit systems there is padding due to the alignment of `s64` which makes this 12 bytes long.

Then `timespec64_to_ktime` is called. It only reads the `tv_sec` and `tv_nsec` members of the struct. It doesn't use the padding, so no issues there. That function returns a `ktime_t`. Then, this ktime is copied to `shhwtstamps.hwtstamp`, which is another `ktime_t` (8 bytes). Finally, that's copied into the shared timestamp of the skb. Since I know everything in `hwtstamps` is initialized (it's just an 8-byte `ktime_t`), there's no risk of reading uninitialized memory.

The same applies to the receiving side where the `ktime_t` is copied to the `skb->hwtstamp`.

Now let's verify `mock_phc_get_ptp_info` returns the address of `phc->info`. Wait, if `phc` is NULL here, I'm going to dereference a NULL pointer! No, if `phc` is NULL, then `&phc->info` is `offsetof(struct mock_phc, info)`. So, that's not a dereference, just an offset from a NULL pointer, which is still safe.



72/3 2026/08/13 22:57 tool grepper
0m Args:
{
  "Expression": "struct mock_phc \\{"
}

Results:
{
  "Output": "drivers/ptp/ptp_mock.c-35-\ndrivers/ptp/ptp_mock.c:36:struct mock_phc {\ndrivers/ptp/ptp_mock.c-37-\tstruct ptp_clock_info info;\n"
}

73/3 2026/08/13 22:57 llm kmsan-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 89456
							output: 38
							thoughts: 23
						

Thoughts:
Here's my summary, as if I were thinking these thoughts:

**Analyzing the PTP Mock Driver**

Okay, let's dive into this `drivers/ptp/ptp_mock.c` file. I'm specifically targeting around line 36. My gut feeling is that something interesting, likely foundational, is defined there. This mock driver, if I recall correctly, is probably a crucial piece for testing and simulation in the PTP subsystem. I'm guessing that line 36 probably deals with either initialization, a core data structure, or a fundamental function related to timing emulation within this mock environment. Time to dig in and confirm (or disprove) my initial assumptions. Let's see what the code reveals. I need to understand how the mock interacts with the broader PTP framework.



74/3 2026/08/13 22:57 tool read-file
0m Args:
{
  "File": "drivers/ptp/ptp_mock.c",
  "FirstLine": 30,
  "LineCount": 20
}

Results:
{
  "Contents": "  30:\t * we permit, is ~8.3 seconds. Make sure readouts are more frequent than that.\n  31:\t */\n  32:\t#define MOCK_PHC_REFRESH_INTERVAL\t(HZ * 5)\n  33:\t\n  34:\t#define info_to_phc(d) container_of((d), struct mock_phc, info)\n  35:\t\n  36:\tstruct mock_phc {\n  37:\t\tstruct ptp_clock_info info;\n  38:\t\tstruct ptp_clock *clock;\n  39:\t\tstruct timecounter tc;\n  40:\t\tstruct cyclecounter cc;\n  41:\t\tspinlock_t lock;\n  42:\t};\n  43:\t\n  44:\tstatic u64 mock_phc_cc_read(struct cyclecounter *cc)\n  45:\t{\n  46:\t\treturn ktime_get_raw_ns();\n  47:\t}\n  48:\t\n  49:\tstatic int mock_phc_adjfine(struct ptp_clock_info *info, long scaled_ppm)\n"
}

75/3 2026/08/13 22:57 llm kmsan-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 89980
							output: 19
							thoughts: 211
						

Thoughts:
**Analyzing Potential Null Pointer Dereference in PTP Timestamping**

Okay, so I'm digging into this code and a potential null pointer dereference is nagging at me. It looks like if `phc` is `NULL`, then `&phc->info` is effectively `0`, which would make `ptp_info_rx` null. That's a classic trap. But then I'm thinking, is the state guaranteed to be non-NULL when timestamps are expected? Specifically, is `peer_ns->phc` *always* non-NULL if `peer_ns->tstamp_config.rx_filter` isn't `HWTSTAMP_FILTER_NONE`?

I just saw the `nsim_set_ts_config` function, where it has this check:

```c
	if (!ns->phc)
		return -EOPNOTSUPP;
```

This *strongly* suggests that `rx_filter` can *only* be set to something other than `NONE` if `ns->phc` is actually valid. So, at first glance, that might seem solid. 

But hold on, there's a loophole. What if `ns->phc` is destroyed *after* `rx_filter` has been set to something non-NONE? That would be a race condition, and that's precisely what I'm concerned about. Where is `ns->phc` actually created and destroyed? I need to track down the lifecycle of `ns->phc`. I need to figure out where it's created, destroyed, and by whom. Let's see... it's probably done in `nsim_create` or something like that... I need to double-check those functions and any others that deal with `ns->phc` to ensure this isn't a ticking time bomb.



76/3 2026/08/13 22:57 tool grepper
0m Args:
{
  "Expression": "ns-\u003ephc ="
}

Results:
{
  "Output": "drivers/net/netdevsim/netdev.c=1145=static int nsim_init_netdevsim(struct netdevsim *ns)\n--\ndrivers/net/netdevsim/netdev.c-1154-\ndrivers/net/netdevsim/netdev.c:1155:\tns-\u003ephc = phc;\ndrivers/net/netdevsim/netdev.c-1156-\tns-\u003enetdev-\u003enetdev_ops = \u0026nsim_netdev_ops;\n"
}

77/3 2026/08/13 22:57 llm kmsan-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 90745
							output: 41
							thoughts: 29
						

Thoughts:
Okay, here's my interpretation of that thought process, as if it were my own:

**Diving into the netdevsim Init Function**

Alright, time to dig into the guts of the `netdevsim` driver. I need to understand how these simulated network devices are initialized. The best place to start, as always, is the initialization function. So, I'm pulling up `nsim_init_netdevsim` in `drivers/net/netdevsim/netdev.c`. This is where the magic (or at least, the foundational setup) begins. I expect to find the core registration and resource allocation happening here – the creation of the net device structure, allocation of memory, setting up the necessary callbacks, and probably some initial configuration based on the platform. Let's see what they've done with it. I'm keen to see if they're handling things like interrupt registration (even if simulated), how they’re managing the device's lifecycle within the kernel's networking stack, and how they hook into the general device model. I'm really looking for how they achieve the "simulated" aspect of it; there must be some sort of virtual hardware implementation in here that I'm interested in.



78/3 2026/08/13 22:57 tool read-file
0m Args:
{
  "File": "drivers/net/netdevsim/netdev.c",
  "FirstLine": 1140,
  "LineCount": 30
}

Results:
{
  "Contents": "1140:\t\n1141:\t\tkfree(ns-\u003erq);\n1142:\t\tns-\u003erq = NULL;\n1143:\t}\n1144:\t\n1145:\tstatic int nsim_init_netdevsim(struct netdevsim *ns)\n1146:\t{\n1147:\t\tstruct netdevsim *peer;\n1148:\t\tstruct mock_phc *phc;\n1149:\t\tint err;\n1150:\t\n1151:\t\tphc = mock_phc_create(\u0026ns-\u003ensim_bus_dev-\u003edev);\n1152:\t\tif (IS_ERR(phc))\n1153:\t\t\treturn PTR_ERR(phc);\n1154:\t\n1155:\t\tns-\u003ephc = phc;\n1156:\t\tns-\u003enetdev-\u003enetdev_ops = \u0026nsim_netdev_ops;\n1157:\t\tns-\u003enetdev-\u003estat_ops = \u0026nsim_stat_ops;\n1158:\t\tns-\u003enetdev-\u003equeue_mgmt_ops = \u0026nsim_queue_mgmt_ops;\n1159:\t\tnetdev_lockdep_set_classes(ns-\u003enetdev);\n1160:\t\n1161:\t\terr = nsim_udp_tunnels_info_create(ns-\u003ensim_dev, ns-\u003enetdev);\n1162:\t\tif (err)\n1163:\t\t\tgoto err_phc_destroy;\n1164:\t\n1165:\t\trtnl_lock();\n1166:\t\terr = nsim_queue_init(ns);\n1167:\t\tif (err)\n1168:\t\t\tgoto err_utn_destroy;\n1169:\t\n"
}

79/3 2026/08/13 22:57 llm kmsan-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 91535
							output: 37
							thoughts: 1043
						

Thoughts:
**Analyzing Potential Uninitialized Memory Leaks in the Netdevsim Driver**

Okay, let's break this down systematically. I need to make sure there aren't any sneaky uninitialized memory leaks in this `netdevsim` driver. My initial thought is that the lifetime of `ns->phc` is tied to the `netdevsim` device itself, so anything using it should be valid for that duration.

First, I looked at `nsim_start_xmit`. The code initializes `shhwtstamps` to zero, which is good. Then, `tx_ts` gets populated by `ptp_info_tx->gettime64`, and the relevant values are extracted and copied into the `skb`. Since `shhwtstamps` is explicitly initialized, and the source values for `tx_ts` come from a known good, initialized location, there's no leak here. The copy to `skb_shinfo(skb)->hwtstamps` also appears safe.

Next, I turned my attention to `nsim_get_ts_info`. It looks like `ethtool_init_tsinfo` zero-initializes the `info` structure before `nsim_get_ts_info` gets called. `ethtool_op_get_ts_info` sets some values, and then the function itself modifies several fields. Zero-initialization at the start removes concerns about uninitialized memory. `phc_index`, `so_timestamping`, `tx_types`, and `rx_filters` are all explicitly set. So no problems here.

I then considered `mock_phc_adjfine`, `mock_phc_adjtime`, `mock_phc_settime64`, and `mock_phc_gettime64`. The only change seems to be around `spin_lock` and `spin_lock_irqsave`, unrelated to memory initialization. No issues here.

I need to be more thorough and consider if any other structures are being copied to user space. The key area is `nsim_get_ts_config`. This function copies `ns->tstamp_config` to `*config`. Crucially, `config` is `kernel_cfg` within `dev_get_hwtstamp`. Good, `kernel_cfg` is initialized to `{}`. `nsim_get_ts_config` overwrites it with `ns->tstamp_config`. Since `ns->tstamp_config` is zero-initialized and gets updated, the issue of using uninitialized memory is solved. `dev_get_hwtstamp` then calls `hwtstamp_config_from_kernel` to fill the full `cfg` structure. The `cfg` is initialized to be safely copied to user space using `copy_to_user`. So, no leak is detected.

Now, a bit of extra caution. What if `nsim_get_ts_config` is called from `ethnl_set_tsconfig`?
The call to `dev_get_hwtstamp_phylib` uses `hwtst_config`, which is initialized to `{}` in `ethnl_set_tsconfig`. That's good.

So, it seems that there's a strong pattern of zero-initialization or safe initialization before any potentially problematic copy to user space. After a thorough review, I'm confident there are no uninitialized memory leaks.



80/3 2026/08/13 22:57 tool read-file
0m Args:
{
  "File": "net/ethtool/tsconfig.c",
  "FirstLine": 300,
  "LineCount": 50
}

Results:
{
  "Contents": " 300:\t\treturn hwprov;\n 301:\t}\n 302:\t\n 303:\tstatic int ethnl_set_tsconfig(struct ethnl_req_info *req_base,\n 304:\t\t\t\t      struct genl_info *info)\n 305:\t{\n 306:\t\tstruct kernel_hwtstamp_config hwtst_config = {0};\n 307:\t\tbool hwprov_mod = false, config_mod = false;\n 308:\t\tstruct hwtstamp_provider *hwprov = NULL;\n 309:\t\tstruct net_device *dev = req_base-\u003edev;\n 310:\t\tstruct nlattr **tb = info-\u003eattrs;\n 311:\t\tint ret;\n 312:\t\n 313:\t\tif (!netif_device_present(dev))\n 314:\t\t\treturn -ENODEV;\n 315:\t\n 316:\t\tif (tb[ETHTOOL_A_TSCONFIG_HWTSTAMP_PROVIDER]) {\n 317:\t\t\tstruct hwtstamp_provider_desc __hwprov_desc = {.index = -1};\n 318:\t\t\tstruct hwtstamp_provider *__hwprov;\n 319:\t\n 320:\t\t\t__hwprov = netdev_ops_lock_dereference(dev-\u003ehwprov, dev);\n 321:\t\t\tif (__hwprov) {\n 322:\t\t\t\t__hwprov_desc.index = __hwprov-\u003edesc.index;\n 323:\t\t\t\t__hwprov_desc.qualifier = __hwprov-\u003edesc.qualifier;\n 324:\t\t\t}\n 325:\t\n 326:\t\t\tret = ts_parse_hwtst_provider(tb[ETHTOOL_A_TSCONFIG_HWTSTAMP_PROVIDER],\n 327:\t\t\t\t\t\t      \u0026__hwprov_desc, info-\u003eextack,\n 328:\t\t\t\t\t\t      \u0026hwprov_mod);\n 329:\t\t\tif (ret \u003c 0)\n 330:\t\t\t\treturn ret;\n 331:\t\n 332:\t\t\tif (hwprov_mod) {\n 333:\t\t\t\thwprov = tsconfig_set_hwprov_from_desc(dev, info,\n 334:\t\t\t\t\t\t\t\t       \u0026__hwprov_desc);\n 335:\t\t\t\tif (IS_ERR(hwprov))\n 336:\t\t\t\t\treturn PTR_ERR(hwprov);\n 337:\t\t\t}\n 338:\t\t}\n 339:\t\n 340:\t\t/* Get current hwtstamp config if we are not changing the\n 341:\t\t * hwtstamp source. It will be zeroed in the other case.\n 342:\t\t */\n 343:\t\tif (!hwprov_mod) {\n 344:\t\t\tret = dev_get_hwtstamp_phylib(dev, \u0026hwtst_config);\n 345:\t\t\tif (ret \u003c 0 \u0026\u0026 ret != -EOPNOTSUPP)\n 346:\t\t\t\tgoto err_free_hwprov;\n 347:\t\t}\n 348:\t\n 349:\t\t/* Get the hwtstamp config from netlink */\n"
}

81/3 2026/08/13 22:57 llm kmsan-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 94160
							output: 20
							thoughts: 831
						

Thoughts:
**Uninitialized Memory Analysis in Network Timestamping Code**

Okay, let's break this down systematically. I'm looking at potential uninitialized memory reads in this timestamping code. First, `hwtst_config` is initialized to `{0}`. Then the `dev_get_hwtstamp_phylib` function is called. The `nsim_get_ts_config` function copies `ns->tstamp_config` to `hwtst_config`. Since `ns->tstamp_config` is zero-initialized and then later populated, I can confidently say `hwtst_config` doesn't have any uninitialized memory. That's good.

Wait a second, is there *anywhere* else that `ns->tstamp_config` is read? Let me check `nsim_start_xmit`. Yep, there it is!

```c
	if (unlikely(READ_ONCE(peer_ns->tstamp_config.rx_filter) !=
		     HWTSTAMP_FILTER_NONE))
		ptp_info_rx = mock_phc_get_ptp_info(peer_ns->phc);

	if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) &&
	    READ_ONCE(ns->tstamp_config.tx_type) == HWTSTAMP_TX_ON)
		ptp_info_tx = mock_phc_get_ptp_info(ns->phc);
```

Okay, it reads `rx_filter` and `tx_type`. But, since `ns->tstamp_config` itself is zero-initialized, and later updated, there are no uninitialized reads here.

Now, what about the `skb_shared_hwtstamps` struct? I see `struct skb_shared_hwtstamps shhwtstamps = {};`. That's zero-initialized. So, no problems there.

Next, I need to check `tx_ts` and `rx_ts`. They're only read if `ptp_info_tx` or `ptp_info_rx` is true, and in that case, they are populated by `gettime64`. The `mock_phc_gettime64` function populates them using `ns_to_timespec64(ns)`. `ns_to_timespec64` returns a fully initialized `struct timespec64`. Then `timespec64_to_ktime` reads `tv_sec` and `tv_nsec`. That's safe.

Let's look at `struct kernel_hwtstamp_config tstamp_config;` in `struct netdevsim`. The `netdevsim` structure is allocated with `alloc_netdev`. I know that `alloc_netdev` will use `kvzalloc` or `kzalloc` for the private data. Let me quickly verify if `alloc_netdev` zero-initializes this. Yes, `alloc_netdev` calls `alloc_netdev_mqs`, which uses `kvzalloc` for the net_device and its private data. So, `ns->tstamp_config` *is* fully zeroed initially. That's crucial.

Then I see `struct kernel_ethtool_ts_info`, let's verify if there is uninitialized memory there. It's fully zeroed by `ethtool_init_tsinfo` before `ops->get_ts_info` is called.

Okay, `struct hwtstamp_config`... it's fully initialized by `hwtstamp_config_from_kernel` before `copy_to_user`.

And `struct skb_shared_hwtstamps`? Zeroed by `= {}` and then `hwtstamp` is assigned. Safe.

Finally, `struct timespec64` is fully initialized by `ns_to_timespec64`. So that's safe.

And lastly `struct ptp_clock_info` is initialized in `mock_phc_create`. Ok, let me double check `mock_phc_create` real quick... *[checks mock_phc_create]*... yep, that's initialized.

Alright, after this thorough review, I can confidently say that there aren't any obvious cases of uninitialized memory reads in this timestamping code. All the critical structures are either zero-initialized or fully populated before being read. That's a clean bill of health!



82/3 2026/08/13 22:58 tool grepper
0m Args:
{
  "Expression": "mock_phc_create"
}

Results:
{
  "Output": "drivers/net/netdevsim/netdev.c=1145=static int nsim_init_netdevsim(struct netdevsim *ns)\n--\ndrivers/net/netdevsim/netdev.c-1150-\ndrivers/net/netdevsim/netdev.c:1151:\tphc = mock_phc_create(\u0026ns-\u003ensim_bus_dev-\u003edev);\ndrivers/net/netdevsim/netdev.c-1152-\tif (IS_ERR(phc))\n--\ndrivers/ptp/ptp_mock.c=120=EXPORT_SYMBOL_GPL(mock_phc_index);\ndrivers/ptp/ptp_mock.c-121-\ndrivers/ptp/ptp_mock.c:122:struct mock_phc *mock_phc_create(struct device *dev)\ndrivers/ptp/ptp_mock.c-123-{\n--\ndrivers/ptp/ptp_mock.c-168-}\ndrivers/ptp/ptp_mock.c:169:EXPORT_SYMBOL_GPL(mock_phc_create);\ndrivers/ptp/ptp_mock.c-170-\n--\ninclude/linux/ptp_mock.h=12=struct mock_phc;\n--\ninclude/linux/ptp_mock.h-15-\ninclude/linux/ptp_mock.h:16:struct mock_phc *mock_phc_create(struct device *dev);\ninclude/linux/ptp_mock.h-17-void mock_phc_destroy(struct mock_phc *phc);\n--\ninclude/linux/ptp_mock.h=19=struct ptp_clock_info *mock_phc_get_ptp_info(struct mock_phc *phc);\n--\ninclude/linux/ptp_mock.h-22-\ninclude/linux/ptp_mock.h:23:static inline struct mock_phc *mock_phc_create(struct device *dev)\ninclude/linux/ptp_mock.h-24-{\n"
}

83/3 2026/08/13 22:58 llm kmsan-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 96535
							output: 39
							thoughts: 26
						

Thoughts:
Here's my summary, as though I'm reading and thinking about the code:

**Diving into `mock_phc_create`**

Okay, let's pull up the `mock_phc_create` function, specifically in `drivers/ptp/ptp_mock.c`. I'm assuming this is part of a PTP (Precision Time Protocol) driver implementation, and it looks like a mock or simulation. I'm interested in how they're handling the creation of the simulated PHC (presumably a Precision Hardware Clock) here. I want to see how this particular mock is structured. I'm keen on checking if this mock is a good representation of a real hardware clock, especially the timing aspects. I want to figure out if it's got any interesting features.



84/3 2026/08/13 22:58 tool read-file
0m Args:
{
  "File": "drivers/ptp/ptp_mock.c",
  "FirstLine": 120,
  "LineCount": 40
}

Results:
{
  "Contents": " 120:\tEXPORT_SYMBOL_GPL(mock_phc_index);\n 121:\t\n 122:\tstruct mock_phc *mock_phc_create(struct device *dev)\n 123:\t{\n 124:\t\tstruct mock_phc *phc;\n 125:\t\tint err;\n 126:\t\n 127:\t\tphc = kzalloc_obj(*phc);\n 128:\t\tif (!phc) {\n 129:\t\t\terr = -ENOMEM;\n 130:\t\t\tgoto out;\n 131:\t\t}\n 132:\t\n 133:\t\tphc-\u003einfo = (struct ptp_clock_info) {\n 134:\t\t\t.owner\t\t= THIS_MODULE,\n 135:\t\t\t.name\t\t= \"Mock-up PTP clock\",\n 136:\t\t\t.max_adj\t= MOCK_PHC_MAX_ADJ_PPB,\n 137:\t\t\t.adjfine\t= mock_phc_adjfine,\n 138:\t\t\t.adjtime\t= mock_phc_adjtime,\n 139:\t\t\t.gettime64\t= mock_phc_gettime64,\n 140:\t\t\t.settime64\t= mock_phc_settime64,\n 141:\t\t\t.do_aux_work\t= mock_phc_refresh,\n 142:\t\t};\n 143:\t\n 144:\t\tphc-\u003ecc = (struct cyclecounter) {\n 145:\t\t\t.read\t= mock_phc_cc_read,\n 146:\t\t\t.mask\t= CYCLECOUNTER_MASK(64),\n 147:\t\t\t.mult\t= MOCK_PHC_CC_MULT,\n 148:\t\t\t.shift\t= MOCK_PHC_CC_SHIFT,\n 149:\t\t};\n 150:\t\n 151:\t\tspin_lock_init(\u0026phc-\u003elock);\n 152:\t\ttimecounter_init(\u0026phc-\u003etc, \u0026phc-\u003ecc, 0);\n 153:\t\n 154:\t\tphc-\u003eclock = ptp_clock_register(\u0026phc-\u003einfo, dev);\n 155:\t\tif (IS_ERR(phc-\u003eclock)) {\n 156:\t\t\terr = PTR_ERR(phc-\u003eclock);\n 157:\t\t\tgoto out_free_phc;\n 158:\t\t}\n 159:\t\n"
}

85/3 2026/08/13 22:58 llm kmsan-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 97413
							output: 478
							thoughts: 3409
						

Thoughts:
**Hardware Timestamping Implementation in `netdevsim`**

Okay, let's break down this patch. My main concern is always memory safety, so that's where I'll start.

First, the core of the change is enabling hardware timestamping in the `netdevsim` driver. They're using a `mock_phc` (Precision Time Protocol Clock) as the underlying PTP clock. The `mock_phc` is allocated using `kzalloc_obj`, which is nice because it guarantees zero-initialization. This is crucial: the macro `kzalloc_obj` uses `kzalloc`, and that means everything within the allocated `mock_phc` struct, including the `info` and `cc` members, is set to zero. Excellent! Then, we have `spin_lock_init` and `timecounter_init` being called which also initialize the lock and time counter. Also important is `ptp_clock_register`. No obvious uninitialized memory problems there.

Now, let's look at the changes in `drivers/net/netdevsim/ethtool.c`. This part adds `nsim_get_ts_info`, which fetches timestamping information. The relevant structures (`info`) passed to `ethtool_op_get_ts_info` are *already* initialized before this call, and within the function, no uninitialized values are used to populate the struct. The important thing is that `phc_index` is -1 if no PHC is available and 0 otherwise. The flags and types are set as appropriate.

Moving on to `drivers/net/netdevsim/netdev.c`, this is where the interesting stuff happens in `nsim_start_xmit`. This function now handles the actual timestamping. Critical point: local variables `tx_ts`, `rx_ts` are fully assigned inside `ptp_info_tx->gettime64` and `ptp_info_rx->gettime64`, so there's no chance of using uninitialized memory. `skb_shared_hwtstamps` is initialized as `{}` which guarantees zero-initialization for that structure. It appears there is no uninitialized memory leak.

Furthermore, regarding the `mock_phc` changes, the spinlocks inside the mock PTP clock are now using `spin_lock_irqsave` instead of `spin_lock`. This is important because it allows the timestamping code to sample the PTP clock while in an interrupt context (or with interrupts disabled), which is necessary for accurate hardware timestamping. This change ensures that timestamp reads are atomic and consistent, even in interrupt handlers. The critical concern here is that we use `spin_lock_irqsave` *everywhere* in the `mock_phc` code.

Finally, looking at the addition of `nsim_set_ts_config` and `nsim_get_ts_config`, they're responsible for configuring the timestamping feature. These functions make use of a `tstamp_config` which is handled correctly.

The patch also has changes in `drivers/ptp/ptp_mock.c` which use the updated spinlock calls.

Overall, the data structures used (including those passed to userspace via ethtool commands) and those added to the `skb` appear to be properly initialized. There are no obvious uninitialized memory risks. Standard KASAN and other memory error detectors should be sufficient to catch any subtle issues like out-of-bounds accesses or use-after-free conditions. The locking changes look correct, mitigating potential data races.



86/3 2026/08/13 22:58 tool set-results
0m Args:
{
  "KMSANReasoning": "The patch adds hardware timestamping support to the `netdevsim` driver. It introduces `nsim_get_ts_info`, `nsim_set_ts_config`, and `nsim_get_ts_config` to configure timestamping, and modifies `nsim_start_xmit` to sample the mock PTP clock and attach timestamps to the skb.\n\nAnalysis of potential uninitialized memory risks:\n1. `nsim_get_ts_info` populates a `struct kernel_ethtool_ts_info`. This structure is fully zeroed by `ethtool_init_tsinfo` in the ethtool core before `ops-\u003eget_ts_info` is called. The driver only modifies specific fields, leaving no uninitialized memory.\n2. `nsim_get_ts_config` copies `ns-\u003etstamp_config` to a `struct kernel_hwtstamp_config`. `ns-\u003etstamp_config` is zero-initialized when the `netdevsim` private data is allocated via `alloc_netdev` (which uses `kvzalloc`). The core ioctl handler (`dev_get_hwtstamp`) then copies the relevant fields to a `struct hwtstamp_config` (which has no padding) before copying it to user space. No uninitialized memory is leaked.\n3. In `nsim_start_xmit`, `tx_ts` and `rx_ts` are populated by `mock_phc_gettime64`, which uses `ns_to_timespec64` to return a fully initialized `struct timespec64`.\n4. The `struct skb_shared_hwtstamps` attached to the skb is zero-initialized (`= {}`) before the `hwtstamp` field is assigned, preventing any uninitialized memory from being attached to the packet.\n\nSince all structures sent to user space or attached to packets are fully initialized, this patch does not introduce any uninitialized memory risks or info-leaks. Standard KASAN and LOCKDEP are sufficient to detect any potential memory corruption or locking issues.",
  "NeedsKMSAN": false
}

Results:
{
  "KMSANReasoning": "The patch adds hardware timestamping support to the `netdevsim` driver. It introduces `nsim_get_ts_info`, `nsim_set_ts_config`, and `nsim_get_ts_config` to configure timestamping, and modifies `nsim_start_xmit` to sample the mock PTP clock and attach timestamps to the skb.\n\nAnalysis of potential uninitialized memory risks:\n1. `nsim_get_ts_info` populates a `struct kernel_ethtool_ts_info`. This structure is fully zeroed by `ethtool_init_tsinfo` in the ethtool core before `ops-\u003eget_ts_info` is called. The driver only modifies specific fields, leaving no uninitialized memory.\n2. `nsim_get_ts_config` copies `ns-\u003etstamp_config` to a `struct kernel_hwtstamp_config`. `ns-\u003etstamp_config` is zero-initialized when the `netdevsim` private data is allocated via `alloc_netdev` (which uses `kvzalloc`). The core ioctl handler (`dev_get_hwtstamp`) then copies the relevant fields to a `struct hwtstamp_config` (which has no padding) before copying it to user space. No uninitialized memory is leaked.\n3. In `nsim_start_xmit`, `tx_ts` and `rx_ts` are populated by `mock_phc_gettime64`, which uses `ns_to_timespec64` to return a fully initialized `struct timespec64`.\n4. The `struct skb_shared_hwtstamps` attached to the skb is zero-initialized (`= {}`) before the `hwtstamp` field is assigned, preventing any uninitialized memory from being attached to the packet.\n\nSince all structures sent to user space or attached to packets are fully initialized, this patch does not introduce any uninitialized memory risks or info-leaks. Standard KASAN and LOCKDEP are sufficient to detect any potential memory corruption or locking issues.",
  "NeedsKMSAN": false
}

LLM Calls Summary:
Total Calls Total Tokens Avg Tokens Total Duration (Seconds) Avg Duration (Seconds)
Tool Calls Summary:
Total Calls Total Duration (Seconds) Avg Duration (Seconds)