Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

can: kvaser_pciefd: advertise timestamping capabilities and add ioctl support

Currently, userland has no method to query which timestamping features
are supported by the kvaser_pciefd driver (aside maybe of getting RX
messages and observe whether or not hardware timestamps stay at zero).

The canonical way for a network driver to advertise what kind of
timestamping it supports is to implement
ethtool_ops::get_ts_info(). Here, we use the CAN specific
can_ethtool_op_get_ts_info_hwts() function to achieve this.

In addition, the driver currently does not support the hardware
timestamps ioctls. According to [1], SIOCSHWTSTAMP is "must" and
SIOCGHWTSTAMP is "should". This patch fills up that gap by
implementing net_device_ops::ndo_eth_ioctl() using the CAN specific
function can_eth_ioctl_hwts().

[1] kernel doc Timestamping, section 3.1: "Hardware Timestamping
Implementation: Device Drivers"
Link: https://docs.kernel.org/networking/timestamping.html#hardware-timestamping-implementation-device-drivers

CC: Jimmy Assarsson <extja@kvaser.com>
Signed-off-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
Link: https://lore.kernel.org/all/20220727101641.198847-12-mailhol.vincent@wanadoo.fr
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>

authored by

Vincent Mailhol and committed by
Marc Kleine-Budde
fa5cc7e1 1d46efa0

+7
+7
drivers/net/can/kvaser_pciefd.c
··· 9 9 #include <linux/kernel.h> 10 10 #include <linux/module.h> 11 11 #include <linux/device.h> 12 + #include <linux/ethtool.h> 12 13 #include <linux/pci.h> 13 14 #include <linux/can/dev.h> 14 15 #include <linux/timer.h> ··· 920 919 static const struct net_device_ops kvaser_pciefd_netdev_ops = { 921 920 .ndo_open = kvaser_pciefd_open, 922 921 .ndo_stop = kvaser_pciefd_stop, 922 + .ndo_eth_ioctl = can_eth_ioctl_hwts, 923 923 .ndo_start_xmit = kvaser_pciefd_start_xmit, 924 924 .ndo_change_mtu = can_change_mtu, 925 + }; 926 + 927 + static const struct ethtool_ops kvaser_pciefd_ethtool_ops = { 928 + .get_ts_info = can_ethtool_op_get_ts_info_hwts, 925 929 }; 926 930 927 931 static int kvaser_pciefd_setup_can_ctrls(struct kvaser_pciefd *pcie) ··· 945 939 946 940 can = netdev_priv(netdev); 947 941 netdev->netdev_ops = &kvaser_pciefd_netdev_ops; 942 + netdev->ethtool_ops = &kvaser_pciefd_ethtool_ops; 948 943 can->reg_base = pcie->reg_base + KVASER_PCIEFD_KCAN0_BASE + 949 944 i * KVASER_PCIEFD_KCAN_BASE_OFFSET; 950 945