Skip to content

Commit

Permalink
can: kvaser_usb: advertise timestamping capabilities and add ioctl su…
Browse files Browse the repository at this point in the history
…pport

Currently, userland has no method to query which timestamping features
are supported by the kvaser_usb 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-13-mailhol.vincent@wanadoo.fr
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
  • Loading branch information
Vincent Mailhol authored and Marc Kleine-Budde committed Jul 28, 2022
1 parent fa5cc7e commit 1d5eeda
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 2 deletions.
1 change: 1 addition & 0 deletions drivers/net/can/usb/kvaser_usb/kvaser_usb.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
#define KVASER_USB_QUIRK_HAS_SILENT_MODE BIT(0)
#define KVASER_USB_QUIRK_HAS_TXRX_ERRORS BIT(1)
#define KVASER_USB_QUIRK_IGNORE_CLK_FREQ BIT(2)
#define KVASER_USB_QUIRK_HAS_HARDWARE_TIMESTAMP BIT(3)

/* Device capabilities */
#define KVASER_USB_CAP_BERR_CAP 0x01
Expand Down
27 changes: 25 additions & 2 deletions drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

#include <linux/completion.h>
#include <linux/device.h>
#include <linux/ethtool.h>
#include <linux/gfp.h>
#include <linux/if.h>
#include <linux/kernel.h>
Expand Down Expand Up @@ -89,7 +90,7 @@
#define USB_HYBRID_PRO_CANLIN_PRODUCT_ID 278

static const struct kvaser_usb_driver_info kvaser_usb_driver_info_hydra = {
.quirks = 0,
.quirks = KVASER_USB_QUIRK_HAS_HARDWARE_TIMESTAMP,
.ops = &kvaser_usb_hydra_dev_ops,
};

Expand Down Expand Up @@ -665,6 +666,22 @@ static const struct net_device_ops kvaser_usb_netdev_ops = {
.ndo_change_mtu = can_change_mtu,
};

static const struct net_device_ops kvaser_usb_netdev_ops_hwts = {
.ndo_open = kvaser_usb_open,
.ndo_stop = kvaser_usb_close,
.ndo_eth_ioctl = can_eth_ioctl_hwts,
.ndo_start_xmit = kvaser_usb_start_xmit,
.ndo_change_mtu = can_change_mtu,
};

static const struct ethtool_ops kvaser_usb_ethtool_ops = {
.get_ts_info = ethtool_op_get_ts_info,
};

static const struct ethtool_ops kvaser_usb_ethtool_ops_hwts = {
.get_ts_info = can_ethtool_op_get_ts_info_hwts,
};

static void kvaser_usb_remove_interfaces(struct kvaser_usb *dev)
{
int i;
Expand Down Expand Up @@ -742,7 +759,13 @@ static int kvaser_usb_init_one(struct kvaser_usb *dev, int channel)
netdev->flags |= IFF_ECHO;

netdev->netdev_ops = &kvaser_usb_netdev_ops;

if (driver_info->quirks & KVASER_USB_QUIRK_HAS_HARDWARE_TIMESTAMP) {
netdev->netdev_ops = &kvaser_usb_netdev_ops_hwts;
netdev->ethtool_ops = &kvaser_usb_ethtool_ops_hwts;
} else {
netdev->netdev_ops = &kvaser_usb_netdev_ops;
netdev->ethtool_ops = &kvaser_usb_ethtool_ops;
}
SET_NETDEV_DEV(netdev, &dev->intf->dev);
netdev->dev_id = channel;

Expand Down

0 comments on commit 1d5eeda

Please sign in to comment.