.. | .. |
---|
1 | | -/* |
---|
2 | | - * Copyright (C) 2007, 2011 Wolfgang Grandegger <wg@grandegger.com> |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
| 2 | +/* Copyright (C) 2007, 2011 Wolfgang Grandegger <wg@grandegger.com> |
---|
3 | 3 | * Copyright (C) 2012 Stephane Grosjean <s.grosjean@peak-system.com> |
---|
4 | 4 | * |
---|
5 | 5 | * Copyright (C) 2016 PEAK System-Technik GmbH |
---|
6 | | - * |
---|
7 | | - * This program is free software; you can redistribute it and/or modify |
---|
8 | | - * it under the terms of the version 2 of the GNU General Public License |
---|
9 | | - * as published by the Free Software Foundation |
---|
10 | | - * |
---|
11 | | - * This program is distributed in the hope that it will be useful, |
---|
12 | | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
13 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
---|
14 | | - * GNU General Public License for more details. |
---|
15 | 6 | */ |
---|
16 | 7 | |
---|
17 | 8 | #include <linux/can.h> |
---|
.. | .. |
---|
130 | 121 | cmd = pucan_add_cmd(pucan_init_cmd(priv), PUCAN_CMD_TIMING_SLOW); |
---|
131 | 122 | |
---|
132 | 123 | cmd->sjw_t = PUCAN_TSLOW_SJW_T(pbt->sjw - 1, |
---|
133 | | - priv->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES); |
---|
| 124 | + priv->can.ctrlmode & |
---|
| 125 | + CAN_CTRLMODE_3_SAMPLES); |
---|
134 | 126 | cmd->tseg1 = PUCAN_TSLOW_TSEG1(pbt->prop_seg + pbt->phase_seg1 - 1); |
---|
135 | 127 | cmd->tseg2 = PUCAN_TSLOW_TSEG2(pbt->phase_seg2 - 1); |
---|
136 | 128 | cmd->brp = cpu_to_le16(PUCAN_TSLOW_BRP(pbt->brp - 1)); |
---|
.. | .. |
---|
240 | 232 | return pucan_write_cmd(priv); |
---|
241 | 233 | } |
---|
242 | 234 | |
---|
| 235 | +static int pucan_netif_rx(struct sk_buff *skb, __le32 ts_low, __le32 ts_high) |
---|
| 236 | +{ |
---|
| 237 | + struct skb_shared_hwtstamps *hwts = skb_hwtstamps(skb); |
---|
| 238 | + u64 ts_us; |
---|
| 239 | + |
---|
| 240 | + ts_us = (u64)le32_to_cpu(ts_high) << 32; |
---|
| 241 | + ts_us |= le32_to_cpu(ts_low); |
---|
| 242 | + |
---|
| 243 | + /* IP core timestamps are µs. */ |
---|
| 244 | + hwts->hwtstamp = ns_to_ktime(ts_us * NSEC_PER_USEC); |
---|
| 245 | + |
---|
| 246 | + return netif_rx(skb); |
---|
| 247 | +} |
---|
| 248 | + |
---|
243 | 249 | /* handle the reception of one CAN frame */ |
---|
244 | 250 | static int pucan_handle_can_rx(struct peak_canfd_priv *priv, |
---|
245 | 251 | struct pucan_rx_msg *msg) |
---|
.. | .. |
---|
312 | 318 | stats->rx_bytes += cf->len; |
---|
313 | 319 | stats->rx_packets++; |
---|
314 | 320 | |
---|
315 | | - netif_rx(skb); |
---|
| 321 | + pucan_netif_rx(skb, msg->ts_low, msg->ts_high); |
---|
316 | 322 | |
---|
317 | 323 | return 0; |
---|
318 | 324 | } |
---|
.. | .. |
---|
338 | 344 | |
---|
339 | 345 | /* this STATUS is the CNF of the RX_BARRIER: Tx path can be setup */ |
---|
340 | 346 | if (pucan_status_is_rx_barrier(msg)) { |
---|
341 | | - |
---|
342 | 347 | if (priv->enable_tx_path) { |
---|
343 | 348 | int err = priv->enable_tx_path(priv); |
---|
344 | 349 | |
---|
.. | .. |
---|
406 | 411 | |
---|
407 | 412 | stats->rx_packets++; |
---|
408 | 413 | stats->rx_bytes += cf->can_dlc; |
---|
409 | | - netif_rx(skb); |
---|
| 414 | + pucan_netif_rx(skb, msg->ts_low, msg->ts_high); |
---|
410 | 415 | |
---|
411 | 416 | return 0; |
---|
412 | 417 | } |
---|