can: kvaser_usb: leaf: Add hardware timestamp support to leaf based devices
authorJimmy Assarsson <extja@kvaser.com>
Mon, 1 Jul 2024 15:49:30 +0000 (17:49 +0200)
committerMarc Kleine-Budde <mkl@pengutronix.de>
Mon, 5 Aug 2024 15:39:02 +0000 (17:39 +0200)
Add hardware timestamp support to leaf based devices (M32C and leafimx).

Signed-off-by: Jimmy Assarsson <extja@kvaser.com>
Reviewed-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
Link: https://lore.kernel.org/all/20240701154936.92633-10-extja@kvaser.com
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c
drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c

index daa34b532aa8f0236fa3fe24afa387408aa6a3a3..b5d762d38d5d63ac2fec2f381253b742a1f1c370 100644 (file)
@@ -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,
 };
index caef1f26a95cb25006a531efd41fa053e2791ced..5839333eb5aea7622d77add1f35471fa9d044232 100644 (file)
@@ -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;
+       ktime_t hwtstamp = 0;
 
        channel = cmd->u.tx_acknowledge_header.channel;
        tid = cmd->u.tx_acknowledge_header.tid;
@@ -954,9 +956,19 @@ 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:
+               hwtstamp = kvaser_usb_timestamp48_to_ktime(dev->cfg, cmd->u.leaf.tx_ack.time);
+               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 = hwtstamp;
        stats->tx_packets++;
        stats->tx_bytes += can_get_echo_skb(priv->netdev,
                                            context->echo_index, NULL);
@@ -1334,6 +1346,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 */
+       ktime_t hwtstamp = 0;
 
        if (channel >= dev->nchannels) {
                dev_err(&dev->intf->dev,
@@ -1364,6 +1377,7 @@ 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;
+               hwtstamp = kvaser_usb_timestamp48_to_ktime(dev->cfg, cmd->u.leaf.rx_can.time);
                break;
        case KVASER_USBCAN:
                rx_data = cmd->u.usbcan.rx_can.data;
@@ -1410,6 +1424,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 = hwtstamp;
        stats->rx_packets++;
        if (!(cf->can_id & CAN_RTR_FLAG))
                stats->rx_bytes += cf->len;