forked from intel/linux-intel-lts
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
can: mcp251xfd: clarify the meaning of timestamp
[ Upstream commit e793c72 ] The mcp251xfd chip is configured to provide a timestamp with each received and transmitted CAN frame. The timestamp is derived from the internal free-running timer, which can also be read from the TBC register via SPI. The timer is 32 bits wide and is clocked by the external oscillator (typically 20 or 40 MHz). To avoid confusion, we call this timestamp "timestamp_raw" or "ts_raw" for short. Using the timecounter framework, the "ts_raw" is converted to 64 bit nanoseconds since the epoch. This is what we call "timestamp". This is a preparation for the next patches which use the "timestamp" to work around a bug where so far only the "ts_raw" is used. Tested-by: Stefan Althöfer <[email protected]> Tested-by: Thomas Kopp <[email protected]> Signed-off-by: Marc Kleine-Budde <[email protected]> Signed-off-by: Sasha Levin <[email protected]>
- Loading branch information
1 parent
bf501ab
commit 6cdc3fc
Showing
5 changed files
with
43 additions
and
38 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,7 +2,7 @@ | |
// | ||
// mcp251xfd - Microchip MCP251xFD Family CAN controller driver | ||
// | ||
// Copyright (c) 2019, 2020, 2021 Pengutronix, | ||
// Copyright (c) 2019, 2020, 2021, 2023 Pengutronix, | ||
// Marc Kleine-Budde <[email protected]> | ||
// | ||
// Based on: | ||
|
@@ -867,18 +867,18 @@ static int mcp251xfd_get_berr_counter(const struct net_device *ndev, | |
|
||
static struct sk_buff * | ||
mcp251xfd_alloc_can_err_skb(struct mcp251xfd_priv *priv, | ||
struct can_frame **cf, u32 *timestamp) | ||
struct can_frame **cf, u32 *ts_raw) | ||
{ | ||
struct sk_buff *skb; | ||
int err; | ||
|
||
err = mcp251xfd_get_timestamp(priv, timestamp); | ||
err = mcp251xfd_get_timestamp_raw(priv, ts_raw); | ||
if (err) | ||
return NULL; | ||
|
||
skb = alloc_can_err_skb(priv->ndev, cf); | ||
if (skb) | ||
mcp251xfd_skb_set_timestamp(priv, skb, *timestamp); | ||
mcp251xfd_skb_set_timestamp_raw(priv, skb, *ts_raw); | ||
|
||
return skb; | ||
} | ||
|
@@ -889,7 +889,7 @@ static int mcp251xfd_handle_rxovif(struct mcp251xfd_priv *priv) | |
struct mcp251xfd_rx_ring *ring; | ||
struct sk_buff *skb; | ||
struct can_frame *cf; | ||
u32 timestamp, rxovif; | ||
u32 ts_raw, rxovif; | ||
int err, i; | ||
|
||
stats->rx_over_errors++; | ||
|
@@ -924,14 +924,14 @@ static int mcp251xfd_handle_rxovif(struct mcp251xfd_priv *priv) | |
return err; | ||
} | ||
|
||
skb = mcp251xfd_alloc_can_err_skb(priv, &cf, ×tamp); | ||
skb = mcp251xfd_alloc_can_err_skb(priv, &cf, &ts_raw); | ||
if (!skb) | ||
return 0; | ||
|
||
cf->can_id |= CAN_ERR_CRTL; | ||
cf->data[1] = CAN_ERR_CRTL_RX_OVERFLOW; | ||
|
||
err = can_rx_offload_queue_timestamp(&priv->offload, skb, timestamp); | ||
err = can_rx_offload_queue_timestamp(&priv->offload, skb, ts_raw); | ||
if (err) | ||
stats->rx_fifo_errors++; | ||
|
||
|
@@ -948,12 +948,12 @@ static int mcp251xfd_handle_txatif(struct mcp251xfd_priv *priv) | |
static int mcp251xfd_handle_ivmif(struct mcp251xfd_priv *priv) | ||
{ | ||
struct net_device_stats *stats = &priv->ndev->stats; | ||
u32 bdiag1, timestamp; | ||
u32 bdiag1, ts_raw; | ||
struct sk_buff *skb; | ||
struct can_frame *cf = NULL; | ||
int err; | ||
|
||
err = mcp251xfd_get_timestamp(priv, ×tamp); | ||
err = mcp251xfd_get_timestamp_raw(priv, &ts_raw); | ||
if (err) | ||
return err; | ||
|
||
|
@@ -1035,8 +1035,8 @@ static int mcp251xfd_handle_ivmif(struct mcp251xfd_priv *priv) | |
if (!cf) | ||
return 0; | ||
|
||
mcp251xfd_skb_set_timestamp(priv, skb, timestamp); | ||
err = can_rx_offload_queue_timestamp(&priv->offload, skb, timestamp); | ||
mcp251xfd_skb_set_timestamp_raw(priv, skb, ts_raw); | ||
err = can_rx_offload_queue_timestamp(&priv->offload, skb, ts_raw); | ||
if (err) | ||
stats->rx_fifo_errors++; | ||
|
||
|
@@ -1049,7 +1049,7 @@ static int mcp251xfd_handle_cerrif(struct mcp251xfd_priv *priv) | |
struct sk_buff *skb; | ||
struct can_frame *cf = NULL; | ||
enum can_state new_state, rx_state, tx_state; | ||
u32 trec, timestamp; | ||
u32 trec, ts_raw; | ||
int err; | ||
|
||
err = regmap_read(priv->map_reg, MCP251XFD_REG_TREC, &trec); | ||
|
@@ -1079,7 +1079,7 @@ static int mcp251xfd_handle_cerrif(struct mcp251xfd_priv *priv) | |
/* The skb allocation might fail, but can_change_state() | ||
* handles cf == NULL. | ||
*/ | ||
skb = mcp251xfd_alloc_can_err_skb(priv, &cf, ×tamp); | ||
skb = mcp251xfd_alloc_can_err_skb(priv, &cf, &ts_raw); | ||
can_change_state(priv->ndev, cf, tx_state, rx_state); | ||
|
||
if (new_state == CAN_STATE_BUS_OFF) { | ||
|
@@ -1110,7 +1110,7 @@ static int mcp251xfd_handle_cerrif(struct mcp251xfd_priv *priv) | |
cf->data[7] = bec.rxerr; | ||
} | ||
|
||
err = can_rx_offload_queue_timestamp(&priv->offload, skb, timestamp); | ||
err = can_rx_offload_queue_timestamp(&priv->offload, skb, ts_raw); | ||
if (err) | ||
stats->rx_fifo_errors++; | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,7 +2,7 @@ | |
// | ||
// mcp251xfd - Microchip MCP251xFD Family CAN controller driver | ||
// | ||
// Copyright (c) 2021 Pengutronix, | ||
// Copyright (c) 2021, 2023 Pengutronix, | ||
// Marc Kleine-Budde <[email protected]> | ||
// | ||
|
||
|
@@ -11,20 +11,20 @@ | |
|
||
#include "mcp251xfd.h" | ||
|
||
static u64 mcp251xfd_timestamp_read(const struct cyclecounter *cc) | ||
static u64 mcp251xfd_timestamp_raw_read(const struct cyclecounter *cc) | ||
{ | ||
const struct mcp251xfd_priv *priv; | ||
u32 timestamp = 0; | ||
u32 ts_raw = 0; | ||
int err; | ||
|
||
priv = container_of(cc, struct mcp251xfd_priv, cc); | ||
err = mcp251xfd_get_timestamp(priv, ×tamp); | ||
err = mcp251xfd_get_timestamp_raw(priv, &ts_raw); | ||
if (err) | ||
netdev_err(priv->ndev, | ||
"Error %d while reading timestamp. HW timestamps may be inaccurate.", | ||
err); | ||
|
||
return timestamp; | ||
return ts_raw; | ||
} | ||
|
||
static void mcp251xfd_timestamp_work(struct work_struct *work) | ||
|
@@ -39,21 +39,11 @@ static void mcp251xfd_timestamp_work(struct work_struct *work) | |
MCP251XFD_TIMESTAMP_WORK_DELAY_SEC * HZ); | ||
} | ||
|
||
void mcp251xfd_skb_set_timestamp(const struct mcp251xfd_priv *priv, | ||
struct sk_buff *skb, u32 timestamp) | ||
{ | ||
struct skb_shared_hwtstamps *hwtstamps = skb_hwtstamps(skb); | ||
u64 ns; | ||
|
||
ns = timecounter_cyc2time(&priv->tc, timestamp); | ||
hwtstamps->hwtstamp = ns_to_ktime(ns); | ||
} | ||
|
||
void mcp251xfd_timestamp_init(struct mcp251xfd_priv *priv) | ||
{ | ||
struct cyclecounter *cc = &priv->cc; | ||
|
||
cc->read = mcp251xfd_timestamp_read; | ||
cc->read = mcp251xfd_timestamp_raw_read; | ||
cc->mask = CYCLECOUNTER_MASK(32); | ||
cc->shift = 1; | ||
cc->mult = clocksource_hz2mult(priv->can.clock.freq, cc->shift); | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,7 +2,7 @@ | |
* | ||
* mcp251xfd - Microchip MCP251xFD Family CAN controller driver | ||
* | ||
* Copyright (c) 2019, 2020, 2021 Pengutronix, | ||
* Copyright (c) 2019, 2020, 2021, 2023 Pengutronix, | ||
* Marc Kleine-Budde <[email protected]> | ||
* Copyright (c) 2019 Martin Sperl <[email protected]> | ||
*/ | ||
|
@@ -812,10 +812,27 @@ mcp251xfd_spi_cmd_write(const struct mcp251xfd_priv *priv, | |
return data; | ||
} | ||
|
||
static inline int mcp251xfd_get_timestamp(const struct mcp251xfd_priv *priv, | ||
u32 *timestamp) | ||
static inline int mcp251xfd_get_timestamp_raw(const struct mcp251xfd_priv *priv, | ||
u32 *ts_raw) | ||
{ | ||
return regmap_read(priv->map_reg, MCP251XFD_REG_TBC, timestamp); | ||
return regmap_read(priv->map_reg, MCP251XFD_REG_TBC, ts_raw); | ||
} | ||
|
||
static inline void mcp251xfd_skb_set_timestamp(struct sk_buff *skb, u64 ns) | ||
{ | ||
struct skb_shared_hwtstamps *hwtstamps = skb_hwtstamps(skb); | ||
|
||
hwtstamps->hwtstamp = ns_to_ktime(ns); | ||
} | ||
|
||
static inline | ||
void mcp251xfd_skb_set_timestamp_raw(const struct mcp251xfd_priv *priv, | ||
struct sk_buff *skb, u32 ts_raw) | ||
{ | ||
u64 ns; | ||
|
||
ns = timecounter_cyc2time(&priv->tc, ts_raw); | ||
mcp251xfd_skb_set_timestamp(skb, ns); | ||
} | ||
|
||
static inline u16 mcp251xfd_get_tef_obj_addr(u8 n) | ||
|
@@ -936,8 +953,6 @@ void mcp251xfd_ring_free(struct mcp251xfd_priv *priv); | |
int mcp251xfd_ring_alloc(struct mcp251xfd_priv *priv); | ||
int mcp251xfd_handle_rxif(struct mcp251xfd_priv *priv); | ||
int mcp251xfd_handle_tefif(struct mcp251xfd_priv *priv); | ||
void mcp251xfd_skb_set_timestamp(const struct mcp251xfd_priv *priv, | ||
struct sk_buff *skb, u32 timestamp); | ||
void mcp251xfd_timestamp_init(struct mcp251xfd_priv *priv); | ||
void mcp251xfd_timestamp_stop(struct mcp251xfd_priv *priv); | ||
|
||
|