Add hardware timestamp support to leaf based devices (M32C and leafimx). Signed-off-by: Jimmy Assarsson <extja@xxxxxxxxxx> --- .../net/can/usb/kvaser_usb/kvaser_usb_core.c | 11 +++++++---- .../net/can/usb/kvaser_usb/kvaser_usb_leaf.c | 19 +++++++++++++++++++ 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c b/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c index daa34b532aa8..b5d762d38d5d 100644 --- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c +++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c @@ -106,14 +106,16 @@ static const struct kvaser_usb_driver_info kvaser_usb_driver_info_usbcan = { }; static const struct kvaser_usb_driver_info kvaser_usb_driver_info_leaf = { - .quirks = KVASER_USB_QUIRK_IGNORE_CLK_FREQ, + .quirks = KVASER_USB_QUIRK_IGNORE_CLK_FREQ | + KVASER_USB_QUIRK_HAS_HARDWARE_TIMESTAMP, .family = KVASER_LEAF, .ops = &kvaser_usb_leaf_dev_ops, }; static const struct kvaser_usb_driver_info kvaser_usb_driver_info_leaf_err = { .quirks = KVASER_USB_QUIRK_HAS_TXRX_ERRORS | - KVASER_USB_QUIRK_IGNORE_CLK_FREQ, + KVASER_USB_QUIRK_IGNORE_CLK_FREQ | + KVASER_USB_QUIRK_HAS_HARDWARE_TIMESTAMP, .family = KVASER_LEAF, .ops = &kvaser_usb_leaf_dev_ops, }; @@ -121,13 +123,14 @@ static const struct kvaser_usb_driver_info kvaser_usb_driver_info_leaf_err = { static const struct kvaser_usb_driver_info kvaser_usb_driver_info_leaf_err_listen = { .quirks = KVASER_USB_QUIRK_HAS_TXRX_ERRORS | KVASER_USB_QUIRK_HAS_SILENT_MODE | - KVASER_USB_QUIRK_IGNORE_CLK_FREQ, + KVASER_USB_QUIRK_IGNORE_CLK_FREQ | + KVASER_USB_QUIRK_HAS_HARDWARE_TIMESTAMP, .family = KVASER_LEAF, .ops = &kvaser_usb_leaf_dev_ops, }; static const struct kvaser_usb_driver_info kvaser_usb_driver_info_leafimx = { - .quirks = 0, + .quirks = KVASER_USB_QUIRK_HAS_HARDWARE_TIMESTAMP, .family = KVASER_LEAF, .ops = &kvaser_usb_leaf_dev_ops, }; diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c b/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c index caef1f26a95c..c0a8713d8cf2 100644 --- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c +++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c @@ -915,6 +915,8 @@ static void kvaser_usb_leaf_tx_acknowledge(const struct kvaser_usb *dev, struct kvaser_usb_net_priv *priv; unsigned long flags; u8 channel, tid; + struct sk_buff *skb; + u64 ticks = 0; channel = cmd->u.tx_acknowledge_header.channel; tid = cmd->u.tx_acknowledge_header.tid; @@ -954,9 +956,21 @@ static void kvaser_usb_leaf_tx_acknowledge(const struct kvaser_usb *dev, priv->can.state = CAN_STATE_ERROR_ACTIVE; } + switch (dev->driver_info->family) { + case KVASER_LEAF: + ticks = le16_to_cpu(cmd->u.leaf.tx_ack.time[0]); + ticks += (u64)(le16_to_cpu(cmd->u.leaf.tx_ack.time[1])) << 16; + ticks += (u64)(le16_to_cpu(cmd->u.leaf.tx_ack.time[2])) << 32; + break; + case KVASER_USBCAN: + break; + } spin_lock_irqsave(&priv->tx_contexts_lock, flags); + skb = priv->can.echo_skb[context->echo_index]; + if (skb) + skb_hwtstamps(skb)->hwtstamp = kvaser_usb_ticks_to_ktime(dev->cfg, ticks); stats->tx_packets++; stats->tx_bytes += can_get_echo_skb(priv->netdev, context->echo_index, NULL); @@ -1334,6 +1348,7 @@ static void kvaser_usb_leaf_rx_can_msg(const struct kvaser_usb *dev, struct net_device_stats *stats; u8 channel = cmd->u.rx_can_header.channel; const u8 *rx_data = NULL; /* GCC */ + u64 ticks = 0; if (channel >= dev->nchannels) { dev_err(&dev->intf->dev, @@ -1364,6 +1379,9 @@ static void kvaser_usb_leaf_rx_can_msg(const struct kvaser_usb *dev, switch (dev->driver_info->family) { case KVASER_LEAF: rx_data = cmd->u.leaf.rx_can.data; + ticks = le16_to_cpu(cmd->u.leaf.rx_can.time[0]); + ticks += (u64)(le16_to_cpu(cmd->u.leaf.rx_can.time[1])) << 16; + ticks += (u64)(le16_to_cpu(cmd->u.leaf.rx_can.time[2])) << 32; break; case KVASER_USBCAN: rx_data = cmd->u.usbcan.rx_can.data; @@ -1410,6 +1428,7 @@ static void kvaser_usb_leaf_rx_can_msg(const struct kvaser_usb *dev, memcpy(cf->data, &rx_data[6], cf->len); } + skb_hwtstamps(skb)->hwtstamp = kvaser_usb_ticks_to_ktime(dev->cfg, ticks); stats->rx_packets++; if (!(cf->can_id & CAN_RTR_FLAG)) stats->rx_bytes += cf->len; -- 2.45.2