Skip to content

Commit

Permalink
can: tree-wide: advertise software timestamping capabilities
Browse files Browse the repository at this point in the history
Currently, some CAN drivers support hardware timestamping, some do
not. But userland has no method to query which features are supported
(aside maybe of getting RX messages and observe whether or not
hardware timestamps stay at zero).

The canonical way for a network driver to advertised what kind of
timestamping it supports is to implement ethtool_ops::get_ts_info().

This patch only targets the CAN drivers which *do not* support
hardware timestamping.  For each of those CAN drivers, implement the
get_ts_info() using the generic ethtool_op_get_ts_info().

This way, userland can do:

| $ ethtool --show-time-stamping canX

to confirm the device timestamping capacities.

N.B. the drivers which support hardware timestamping will be migrated
in separate patches.

Signed-off-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
Link: https://lore.kernel.org/all/20220727101641.198847-6-mailhol.vincent@wanadoo.fr
[mkl: mscan: add missing mscan_ethtool_ops]
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
  • Loading branch information
Vincent Mailhol authored and Marc Kleine-Budde committed Jul 28, 2022
1 parent 6a37a28 commit 409c188
Show file tree
Hide file tree
Showing 30 changed files with 159 additions and 0 deletions.
6 changes: 6 additions & 0 deletions drivers/net/can/at91_can.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

#include <linux/clk.h>
#include <linux/errno.h>
#include <linux/ethtool.h>
#include <linux/if_arp.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
Expand Down Expand Up @@ -1152,6 +1153,10 @@ static const struct net_device_ops at91_netdev_ops = {
.ndo_change_mtu = can_change_mtu,
};

static const struct ethtool_ops at91_ethtool_ops = {
.get_ts_info = ethtool_op_get_ts_info,
};

static ssize_t mb0_id_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
Expand Down Expand Up @@ -1293,6 +1298,7 @@ static int at91_can_probe(struct platform_device *pdev)
}

dev->netdev_ops = &at91_netdev_ops;
dev->ethtool_ops = &at91_ethtool_ops;
dev->irq = irq;
dev->flags |= IFF_ECHO;

