| .. | .. |
|---|
| 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 | } |
|---|