diff options
Diffstat (limited to 'drivers/net/can/peak_canfd/peak_canfd.c')
-rw-r--r-- | drivers/net/can/peak_canfd/peak_canfd.c | 25 |
1 files changed, 19 insertions, 6 deletions
diff --git a/drivers/net/can/peak_canfd/peak_canfd.c b/drivers/net/can/peak_canfd/peak_canfd.c index 6b0c6a99fc8d..10aa3e457c33 100644 --- a/drivers/net/can/peak_canfd/peak_canfd.c +++ b/drivers/net/can/peak_canfd/peak_canfd.c @@ -1,6 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (C) 2007, 2011 Wolfgang Grandegger <wg@grandegger.com> +/* Copyright (C) 2007, 2011 Wolfgang Grandegger <wg@grandegger.com> * Copyright (C) 2012 Stephane Grosjean <s.grosjean@peak-system.com> * * Copyright (C) 2016 PEAK System-Technik GmbH @@ -122,7 +121,8 @@ static int pucan_set_timing_slow(struct peak_canfd_priv *priv, cmd = pucan_add_cmd(pucan_init_cmd(priv), PUCAN_CMD_TIMING_SLOW); cmd->sjw_t = PUCAN_TSLOW_SJW_T(pbt->sjw - 1, - priv->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES); + priv->can.ctrlmode & + CAN_CTRLMODE_3_SAMPLES); cmd->tseg1 = PUCAN_TSLOW_TSEG1(pbt->prop_seg + pbt->phase_seg1 - 1); cmd->tseg2 = PUCAN_TSLOW_TSEG2(pbt->phase_seg2 - 1); cmd->brp = cpu_to_le16(PUCAN_TSLOW_BRP(pbt->brp - 1)); @@ -232,6 +232,20 @@ static int pucan_setup_rx_barrier(struct peak_canfd_priv *priv) return pucan_write_cmd(priv); } +static int pucan_netif_rx(struct sk_buff *skb, __le32 ts_low, __le32 ts_high) +{ + struct skb_shared_hwtstamps *hwts = skb_hwtstamps(skb); + u64 ts_us; + + ts_us = (u64)le32_to_cpu(ts_high) << 32; + ts_us |= le32_to_cpu(ts_low); + + /* IP core timestamps are µs. */ + hwts->hwtstamp = ns_to_ktime(ts_us * NSEC_PER_USEC); + + return netif_rx(skb); +} + /* handle the reception of one CAN frame */ static int pucan_handle_can_rx(struct peak_canfd_priv *priv, struct pucan_rx_msg *msg) @@ -299,7 +313,7 @@ static int pucan_handle_can_rx(struct peak_canfd_priv *priv, stats->rx_bytes += cf->len; stats->rx_packets++; - netif_rx(skb); + pucan_netif_rx(skb, msg->ts_low, msg->ts_high); return 0; } @@ -325,7 +339,6 @@ static int pucan_handle_status(struct peak_canfd_priv *priv, /* this STATUS is the CNF of the RX_BARRIER: Tx path can be setup */ if (pucan_status_is_rx_barrier(msg)) { - if (priv->enable_tx_path) { int err = priv->enable_tx_path(priv); @@ -393,7 +406,7 @@ static int pucan_handle_status(struct peak_canfd_priv *priv, stats->rx_packets++; stats->rx_bytes += cf->can_dlc; - netif_rx(skb); + pucan_netif_rx(skb, msg->ts_low, msg->ts_high); return 0; } |