cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

mcp251xfd-timestamp.c (1888B)


      1// SPDX-License-Identifier: GPL-2.0
      2//
      3// mcp251xfd - Microchip MCP251xFD Family CAN controller driver
      4//
      5// Copyright (c) 2021 Pengutronix,
      6//               Marc Kleine-Budde <kernel@pengutronix.de>
      7//
      8
      9#include <linux/clocksource.h>
     10#include <linux/workqueue.h>
     11
     12#include "mcp251xfd.h"
     13
     14static u64 mcp251xfd_timestamp_read(const struct cyclecounter *cc)
     15{
     16	const struct mcp251xfd_priv *priv;
     17	u32 timestamp = 0;
     18	int err;
     19
     20	priv = container_of(cc, struct mcp251xfd_priv, cc);
     21	err = mcp251xfd_get_timestamp(priv, &timestamp);
     22	if (err)
     23		netdev_err(priv->ndev,
     24			   "Error %d while reading timestamp. HW timestamps may be inaccurate.",
     25			   err);
     26
     27	return timestamp;
     28}
     29
     30static void mcp251xfd_timestamp_work(struct work_struct *work)
     31{
     32	struct delayed_work *delayed_work = to_delayed_work(work);
     33	struct mcp251xfd_priv *priv;
     34
     35	priv = container_of(delayed_work, struct mcp251xfd_priv, timestamp);
     36	timecounter_read(&priv->tc);
     37
     38	schedule_delayed_work(&priv->timestamp,
     39			      MCP251XFD_TIMESTAMP_WORK_DELAY_SEC * HZ);
     40}
     41
     42void mcp251xfd_skb_set_timestamp(const struct mcp251xfd_priv *priv,
     43				 struct sk_buff *skb, u32 timestamp)
     44{
     45	struct skb_shared_hwtstamps *hwtstamps = skb_hwtstamps(skb);
     46	u64 ns;
     47
     48	ns = timecounter_cyc2time(&priv->tc, timestamp);
     49	hwtstamps->hwtstamp = ns_to_ktime(ns);
     50}
     51
     52void mcp251xfd_timestamp_init(struct mcp251xfd_priv *priv)
     53{
     54	struct cyclecounter *cc = &priv->cc;
     55
     56	cc->read = mcp251xfd_timestamp_read;
     57	cc->mask = CYCLECOUNTER_MASK(32);
     58	cc->shift = 1;
     59	cc->mult = clocksource_hz2mult(priv->can.clock.freq, cc->shift);
     60
     61	timecounter_init(&priv->tc, &priv->cc, ktime_get_real_ns());
     62
     63	INIT_DELAYED_WORK(&priv->timestamp, mcp251xfd_timestamp_work);
     64	schedule_delayed_work(&priv->timestamp,
     65			      MCP251XFD_TIMESTAMP_WORK_DELAY_SEC * HZ);
     66}
     67
     68void mcp251xfd_timestamp_stop(struct mcp251xfd_priv *priv)
     69{
     70	cancel_delayed_work_sync(&priv->timestamp);
     71}