can: peak_usb: CANFD: store 64-bits hw timestamps
authorStephane Grosjean <s.grosjean@peak-system.com>
Thu, 30 Sep 2021 09:46:03 +0000 (11:46 +0200)
committerMarc Kleine-Budde <mkl@pengutronix.de>
Sun, 24 Oct 2021 14:26:05 +0000 (16:26 +0200)
This patch allows to use the whole 64-bit timestamps received from the
CAN-FD device (expressed in µs) rather than only its low part, in the
hwtstamp structure of the skb transferred to the network layer, when a
CAN/CANFD frame has been received.

Link: https://lore.kernel.org/all/20210930094603.23134-1-s.grosjean@peak-system.com
Signed-off-by: Stephane Grosjean <s.grosjean@peak-system.com>
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
drivers/net/can/usb/peak_usb/pcan_usb_core.c
drivers/net/can/usb/peak_usb/pcan_usb_core.h
drivers/net/can/usb/peak_usb/pcan_usb_fd.c

index e8f43ed..6107fef 100644 (file)
@@ -205,6 +205,19 @@ int peak_usb_netif_rx(struct sk_buff *skb,
        return netif_rx(skb);
 }
 
+/* post received skb with native 64-bit hw timestamp */
+int peak_usb_netif_rx_64(struct sk_buff *skb, u32 ts_low, u32 ts_high)
+{
+       struct skb_shared_hwtstamps *hwts = skb_hwtstamps(skb);
+       u64 ns_ts;
+
+       ns_ts = (u64)ts_high << 32 | ts_low;
+       ns_ts *= NSEC_PER_USEC;
+       hwts->hwtstamp = ns_to_ktime(ns_ts);
+
+       return netif_rx(skb);
+}
+
 /*
  * callback for bulk Rx urb
  */
index b00a481..daa19f5 100644 (file)
@@ -143,6 +143,7 @@ void peak_usb_set_ts_now(struct peak_time_ref *time_ref, u32 ts_now);
 void peak_usb_get_ts_time(struct peak_time_ref *time_ref, u32 ts, ktime_t *tv);
 int peak_usb_netif_rx(struct sk_buff *skb,
                      struct peak_time_ref *time_ref, u32 ts_low);
+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);
 
index 09029a3..6bd1254 100644 (file)
@@ -515,7 +515,8 @@ static int pcan_usb_fd_decode_canmsg(struct pcan_usb_fd_if *usb_if,
        netdev->stats.rx_packets++;
        netdev->stats.rx_bytes += cfd->len;
 
-       peak_usb_netif_rx(skb, &usb_if->time_ref, le32_to_cpu(rm->ts_low));
+       peak_usb_netif_rx_64(skb, le32_to_cpu(rm->ts_low),
+                            le32_to_cpu(rm->ts_high));
 
        return 0;
 }
@@ -579,7 +580,8 @@ static int pcan_usb_fd_decode_status(struct pcan_usb_fd_if *usb_if,
        netdev->stats.rx_packets++;
        netdev->stats.rx_bytes += cf->len;
 
-       peak_usb_netif_rx(skb, &usb_if->time_ref, le32_to_cpu(sm->ts_low));
+       peak_usb_netif_rx_64(skb, le32_to_cpu(sm->ts_low),
+                            le32_to_cpu(sm->ts_high));
 
        return 0;
 }
@@ -629,7 +631,8 @@ static int pcan_usb_fd_decode_overrun(struct pcan_usb_fd_if *usb_if,
        cf->can_id |= CAN_ERR_CRTL;
        cf->data[1] |= CAN_ERR_CRTL_RX_OVERFLOW;
 
-       peak_usb_netif_rx(skb, &usb_if->time_ref, le32_to_cpu(ov->ts_low));
+       peak_usb_netif_rx_64(skb, le32_to_cpu(ov->ts_low),
+                            le32_to_cpu(ov->ts_high));
 
        netdev->stats.rx_over_errors++;
        netdev->stats.rx_errors++;