Skip to content

Commit

Permalink
can: peak_usb: advertise timestamping capabilities and add ioctl support
Browse files Browse the repository at this point in the history
Currently, userland has no method to query which timestamping features
are supported by the peak_usb driver (aside maybe of getting RX
messages and observe whether or not hardware timestamps stay at zero).

The canonical way to add hardware timestamp support is to implement
ethtool_ops::get_ts_info() in order to advertise the timestamping
capabilities and to implement net_device_ops::ndo_eth_ioctl() as
requested in [1]. Currently, the driver only supports hardware RX
timestamps [2] but not hardware TX. For this reason, the generic
function can_ethtool_op_get_ts_info_hwts() and can_eth_ioctl_hwts()
can not be reused and instead this patch adds pcan_get_ts_info() and
peak_eth_ioctl().

[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

[2] https://lore.kernel.org/linux-can/20220727080634.l6uttnbrmwbabh3o@pengutronix.de/

CC: Stephane Grosjean <s.grosjean@peak-system.com>
Signed-off-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
Link: https://lore.kernel.org/all/20220727101641.198847-15-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 8ba09bf commit bedd948
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 0 deletions.
1 change: 1 addition & 0 deletions drivers/net/can/usb/peak_usb/pcan_usb.c
Original file line number Diff line number Diff line change
Expand Up @@ -965,6 +965,7 @@ static int pcan_usb_set_phys_id(struct net_device *netdev,

static const struct ethtool_ops pcan_usb_ethtool_ops = {
.set_phys_id = pcan_usb_set_phys_id,
.get_ts_info = pcan_get_ts_info,
};

/*
Expand Down
41 changes: 41 additions & 0 deletions drivers/net/can/usb/peak_usb/pcan_usb_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -775,13 +775,54 @@ static int peak_usb_set_data_bittiming(struct net_device *netdev)
return 0;
}

static int peak_eth_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
{
struct hwtstamp_config hwts_cfg = { 0 };

switch (cmd) {
case SIOCSHWTSTAMP: /* set */
if (copy_from_user(&hwts_cfg, ifr->ifr_data, sizeof(hwts_cfg)))
return -EFAULT;
if (hwts_cfg.tx_type == HWTSTAMP_TX_OFF &&
hwts_cfg.rx_filter == HWTSTAMP_FILTER_ALL)
return 0;
return -ERANGE;

case SIOCGHWTSTAMP: /* get */
hwts_cfg.tx_type = HWTSTAMP_TX_OFF;
hwts_cfg.rx_filter = HWTSTAMP_FILTER_ALL;
if (copy_to_user(ifr->ifr_data, &hwts_cfg, sizeof(hwts_cfg)))
return -EFAULT;
return 0;

default:
return -EOPNOTSUPP;
}
}

static const struct net_device_ops peak_usb_netdev_ops = {
.ndo_open = peak_usb_ndo_open,
.ndo_stop = peak_usb_ndo_stop,
.ndo_eth_ioctl = peak_eth_ioctl,
.ndo_start_xmit = peak_usb_ndo_start_xmit,
.ndo_change_mtu = can_change_mtu,
};

int pcan_get_ts_info(struct net_device *dev, struct ethtool_ts_info *info)
{
info->so_timestamping =
SOF_TIMESTAMPING_TX_SOFTWARE |
SOF_TIMESTAMPING_RX_SOFTWARE |
SOF_TIMESTAMPING_SOFTWARE |
SOF_TIMESTAMPING_RX_HARDWARE |
SOF_TIMESTAMPING_RAW_HARDWARE;
info->phc_index = -1;
info->tx_types = BIT(HWTSTAMP_TX_OFF);
info->rx_filters = BIT(HWTSTAMP_FILTER_ALL);

return 0;
}

/*
* create one device which is attached to CAN controller #ctrl_idx of the
* usb adapter.
Expand Down
1 change: 1 addition & 0 deletions drivers/net/can/usb/peak_usb/pcan_usb_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -145,5 +145,6 @@ int peak_usb_netif_rx(struct sk_buff *skb,
int peak_usb_netif_rx_64(struct sk_buff *skb, u32 ts_low, u32 ts_high);
void peak_usb_async_complete(struct urb *urb);
void peak_usb_restart_complete(struct peak_usb_device *dev);
int pcan_get_ts_info(struct net_device *dev, struct ethtool_ts_info *info);

#endif
1 change: 1 addition & 0 deletions drivers/net/can/usb/peak_usb/pcan_usb_fd.c
Original file line number Diff line number Diff line change
Expand Up @@ -1080,6 +1080,7 @@ static int pcan_usb_fd_set_phys_id(struct net_device *netdev,

static const struct ethtool_ops pcan_usb_fd_ethtool_ops = {
.set_phys_id = pcan_usb_fd_set_phys_id,
.get_ts_info = pcan_get_ts_info,
};

/* describes the PCAN-USB FD adapter */
Expand Down
1 change: 1 addition & 0 deletions drivers/net/can/usb/peak_usb/pcan_usb_pro.c
Original file line number Diff line number Diff line change
Expand Up @@ -1022,6 +1022,7 @@ static int pcan_usb_pro_set_phys_id(struct net_device *netdev,

static const struct ethtool_ops pcan_usb_pro_ethtool_ops = {
.set_phys_id = pcan_usb_pro_set_phys_id,
.get_ts_info = pcan_get_ts_info,
};

/*
Expand Down

0 comments on commit bedd948

Please sign in to comment.