Expand Down
1 change: 1 addition & 0 deletions drivers/net/can/c_can/c_can_ethtool.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,5 @@ static void c_can_get_ringparam(struct net_device *netdev,

const struct ethtool_ops c_can_ethtool_ops = {
.get_ringparam = c_can_get_ringparam,
.get_ts_info = ethtool_op_get_ts_info,
};
5 changes: 5 additions & 0 deletions drivers/net/can/can327.c
Original file line number Diff line number Diff line change
Expand Up @@ -850,6 +850,10 @@ static const struct net_device_ops can327_netdev_ops = {
.ndo_change_mtu = can_change_mtu,
};

static const struct ethtool_ops can327_ethtool_ops = {
.get_ts_info = ethtool_op_get_ts_info,
};

static bool can327_is_valid_rx_char(u8 c)
{
static const bool lut_char_is_valid['z'] = {
Expand Down Expand Up @@ -1034,6 +1038,7 @@ static int can327_ldisc_open(struct tty_struct *tty)
/* Configure netdev interface */
elm->dev = dev;
dev->netdev_ops = &can327_netdev_ops;
dev->ethtool_ops = &can327_ethtool_ops;

/* Mark ldisc channel as alive */
elm->tty = tty;
Expand Down
6 changes: 6 additions & 0 deletions drivers/net/can/cc770/cc770.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include <linux/ptrace.h>
#include <linux/string.h>
#include <linux/errno.h>
#include <linux/ethtool.h>
#include <linux/netdevice.h>
#include <linux/if_arp.h>
#include <linux/if_ether.h>
Expand Down Expand Up @@ -836,6 +837,10 @@ static const struct net_device_ops cc770_netdev_ops = {
.ndo_change_mtu = can_change_mtu,
};

static const struct ethtool_ops cc770_ethtool_ops = {
.get_ts_info = ethtool_op_get_ts_info,
};

int register_cc770dev(struct net_device *dev)
{
struct cc770_priv *priv = netdev_priv(dev);
Expand All @@ -846,6 +851,7 @@ int register_cc770dev(struct net_device *dev)
return err;

dev->netdev_ops = &cc770_netdev_ops;
dev->ethtool_ops = &cc770_ethtool_ops;

dev->flags |= IFF_ECHO; /* we support local echo */

Expand Down
6 changes: 6 additions & 0 deletions drivers/net/can/ctucanfd/ctucanfd_base.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

#include <linux/clk.h>
#include <linux/errno.h>
#include <linux/ethtool.h>
#include <linux/init.h>
#include <linux/bitfield.h>
#include <linux/interrupt.h>
Expand Down Expand Up @@ -1301,6 +1302,10 @@ static const struct net_device_ops ctucan_netdev_ops = {
.ndo_change_mtu = can_change_mtu,
};

static const struct ethtool_ops ctucan_ethtool_ops = {
.get_ts_info = ethtool_op_get_ts_info,
};

int ctucan_suspend(struct device *dev)
{
struct net_device *ndev = dev_get_drvdata(dev);
Expand Down Expand Up @@ -1377,6 +1382,7 @@ int ctucan_probe_common(struct device *dev, void __iomem *addr, int irq, unsigne
set_drvdata_fnc(dev, ndev);
SET_NETDEV_DEV(ndev, dev);
ndev->netdev_ops = &ctucan_netdev_ops;
ndev->ethtool_ops = &ctucan_ethtool_ops;

/* Getting the can_clk info */
if (!can_clk_rate) {
Expand Down
1 change: 1 addition & 0 deletions drivers/net/can/flexcan/flexcan-ethtool.c
Original file line number Diff line number Diff line change
Expand Up @@ -106,4 +106,5 @@ const struct ethtool_ops flexcan_ethtool_ops = {
.get_priv_flags = flexcan_get_priv_flags,
.set_priv_flags = flexcan_set_priv_flags,
.get_sset_count = flexcan_get_sset_count,
.get_ts_info = ethtool_op_get_ts_info,
};
6 changes: 6 additions & 0 deletions drivers/net/can/grcan.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include <linux/interrupt.h>
#include <linux/netdevice.h>
#include <linux/delay.h>
#include <linux/ethtool.h>
#include <linux/io.h>
#include <linux/can/dev.h>
#include <linux/spinlock.h>
Expand Down Expand Up @@ -1561,6 +1562,10 @@ static const struct net_device_ops grcan_netdev_ops = {
.ndo_change_mtu = can_change_mtu,
};

static const struct ethtool_ops grcan_ethtool_ops = {
.get_ts_info = ethtool_op_get_ts_info,
};

static int grcan_setup_netdev(struct platform_device *ofdev,
void __iomem *base,
int irq, u32 ambafreq, bool txbug)
Expand All @@ -1577,6 +1582,7 @@ static int grcan_setup_netdev(struct platform_device *ofdev,
dev->irq = irq;
dev->flags |= IFF_ECHO;
dev->netdev_ops = &grcan_netdev_ops;
dev->ethtool_ops = &grcan_ethtool_ops;
dev->sysfs_groups[0] = &sysfs_grcan_group;

priv = netdev_priv(dev);
Expand Down
6 changes: 6 additions & 0 deletions drivers/net/can/ifi_canfd/ifi_canfd.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/ethtool.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/kernel.h>
Expand Down Expand Up @@ -925,6 +926,10 @@ static const struct net_device_ops ifi_canfd_netdev_ops = {
.ndo_change_mtu = can_change_mtu,
};

static const struct ethtool_ops ifi_canfd_ethtool_ops = {
.get_ts_info = ethtool_op_get_ts_info,
};

static int ifi_canfd_plat_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
Expand Down Expand Up @@ -962,6 +967,7 @@ static int ifi_canfd_plat_probe(struct platform_device *pdev)
ndev->irq = irq;
ndev->flags |= IFF_ECHO; /* we support local echo */
ndev->netdev_ops = &ifi_canfd_netdev_ops;
ndev->ethtool_ops = &ifi_canfd_ethtool_ops;

priv = netdev_priv(ndev);
priv->ndev = ndev;
Expand Down
6 changes: 6 additions & 0 deletions drivers/net/can/janz-ican3.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/ethtool.h>
#include <linux/platform_device.h>

#include <linux/netdevice.h>
Expand Down Expand Up @@ -1754,6 +1755,10 @@ static const struct net_device_ops ican3_netdev_ops = {
.ndo_change_mtu = can_change_mtu,
};

static const struct ethtool_ops ican3_ethtool_ops = {
.get_ts_info = ethtool_op_get_ts_info,
};

/*
* Low-level CAN Device
*/
Expand Down Expand Up @@ -1925,6 +1930,7 @@ static int ican3_probe(struct platform_device *pdev)
mod->free_page = DPM_FREE_START;

ndev->netdev_ops = &ican3_netdev_ops;
ndev->ethtool_ops = &ican3_ethtool_ops;
ndev->flags |= IFF_ECHO;
SET_NETDEV_DEV(ndev, &pdev->dev);

Expand Down
6 changes: 6 additions & 0 deletions drivers/net/can/m_can/m_can.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
*/

#include <linux/bitfield.h>
#include <linux/ethtool.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/kernel.h>
Expand Down Expand Up @@ -1829,10 +1830,15 @@ static const struct net_device_ops m_can_netdev_ops = {
.ndo_change_mtu = can_change_mtu,
};

static const struct ethtool_ops m_can_ethtool_ops = {
.get_ts_info = ethtool_op_get_ts_info,
};

static int register_m_can_dev(struct net_device *dev)
{
dev->flags |= IFF_ECHO; /* we support local echo */
dev->netdev_ops = &m_can_netdev_ops;
dev->ethtool_ops = &m_can_ethtool_ops;

return register_candev(dev);
}
Expand Down
5 changes: 5 additions & 0 deletions drivers/net/can/mscan/mscan.c
Original file line number Diff line number Diff line change
Expand Up @@ -616,6 +616,10 @@ static const struct net_device_ops mscan_netdev_ops = {
.ndo_change_mtu = can_change_mtu,
};

static const struct ethtool_ops mscan_ethtool_ops = {
.get_ts_info = ethtool_op_get_ts_info,
};

int register_mscandev(struct net_device *dev, int mscan_clksrc)
{
struct mscan_priv *priv = netdev_priv(dev);
Expand Down Expand Up @@ -676,6 +680,7 @@ struct net_device *alloc_mscandev(void)
priv = netdev_priv(dev);

dev->netdev_ops = &mscan_netdev_ops;
dev->ethtool_ops = &mscan_ethtool_ops;

dev->flags |= IFF_ECHO; /* we support local echo */

Expand Down
6 changes: 6 additions & 0 deletions drivers/net/can/pch_can.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/ethtool.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/sched.h>
Expand Down Expand Up @@ -938,6 +939,10 @@ static const struct net_device_ops pch_can_netdev_ops = {
.ndo_change_mtu = can_change_mtu,
};

static const struct ethtool_ops pch_can_ethtool_ops = {
.get_ts_info = ethtool_op_get_ts_info,
};

static void pch_can_remove(struct pci_dev *pdev)
{
struct net_device *ndev = pci_get_drvdata(pdev);
Expand Down Expand Up @@ -1188,6 +1193,7 @@ static int pch_can_probe(struct pci_dev *pdev,
pci_set_drvdata(pdev, ndev);
SET_NETDEV_DEV(ndev, &pdev->dev);
ndev->netdev_ops = &pch_can_netdev_ops;
ndev->ethtool_ops = &pch_can_ethtool_ops;
priv->can.clock.freq = PCH_CAN_CLK; /* Hz */

netif_napi_add_weight(ndev, &priv->napi, pch_can_poll, PCH_RX_OBJ_END);
Expand Down
6 changes: 6 additions & 0 deletions drivers/net/can/rcar/rcar_can.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include <linux/types.h>
#include <linux/interrupt.h>
#include <linux/errno.h>
#include <linux/ethtool.h>
#include <linux/netdevice.h>
#include <linux/platform_device.h>
#include <linux/can/dev.h>
Expand Down Expand Up @@ -630,6 +631,10 @@ static const struct net_device_ops rcar_can_netdev_ops = {
.ndo_change_mtu = can_change_mtu,
};

static const struct ethtool_ops rcar_can_ethtool_ops = {
.get_ts_info = ethtool_op_get_ts_info,
};

static void rcar_can_rx_pkt(struct rcar_can_priv *priv)
{
struct net_device_stats *stats = &priv->ndev->stats;
Expand Down Expand Up @@ -785,6 +790,7 @@ static int rcar_can_probe(struct platform_device *pdev)
}

ndev->netdev_ops = &rcar_can_netdev_ops;
ndev->ethtool_ops = &rcar_can_ethtool_ops;
ndev->irq = irq;
ndev->flags |= IFF_ECHO;
priv->ndev = ndev;
Expand Down
6 changes: 6 additions & 0 deletions drivers/net/can/rcar/rcar_canfd.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include <linux/types.h>
#include <linux/interrupt.h>
#include <linux/errno.h>
#include <linux/ethtool.h>
#include <linux/netdevice.h>
#include <linux/platform_device.h>
#include <linux/can/dev.h>
Expand Down Expand Up @@ -1695,6 +1696,10 @@ static const struct net_device_ops rcar_canfd_netdev_ops = {
.ndo_change_mtu = can_change_mtu,
};

static const struct ethtool_ops rcar_canfd_ethtool_ops = {
.get_ts_info = ethtool_op_get_ts_info,
};

static int rcar_canfd_channel_probe(struct rcar_canfd_global *gpriv, u32 ch,
u32 fcan_freq)
{
Expand All @@ -1711,6 +1716,7 @@ static int rcar_canfd_channel_probe(struct rcar_canfd_global *gpriv, u32 ch,
priv = netdev_priv(ndev);

ndev->netdev_ops = &rcar_canfd_netdev_ops;
ndev->ethtool_ops = &rcar_canfd_ethtool_ops;
ndev->flags |= IFF_ECHO;
priv->ndev = ndev;
priv->base = gpriv->base;
Expand Down
6 changes: 6 additions & 0 deletions drivers/net/can/sja1000/sja1000.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
#include <linux/ptrace.h>
#include <linux/string.h>
#include <linux/errno.h>
#include <linux/ethtool.h>
#include <linux/netdevice.h>
#include <linux/if_arp.h>
#include <linux/if_ether.h>
Expand Down Expand Up @@ -654,6 +655,10 @@ static const struct net_device_ops sja1000_netdev_ops = {
.ndo_change_mtu = can_change_mtu,
};

static const struct ethtool_ops sja1000_ethtool_ops = {
.get_ts_info = ethtool_op_get_ts_info,
};

int register_sja1000dev(struct net_device *dev)
{
int ret;
Expand All @@ -663,6 +668,7 @@ int register_sja1000dev(struct net_device *dev)

dev->flags |= IFF_ECHO; /* we support local echo */
dev->netdev_ops = &sja1000_netdev_ops;
dev->ethtool_ops = &sja1000_ethtool_ops;

set_reset_mode(dev);
chipset_init(dev);
Expand Down
1 change: 1 addition & 0 deletions drivers/net/can/slcan/slcan-ethtool.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,4 +57,5 @@ const struct ethtool_ops slcan_ethtool_ops = {
.get_priv_flags = slcan_get_priv_flags,
.set_priv_flags = slcan_set_priv_flags,
.get_sset_count = slcan_get_sset_count,
.get_ts_info = ethtool_op_get_ts_info,
};
6 changes: 6 additions & 0 deletions drivers/net/can/softing/softing_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
* - Kurt Van Dijck, EIA Electronics
*/

#include <linux/ethtool.h>
#include <linux/module.h>
#include <linux/interrupt.h>
#include <asm/io.h>
Expand Down Expand Up @@ -611,6 +612,10 @@ static const struct net_device_ops softing_netdev_ops = {
.ndo_change_mtu = can_change_mtu,
};

static const struct ethtool_ops softing_ethtool_ops = {
.get_ts_info = ethtool_op_get_ts_info,
};

static const struct can_bittiming_const softing_btr_const = {
.name = KBUILD_MODNAME,
.tseg1_min = 1,
Expand Down Expand Up @@ -649,6 +654,7 @@ static struct net_device *softing_netdev_create(struct softing *card,

netdev->flags |= IFF_ECHO;
netdev->netdev_ops = &softing_netdev_ops;
netdev->ethtool_ops = &softing_ethtool_ops;
priv->can.do_set_mode = softing_candev_set_mode;
priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES;

Expand Down
Loading

0 comments on commit 409c188

Please sign in to comment.