Commit 409c188c authored by Vincent Mailhol's avatar Vincent Mailhol Committed by Marc Kleine-Budde

can: tree-wide: advertise software timestamping capabilities

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: default avatarVincent 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: default avatarMarc Kleine-Budde <mkl@pengutronix.de>
parent 6a37a28b
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/ethtool.h>
#include <linux/if_arp.h> #include <linux/if_arp.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/kernel.h> #include <linux/kernel.h>
...@@ -1152,6 +1153,10 @@ static const struct net_device_ops at91_netdev_ops = { ...@@ -1152,6 +1153,10 @@ static const struct net_device_ops at91_netdev_ops = {
.ndo_change_mtu = can_change_mtu, .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, static ssize_t mb0_id_show(struct device *dev,
struct device_attribute *attr, char *buf) struct device_attribute *attr, char *buf)
{ {
...@@ -1293,6 +1298,7 @@ static int at91_can_probe(struct platform_device *pdev) ...@@ -1293,6 +1298,7 @@ static int at91_can_probe(struct platform_device *pdev)
} }
dev->netdev_ops = &at91_netdev_ops; dev->netdev_ops = &at91_netdev_ops;
dev->ethtool_ops = &at91_ethtool_ops;
dev->irq = irq; dev->irq = irq;
dev->flags |= IFF_ECHO; dev->flags |= IFF_ECHO;
......
...@@ -26,4 +26,5 @@ static void c_can_get_ringparam(struct net_device *netdev, ...@@ -26,4 +26,5 @@ static void c_can_get_ringparam(struct net_device *netdev,
const struct ethtool_ops c_can_ethtool_ops = { const struct ethtool_ops c_can_ethtool_ops = {
.get_ringparam = c_can_get_ringparam, .get_ringparam = c_can_get_ringparam,
.get_ts_info = ethtool_op_get_ts_info,
}; };
...@@ -850,6 +850,10 @@ static const struct net_device_ops can327_netdev_ops = { ...@@ -850,6 +850,10 @@ static const struct net_device_ops can327_netdev_ops = {
.ndo_change_mtu = can_change_mtu, .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 bool can327_is_valid_rx_char(u8 c)
{ {
static const bool lut_char_is_valid['z'] = { static const bool lut_char_is_valid['z'] = {
...@@ -1034,6 +1038,7 @@ static int can327_ldisc_open(struct tty_struct *tty) ...@@ -1034,6 +1038,7 @@ static int can327_ldisc_open(struct tty_struct *tty)
/* Configure netdev interface */ /* Configure netdev interface */
elm->dev = dev; elm->dev = dev;
dev->netdev_ops = &can327_netdev_ops; dev->netdev_ops = &can327_netdev_ops;
dev->ethtool_ops = &can327_ethtool_ops;
/* Mark ldisc channel as alive */ /* Mark ldisc channel as alive */
elm->tty = tty; elm->tty = tty;
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include <linux/ptrace.h> #include <linux/ptrace.h>
#include <linux/string.h> #include <linux/string.h>
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/ethtool.h>
#include <linux/netdevice.h> #include <linux/netdevice.h>
#include <linux/if_arp.h> #include <linux/if_arp.h>
#include <linux/if_ether.h> #include <linux/if_ether.h>
...@@ -836,6 +837,10 @@ static const struct net_device_ops cc770_netdev_ops = { ...@@ -836,6 +837,10 @@ static const struct net_device_ops cc770_netdev_ops = {
.ndo_change_mtu = can_change_mtu, .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) int register_cc770dev(struct net_device *dev)
{ {
struct cc770_priv *priv = netdev_priv(dev); struct cc770_priv *priv = netdev_priv(dev);
...@@ -846,6 +851,7 @@ int register_cc770dev(struct net_device *dev) ...@@ -846,6 +851,7 @@ int register_cc770dev(struct net_device *dev)
return err; return err;
dev->netdev_ops = &cc770_netdev_ops; dev->netdev_ops = &cc770_netdev_ops;
dev->ethtool_ops = &cc770_ethtool_ops;
dev->flags |= IFF_ECHO; /* we support local echo */ dev->flags |= IFF_ECHO; /* we support local echo */
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/ethtool.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/bitfield.h> #include <linux/bitfield.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
...@@ -1301,6 +1302,10 @@ static const struct net_device_ops ctucan_netdev_ops = { ...@@ -1301,6 +1302,10 @@ static const struct net_device_ops ctucan_netdev_ops = {
.ndo_change_mtu = can_change_mtu, .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) int ctucan_suspend(struct device *dev)
{ {
struct net_device *ndev = dev_get_drvdata(dev); struct net_device *ndev = dev_get_drvdata(dev);
...@@ -1377,6 +1382,7 @@ int ctucan_probe_common(struct device *dev, void __iomem *addr, int irq, unsigne ...@@ -1377,6 +1382,7 @@ int ctucan_probe_common(struct device *dev, void __iomem *addr, int irq, unsigne
set_drvdata_fnc(dev, ndev); set_drvdata_fnc(dev, ndev);
SET_NETDEV_DEV(ndev, dev); SET_NETDEV_DEV(ndev, dev);
ndev->netdev_ops = &ctucan_netdev_ops; ndev->netdev_ops = &ctucan_netdev_ops;
ndev->ethtool_ops = &ctucan_ethtool_ops;
/* Getting the can_clk info */ /* Getting the can_clk info */
if (!can_clk_rate) { if (!can_clk_rate) {
......
...@@ -106,4 +106,5 @@ const struct ethtool_ops flexcan_ethtool_ops = { ...@@ -106,4 +106,5 @@ const struct ethtool_ops flexcan_ethtool_ops = {
.get_priv_flags = flexcan_get_priv_flags, .get_priv_flags = flexcan_get_priv_flags,
.set_priv_flags = flexcan_set_priv_flags, .set_priv_flags = flexcan_set_priv_flags,
.get_sset_count = flexcan_get_sset_count, .get_sset_count = flexcan_get_sset_count,
.get_ts_info = ethtool_op_get_ts_info,
}; };
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/netdevice.h> #include <linux/netdevice.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/ethtool.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/can/dev.h> #include <linux/can/dev.h>
#include <linux/spinlock.h> #include <linux/spinlock.h>
...@@ -1561,6 +1562,10 @@ static const struct net_device_ops grcan_netdev_ops = { ...@@ -1561,6 +1562,10 @@ static const struct net_device_ops grcan_netdev_ops = {
.ndo_change_mtu = can_change_mtu, .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, static int grcan_setup_netdev(struct platform_device *ofdev,
void __iomem *base, void __iomem *base,
int irq, u32 ambafreq, bool txbug) int irq, u32 ambafreq, bool txbug)
...@@ -1577,6 +1582,7 @@ static int grcan_setup_netdev(struct platform_device *ofdev, ...@@ -1577,6 +1582,7 @@ static int grcan_setup_netdev(struct platform_device *ofdev,
dev->irq = irq; dev->irq = irq;
dev->flags |= IFF_ECHO; dev->flags |= IFF_ECHO;
dev->netdev_ops = &grcan_netdev_ops; dev->netdev_ops = &grcan_netdev_ops;
dev->ethtool_ops = &grcan_ethtool_ops;
dev->sysfs_groups[0] = &sysfs_grcan_group; dev->sysfs_groups[0] = &sysfs_grcan_group;
priv = netdev_priv(dev); priv = netdev_priv(dev);
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/ethtool.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/kernel.h> #include <linux/kernel.h>
...@@ -925,6 +926,10 @@ static const struct net_device_ops ifi_canfd_netdev_ops = { ...@@ -925,6 +926,10 @@ static const struct net_device_ops ifi_canfd_netdev_ops = {
.ndo_change_mtu = can_change_mtu, .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) static int ifi_canfd_plat_probe(struct platform_device *pdev)
{ {
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
...@@ -962,6 +967,7 @@ static int ifi_canfd_plat_probe(struct platform_device *pdev) ...@@ -962,6 +967,7 @@ static int ifi_canfd_plat_probe(struct platform_device *pdev)
ndev->irq = irq; ndev->irq = irq;
ndev->flags |= IFF_ECHO; /* we support local echo */ ndev->flags |= IFF_ECHO; /* we support local echo */
ndev->netdev_ops = &ifi_canfd_netdev_ops; ndev->netdev_ops = &ifi_canfd_netdev_ops;
ndev->ethtool_ops = &ifi_canfd_ethtool_ops;
priv = netdev_priv(ndev); priv = netdev_priv(ndev);
priv->ndev = ndev; priv->ndev = ndev;
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/ethtool.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/netdevice.h> #include <linux/netdevice.h>
...@@ -1754,6 +1755,10 @@ static const struct net_device_ops ican3_netdev_ops = { ...@@ -1754,6 +1755,10 @@ static const struct net_device_ops ican3_netdev_ops = {
.ndo_change_mtu = can_change_mtu, .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 * Low-level CAN Device
*/ */
...@@ -1925,6 +1930,7 @@ static int ican3_probe(struct platform_device *pdev) ...@@ -1925,6 +1930,7 @@ static int ican3_probe(struct platform_device *pdev)
mod->free_page = DPM_FREE_START; mod->free_page = DPM_FREE_START;
ndev->netdev_ops = &ican3_netdev_ops; ndev->netdev_ops = &ican3_netdev_ops;
ndev->ethtool_ops = &ican3_ethtool_ops;
ndev->flags |= IFF_ECHO; ndev->flags |= IFF_ECHO;
SET_NETDEV_DEV(ndev, &pdev->dev); SET_NETDEV_DEV(ndev, &pdev->dev);
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
*/ */
#include <linux/bitfield.h> #include <linux/bitfield.h>
#include <linux/ethtool.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/kernel.h> #include <linux/kernel.h>
...@@ -1829,10 +1830,15 @@ static const struct net_device_ops m_can_netdev_ops = { ...@@ -1829,10 +1830,15 @@ static const struct net_device_ops m_can_netdev_ops = {
.ndo_change_mtu = can_change_mtu, .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) static int register_m_can_dev(struct net_device *dev)
{ {
dev->flags |= IFF_ECHO; /* we support local echo */ dev->flags |= IFF_ECHO; /* we support local echo */
dev->netdev_ops = &m_can_netdev_ops; dev->netdev_ops = &m_can_netdev_ops;
dev->ethtool_ops = &m_can_ethtool_ops;
return register_candev(dev); return register_candev(dev);
} }
......
...@@ -616,6 +616,10 @@ static const struct net_device_ops mscan_netdev_ops = { ...@@ -616,6 +616,10 @@ static const struct net_device_ops mscan_netdev_ops = {
.ndo_change_mtu = can_change_mtu, .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) int register_mscandev(struct net_device *dev, int mscan_clksrc)
{ {
struct mscan_priv *priv = netdev_priv(dev); struct mscan_priv *priv = netdev_priv(dev);
...@@ -676,6 +680,7 @@ struct net_device *alloc_mscandev(void) ...@@ -676,6 +680,7 @@ struct net_device *alloc_mscandev(void)
priv = netdev_priv(dev); priv = netdev_priv(dev);
dev->netdev_ops = &mscan_netdev_ops; dev->netdev_ops = &mscan_netdev_ops;
dev->ethtool_ops = &mscan_ethtool_ops;
dev->flags |= IFF_ECHO; /* we support local echo */ dev->flags |= IFF_ECHO; /* we support local echo */
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/ethtool.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/sched.h> #include <linux/sched.h>
...@@ -938,6 +939,10 @@ static const struct net_device_ops pch_can_netdev_ops = { ...@@ -938,6 +939,10 @@ static const struct net_device_ops pch_can_netdev_ops = {
.ndo_change_mtu = can_change_mtu, .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) static void pch_can_remove(struct pci_dev *pdev)
{ {
struct net_device *ndev = pci_get_drvdata(pdev); struct net_device *ndev = pci_get_drvdata(pdev);
...@@ -1188,6 +1193,7 @@ static int pch_can_probe(struct pci_dev *pdev, ...@@ -1188,6 +1193,7 @@ static int pch_can_probe(struct pci_dev *pdev,
pci_set_drvdata(pdev, ndev); pci_set_drvdata(pdev, ndev);
SET_NETDEV_DEV(ndev, &pdev->dev); SET_NETDEV_DEV(ndev, &pdev->dev);
ndev->netdev_ops = &pch_can_netdev_ops; ndev->netdev_ops = &pch_can_netdev_ops;
ndev->ethtool_ops = &pch_can_ethtool_ops;
priv->can.clock.freq = PCH_CAN_CLK; /* Hz */ priv->can.clock.freq = PCH_CAN_CLK; /* Hz */
netif_napi_add_weight(ndev, &priv->napi, pch_can_poll, PCH_RX_OBJ_END); netif_napi_add_weight(ndev, &priv->napi, pch_can_poll, PCH_RX_OBJ_END);
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include <linux/types.h> #include <linux/types.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/ethtool.h>
#include <linux/netdevice.h> #include <linux/netdevice.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/can/dev.h> #include <linux/can/dev.h>
...@@ -630,6 +631,10 @@ static const struct net_device_ops rcar_can_netdev_ops = { ...@@ -630,6 +631,10 @@ static const struct net_device_ops rcar_can_netdev_ops = {
.ndo_change_mtu = can_change_mtu, .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) static void rcar_can_rx_pkt(struct rcar_can_priv *priv)
{ {
struct net_device_stats *stats = &priv->ndev->stats; struct net_device_stats *stats = &priv->ndev->stats;
...@@ -785,6 +790,7 @@ static int rcar_can_probe(struct platform_device *pdev) ...@@ -785,6 +790,7 @@ static int rcar_can_probe(struct platform_device *pdev)
} }
ndev->netdev_ops = &rcar_can_netdev_ops; ndev->netdev_ops = &rcar_can_netdev_ops;
ndev->ethtool_ops = &rcar_can_ethtool_ops;
ndev->irq = irq; ndev->irq = irq;
ndev->flags |= IFF_ECHO; ndev->flags |= IFF_ECHO;
priv->ndev = ndev; priv->ndev = ndev;
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include <linux/types.h> #include <linux/types.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/ethtool.h>
#include <linux/netdevice.h> #include <linux/netdevice.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/can/dev.h> #include <linux/can/dev.h>
...@@ -1695,6 +1696,10 @@ static const struct net_device_ops rcar_canfd_netdev_ops = { ...@@ -1695,6 +1696,10 @@ static const struct net_device_ops rcar_canfd_netdev_ops = {
.ndo_change_mtu = can_change_mtu, .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, static int rcar_canfd_channel_probe(struct rcar_canfd_global *gpriv, u32 ch,
u32 fcan_freq) u32 fcan_freq)
{ {
...@@ -1711,6 +1716,7 @@ static int rcar_canfd_channel_probe(struct rcar_canfd_global *gpriv, u32 ch, ...@@ -1711,6 +1716,7 @@ static int rcar_canfd_channel_probe(struct rcar_canfd_global *gpriv, u32 ch,
priv = netdev_priv(ndev); priv = netdev_priv(ndev);
ndev->netdev_ops = &rcar_canfd_netdev_ops; ndev->netdev_ops = &rcar_canfd_netdev_ops;
ndev->ethtool_ops = &rcar_canfd_ethtool_ops;
ndev->flags |= IFF_ECHO; ndev->flags |= IFF_ECHO;
priv->ndev = ndev; priv->ndev = ndev;
priv->base = gpriv->base; priv->base = gpriv->base;
......
...@@ -52,6 +52,7 @@ ...@@ -52,6 +52,7 @@
#include <linux/ptrace.h> #include <linux/ptrace.h>
#include <linux/string.h> #include <linux/string.h>
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/ethtool.h>
#include <linux/netdevice.h> #include <linux/netdevice.h>
#include <linux/if_arp.h> #include <linux/if_arp.h>
#include <linux/if_ether.h> #include <linux/if_ether.h>
...@@ -654,6 +655,10 @@ static const struct net_device_ops sja1000_netdev_ops = { ...@@ -654,6 +655,10 @@ static const struct net_device_ops sja1000_netdev_ops = {
.ndo_change_mtu = can_change_mtu, .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 register_sja1000dev(struct net_device *dev)
{ {
int ret; int ret;
...@@ -663,6 +668,7 @@ int register_sja1000dev(struct net_device *dev) ...@@ -663,6 +668,7 @@ int register_sja1000dev(struct net_device *dev)
dev->flags |= IFF_ECHO; /* we support local echo */ dev->flags |= IFF_ECHO; /* we support local echo */
dev->netdev_ops = &sja1000_netdev_ops; dev->netdev_ops = &sja1000_netdev_ops;
dev->ethtool_ops = &sja1000_ethtool_ops;
set_reset_mode(dev); set_reset_mode(dev);
chipset_init(dev); chipset_init(dev);
......
...@@ -57,4 +57,5 @@ const struct ethtool_ops slcan_ethtool_ops = { ...@@ -57,4 +57,5 @@ const struct ethtool_ops slcan_ethtool_ops = {
.get_priv_flags = slcan_get_priv_flags, .get_priv_flags = slcan_get_priv_flags,
.set_priv_flags = slcan_set_priv_flags, .set_priv_flags = slcan_set_priv_flags,
.get_sset_count = slcan_get_sset_count, .get_sset_count = slcan_get_sset_count,
.get_ts_info = ethtool_op_get_ts_info,
}; };
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
* - Kurt Van Dijck, EIA Electronics * - Kurt Van Dijck, EIA Electronics
*/ */
#include <linux/ethtool.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <asm/io.h> #include <asm/io.h>
...@@ -611,6 +612,10 @@ static const struct net_device_ops softing_netdev_ops = { ...@@ -611,6 +612,10 @@ static const struct net_device_ops softing_netdev_ops = {
.ndo_change_mtu = can_change_mtu, .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 = { static const struct can_bittiming_const softing_btr_const = {
.name = KBUILD_MODNAME, .name = KBUILD_MODNAME,
.tseg1_min = 1, .tseg1_min = 1,
...@@ -649,6 +654,7 @@ static struct net_device *softing_netdev_create(struct softing *card, ...@@ -649,6 +654,7 @@ static struct net_device *softing_netdev_create(struct softing *card,
netdev->flags |= IFF_ECHO; netdev->flags |= IFF_ECHO;
netdev->netdev_ops = &softing_netdev_ops; netdev->netdev_ops = &softing_netdev_ops;
netdev->ethtool_ops = &softing_ethtool_ops;
priv->can.do_set_mode = softing_candev_set_mode; priv->can.do_set_mode = softing_candev_set_mode;
priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES; priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES;
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include <linux/completion.h> #include <linux/completion.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/device.h> #include <linux/device.h>
#include <linux/ethtool.h>
#include <linux/freezer.h> #include <linux/freezer.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/io.h> #include <linux/io.h>
...@@ -802,6 +803,10 @@ static const struct net_device_ops hi3110_netdev_ops = { ...@@ -802,6 +803,10 @@ static const struct net_device_ops hi3110_netdev_ops = {
.ndo_start_xmit = hi3110_hard_start_xmit, .ndo_start_xmit = hi3110_hard_start_xmit,
}; };
static const struct ethtool_ops hi3110_ethtool_ops = {
.get_ts_info = ethtool_op_get_ts_info,
};
static const struct of_device_id hi3110_of_match[] = { static const struct of_device_id hi3110_of_match[] = {
{ {
.compatible = "holt,hi3110", .compatible = "holt,hi3110",
...@@ -856,6 +861,7 @@ static int hi3110_can_probe(struct spi_device *spi) ...@@ -856,6 +861,7 @@ static int hi3110_can_probe(struct spi_device *spi)
goto out_free; goto out_free;
net->netdev_ops = &hi3110_netdev_ops; net->netdev_ops = &hi3110_netdev_ops;
net->ethtool_ops = &hi3110_ethtool_ops;
net->flags |= IFF_ECHO; net->flags |= IFF_ECHO;
priv = netdev_priv(net); priv = netdev_priv(net);
......
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
#include <linux/completion.h> #include <linux/completion.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/device.h> #include <linux/device.h>
#include <linux/ethtool.h>
#include <linux/freezer.h> #include <linux/freezer.h>
#include <linux/gpio.h> #include <linux/gpio.h>
#include <linux/gpio/driver.h> #include <linux/gpio/driver.h>
...@@ -1248,6 +1249,10 @@ static const struct net_device_ops mcp251x_netdev_ops = { ...@@ -1248,6 +1249,10 @@ static const struct net_device_ops mcp251x_netdev_ops = {
.ndo_change_mtu = can_change_mtu, .ndo_change_mtu = can_change_mtu,
}; };
static const struct ethtool_ops mcp251x_ethtool_ops = {
.get_ts_info = ethtool_op_get_ts_info,
};
static const struct of_device_id mcp251x_of_match[] = { static const struct of_device_id mcp251x_of_match[] = {
{ {
.compatible = "microchip,mcp2510", .compatible = "microchip,mcp2510",
...@@ -1313,6 +1318,7 @@ static int mcp251x_can_probe(struct spi_device *spi) ...@@ -1313,6 +1318,7 @@ static int mcp251x_can_probe(struct spi_device *spi)
goto out_free; goto out_free;
net->netdev_ops = &mcp251x_netdev_ops; net->netdev_ops = &mcp251x_netdev_ops;
net->ethtool_ops = &mcp251x_ethtool_ops;
net->flags |= IFF_ECHO; net->flags |= IFF_ECHO;
priv = netdev_priv(net); priv = netdev_priv(net);
......
...@@ -53,6 +53,7 @@ ...@@ -53,6 +53,7 @@
#include <linux/can/error.h> #include <linux/can/error.h>
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/ethtool.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/io.h> #include <linux/io.h>
...@@ -761,6 +762,10 @@ static const struct net_device_ops sun4ican_netdev_ops = { ...@@ -761,6 +762,10 @@ static const struct net_device_ops sun4ican_netdev_ops = {
.ndo_start_xmit = sun4ican_start_xmit, .ndo_start_xmit = sun4ican_start_xmit,
}; };
static const struct ethtool_ops sun4ican_ethtool_ops = {
.get_ts_info = ethtool_op_get_ts_info,
};
static const struct sun4ican_quirks sun4ican_quirks_a10 = { static const struct sun4ican_quirks sun4ican_quirks_a10 = {
.has_reset = false, .has_reset = false,
}; };
...@@ -851,6 +856,7 @@ static int sun4ican_probe(struct platform_device *pdev) ...@@ -851,6 +856,7 @@ static int sun4ican_probe(struct platform_device *pdev)
} }
dev->netdev_ops = &sun4ican_netdev_ops; dev->netdev_ops = &sun4ican_netdev_ops;
dev->ethtool_ops = &sun4ican_ethtool_ops;
dev->irq = irq; dev->irq = irq;
dev->flags |= IFF_ECHO; dev->flags |= IFF_ECHO;
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#include <linux/types.h> #include <linux/types.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/ethtool.h>
#include <linux/netdevice.h> #include <linux/netdevice.h>
#include <linux/skbuff.h> #include <linux/skbuff.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
...@@ -841,6 +842,10 @@ static const struct net_device_ops ti_hecc_netdev_ops = { ...@@ -841,6 +842,10 @@ static const struct net_device_ops ti_hecc_netdev_ops = {
.ndo_change_mtu = can_change_mtu, .ndo_change_mtu = can_change_mtu,
}; };
static const struct ethtool_ops ti_hecc_ethtool_ops = {
.get_ts_info = ethtool_op_get_ts_info,
};
static const struct of_device_id ti_hecc_dt_ids[] = { static const struct of_device_id ti_hecc_dt_ids[] = {
{ {
.compatible = "ti,am3517-hecc", .compatible = "ti,am3517-hecc",
...@@ -918,6 +923,7 @@ static int ti_hecc_probe(struct platform_device *pdev) ...@@ -918,6 +923,7 @@ static int ti_hecc_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, ndev); platform_set_drvdata(pdev, ndev);
SET_NETDEV_DEV(ndev, &pdev->dev); SET_NETDEV_DEV(ndev, &pdev->dev);
ndev->netdev_ops = &ti_hecc_netdev_ops; ndev->netdev_ops = &ti_hecc_netdev_ops;
ndev->ethtool_ops = &ti_hecc_ethtool_ops;
priv->clk = clk_get(&pdev->dev, "hecc_ck"); priv->clk = clk_get(&pdev->dev, "hecc_ck");
if (IS_ERR(priv->clk)) { if (IS_ERR(priv->clk)) {
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
* *
* Copyright (C) 2004-2009 EMS Dr. Thomas Wuensche * Copyright (C) 2004-2009 EMS Dr. Thomas Wuensche
*/ */
#include <linux/ethtool.h>
#include <linux/signal.h> #include <linux/signal.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/module.h> #include <linux/module.h>
...@@ -879,6 +880,10 @@ static const struct net_device_ops ems_usb_netdev_ops = { ...@@ -879,6 +880,10 @@ static const struct net_device_ops ems_usb_netdev_ops = {
.ndo_change_mtu = can_change_mtu, .ndo_change_mtu = can_change_mtu,
}; };
static const struct ethtool_ops ems_usb_ethtool_ops = {
.get_ts_info = ethtool_op_get_ts_info,
};
static const struct can_bittiming_const ems_usb_bittiming_const = { static const struct can_bittiming_const ems_usb_bittiming_const = {
.name = KBUILD_MODNAME, .name = KBUILD_MODNAME,
.tseg1_min = 1, .tseg1_min = 1,
...@@ -990,6 +995,7 @@ static int ems_usb_probe(struct usb_interface *intf, ...@@ -990,6 +995,7 @@ static int ems_usb_probe(struct usb_interface *intf,
dev->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES; dev->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES;
netdev->netdev_ops = &ems_usb_netdev_ops; netdev->netdev_ops = &ems_usb_netdev_ops;
netdev->ethtool_ops = &ems_usb_ethtool_ops;
netdev->flags |= IFF_ECHO; /* we support local echo */ netdev->flags |= IFF_ECHO; /* we support local echo */
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
* Copyright (C) 2010-2012 esd electronic system design gmbh, Matthias Fuchs <socketcan@esd.eu> * Copyright (C) 2010-2012 esd electronic system design gmbh, Matthias Fuchs <socketcan@esd.eu>
* Copyright (C) 2022 esd electronics gmbh, Frank Jungclaus <frank.jungclaus@esd.eu> * Copyright (C) 2022 esd electronics gmbh, Frank Jungclaus <frank.jungclaus@esd.eu>
*/ */
#include <linux/ethtool.h>
#include <linux/signal.h> #include <linux/signal.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/module.h> #include <linux/module.h>
...@@ -882,6 +883,10 @@ static const struct net_device_ops esd_usb_netdev_ops = { ...@@ -882,6 +883,10 @@ static const struct net_device_ops esd_usb_netdev_ops = {
.ndo_change_mtu = can_change_mtu, .ndo_change_mtu = can_change_mtu,
}; };
static const struct ethtool_ops esd_usb_ethtool_ops = {
.get_ts_info = ethtool_op_get_ts_info,
};
static const struct can_bittiming_const esd_usb2_bittiming_const = { static const struct can_bittiming_const esd_usb2_bittiming_const = {
.name = "esd_usb2", .name = "esd_usb2",
.tseg1_min = ESD_USB2_TSEG1_MIN, .tseg1_min = ESD_USB2_TSEG1_MIN,
...@@ -1015,6 +1020,7 @@ static int esd_usb_probe_one_net(struct usb_interface *intf, int index) ...@@ -1015,6 +1020,7 @@ static int esd_usb_probe_one_net(struct usb_interface *intf, int index)
netdev->flags |= IFF_ECHO; /* we support local echo */ netdev->flags |= IFF_ECHO; /* we support local echo */
netdev->netdev_ops = &esd_usb_netdev_ops; netdev->netdev_ops = &esd_usb_netdev_ops;
netdev->ethtool_ops = &esd_usb_ethtool_ops;
SET_NETDEV_DEV(netdev, &intf->dev); SET_NETDEV_DEV(netdev, &intf->dev);
netdev->dev_id = index; netdev->dev_id = index;
......
...@@ -946,6 +946,7 @@ static int gs_usb_set_phys_id(struct net_device *dev, ...@@ -946,6 +946,7 @@ static int gs_usb_set_phys_id(struct net_device *dev,
static const struct ethtool_ops gs_usb_ethtool_ops = { static const struct ethtool_ops gs_usb_ethtool_ops = {
.set_phys_id = gs_usb_set_phys_id, .set_phys_id = gs_usb_set_phys_id,
.get_ts_info = ethtool_op_get_ts_info,
}; };
static struct gs_can *gs_make_candev(unsigned int channel, static struct gs_can *gs_make_candev(unsigned int channel,
...@@ -989,6 +990,7 @@ static struct gs_can *gs_make_candev(unsigned int channel, ...@@ -989,6 +990,7 @@ static struct gs_can *gs_make_candev(unsigned int channel,
dev = netdev_priv(netdev); dev = netdev_priv(netdev);
netdev->netdev_ops = &gs_usb_netdev_ops; netdev->netdev_ops = &gs_usb_netdev_ops;
netdev->ethtool_ops = &gs_usb_ethtool_ops;
netdev->flags |= IFF_ECHO; /* we support full roundtrip echo */ netdev->flags |= IFF_ECHO; /* we support full roundtrip echo */
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include <linux/can.h> #include <linux/can.h>
#include <linux/can/dev.h> #include <linux/can/dev.h>
#include <linux/can/error.h> #include <linux/can/error.h>
#include <linux/ethtool.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/netdevice.h> #include <linux/netdevice.h>
#include <linux/signal.h> #include <linux/signal.h>
...@@ -758,6 +759,10 @@ static const struct net_device_ops mcba_netdev_ops = { ...@@ -758,6 +759,10 @@ static const struct net_device_ops mcba_netdev_ops = {
.ndo_start_xmit = mcba_usb_start_xmit, .ndo_start_xmit = mcba_usb_start_xmit,
}; };
static const struct ethtool_ops mcba_ethtool_ops = {
.get_ts_info = ethtool_op_get_ts_info,
};
/* Microchip CANBUS has hardcoded bittiming values by default. /* Microchip CANBUS has hardcoded bittiming values by default.
* This function sends request via USB to change the speed and align bittiming * This function sends request via USB to change the speed and align bittiming
* values for presentation purposes only * values for presentation purposes only
...@@ -836,6 +841,7 @@ static int mcba_usb_probe(struct usb_interface *intf, ...@@ -836,6 +841,7 @@ static int mcba_usb_probe(struct usb_interface *intf,
priv->can.do_set_bittiming = mcba_net_set_bittiming; priv->can.do_set_bittiming = mcba_net_set_bittiming;
netdev->netdev_ops = &mcba_netdev_ops; netdev->netdev_ops = &mcba_netdev_ops;
netdev->ethtool_ops = &mcba_ethtool_ops;
netdev->flags |= IFF_ECHO; /* we support local echo */ netdev->flags |= IFF_ECHO; /* we support local echo */
......
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#include <linux/can.h> #include <linux/can.h>
#include <linux/can/dev.h> #include <linux/can/dev.h>
#include <linux/can/error.h> #include <linux/can/error.h>
#include <linux/ethtool.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/netdevice.h> #include <linux/netdevice.h>
#include <linux/signal.h> #include <linux/signal.h>
...@@ -1233,6 +1234,10 @@ static const struct net_device_ops ucan_netdev_ops = { ...@@ -1233,6 +1234,10 @@ static const struct net_device_ops ucan_netdev_ops = {
.ndo_change_mtu = can_change_mtu, .ndo_change_mtu = can_change_mtu,
}; };
static const struct ethtool_ops ucan_ethtool_ops = {
.get_ts_info = ethtool_op_get_ts_info,
};
/* Request to set bittiming /* Request to set bittiming
* *
* This function generates an USB set bittiming message and transmits * This function generates an USB set bittiming message and transmits
...@@ -1512,6 +1517,7 @@ static int ucan_probe(struct usb_interface *intf, ...@@ -1512,6 +1517,7 @@ static int ucan_probe(struct usb_interface *intf,
spin_lock_init(&up->context_lock); spin_lock_init(&up->context_lock);
spin_lock_init(&up->echo_skb_lock); spin_lock_init(&up->echo_skb_lock);
netdev->netdev_ops = &ucan_netdev_ops; netdev->netdev_ops = &ucan_netdev_ops;
netdev->ethtool_ops = &ucan_ethtool_ops;
usb_set_intfdata(intf, up); usb_set_intfdata(intf, up);
SET_NETDEV_DEV(netdev, &intf->dev); SET_NETDEV_DEV(netdev, &intf->dev);
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
* who were very cooperative and answered my questions. * who were very cooperative and answered my questions.
*/ */
#include <linux/ethtool.h>
#include <linux/signal.h> #include <linux/signal.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/module.h> #include <linux/module.h>
...@@ -870,6 +871,10 @@ static const struct net_device_ops usb_8dev_netdev_ops = { ...@@ -870,6 +871,10 @@ static const struct net_device_ops usb_8dev_netdev_ops = {
.ndo_change_mtu = can_change_mtu, .ndo_change_mtu = can_change_mtu,
}; };
static const struct ethtool_ops usb_8dev_ethtool_ops = {
.get_ts_info = ethtool_op_get_ts_info,
};
static const struct can_bittiming_const usb_8dev_bittiming_const = { static const struct can_bittiming_const usb_8dev_bittiming_const = {
.name = KBUILD_MODNAME, .name = KBUILD_MODNAME,
.tseg1_min = 1, .tseg1_min = 1,
...@@ -927,6 +932,7 @@ static int usb_8dev_probe(struct usb_interface *intf, ...@@ -927,6 +932,7 @@ static int usb_8dev_probe(struct usb_interface *intf,
CAN_CTRLMODE_CC_LEN8_DLC; CAN_CTRLMODE_CC_LEN8_DLC;
netdev->netdev_ops = &usb_8dev_netdev_ops; netdev->netdev_ops = &usb_8dev_netdev_ops;
netdev->ethtool_ops = &usb_8dev_ethtool_ops;
netdev->flags |= IFF_ECHO; /* we support local echo */ netdev->flags |= IFF_ECHO; /* we support local echo */
......
...@@ -40,6 +40,7 @@ ...@@ -40,6 +40,7 @@
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/ethtool.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/netdevice.h> #include <linux/netdevice.h>
...@@ -148,6 +149,10 @@ static const struct net_device_ops vcan_netdev_ops = { ...@@ -148,6 +149,10 @@ static const struct net_device_ops vcan_netdev_ops = {
.ndo_change_mtu = vcan_change_mtu, .ndo_change_mtu = vcan_change_mtu,
}; };
static const struct ethtool_ops vcan_ethtool_ops = {
.get_ts_info = ethtool_op_get_ts_info,
};
static void vcan_setup(struct net_device *dev) static void vcan_setup(struct net_device *dev)
{ {
dev->type = ARPHRD_CAN; dev->type = ARPHRD_CAN;
...@@ -163,6 +168,7 @@ static void vcan_setup(struct net_device *dev) ...@@ -163,6 +168,7 @@ static void vcan_setup(struct net_device *dev)
dev->flags |= IFF_ECHO; dev->flags |= IFF_ECHO;
dev->netdev_ops = &vcan_netdev_ops; dev->netdev_ops = &vcan_netdev_ops;
dev->ethtool_ops = &vcan_ethtool_ops;
dev->needs_free_netdev = true; dev->needs_free_netdev = true;
} }
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
* Copyright (c) 2017 Oliver Hartkopp <socketcan@hartkopp.net> * Copyright (c) 2017 Oliver Hartkopp <socketcan@hartkopp.net>
*/ */
#include <linux/ethtool.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/netdevice.h> #include <linux/netdevice.h>
...@@ -146,6 +147,10 @@ static const struct net_device_ops vxcan_netdev_ops = { ...@@ -146,6 +147,10 @@ static const struct net_device_ops vxcan_netdev_ops = {
.ndo_change_mtu = vxcan_change_mtu, .ndo_change_mtu = vxcan_change_mtu,
}; };
static const struct ethtool_ops vxcan_ethtool_ops = {
.get_ts_info = ethtool_op_get_ts_info,
};
static void vxcan_setup(struct net_device *dev) static void vxcan_setup(struct net_device *dev)
{ {
struct can_ml_priv *can_ml; struct can_ml_priv *can_ml;
...@@ -157,6 +162,7 @@ static void vxcan_setup(struct net_device *dev) ...@@ -157,6 +162,7 @@ static void vxcan_setup(struct net_device *dev)
dev->tx_queue_len = 0; dev->tx_queue_len = 0;
dev->flags = IFF_NOARP; dev->flags = IFF_NOARP;
dev->netdev_ops = &vxcan_netdev_ops; dev->netdev_ops = &vxcan_netdev_ops;
dev->ethtool_ops = &vxcan_ethtool_ops;
dev->needs_free_netdev = true; dev->needs_free_netdev = true;
can_ml = netdev_priv(dev) + ALIGN(sizeof(struct vxcan_priv), NETDEV_ALIGN); can_ml = netdev_priv(dev) + ALIGN(sizeof(struct vxcan_priv), NETDEV_ALIGN);
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include <linux/bitfield.h> #include <linux/bitfield.h>
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/ethtool.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/io.h> #include <linux/io.h>
...@@ -1540,6 +1541,10 @@ static const struct net_device_ops xcan_netdev_ops = { ...@@ -1540,6 +1541,10 @@ static const struct net_device_ops xcan_netdev_ops = {
.ndo_change_mtu = can_change_mtu, .ndo_change_mtu = can_change_mtu,
}; };
static const struct ethtool_ops xcan_ethtool_ops = {
.get_ts_info = ethtool_op_get_ts_info,
};
/** /**
* xcan_suspend - Suspend method for the driver * xcan_suspend - Suspend method for the driver
* @dev: Address of the device structure * @dev: Address of the device structure
...@@ -1821,6 +1826,7 @@ static int xcan_probe(struct platform_device *pdev) ...@@ -1821,6 +1826,7 @@ static int xcan_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, ndev); platform_set_drvdata(pdev, ndev);
SET_NETDEV_DEV(ndev, &pdev->dev); SET_NETDEV_DEV(ndev, &pdev->dev);
ndev->netdev_ops = &xcan_netdev_ops; ndev->netdev_ops = &xcan_netdev_ops;
ndev->ethtool_ops = &xcan_ethtool_ops;
/* Getting the CAN can_clk info */ /* Getting the CAN can_clk info */
priv->can_clk = devm_clk_get(&pdev->dev, "can_clk"); priv->can_clk = devm_clk_get(&pdev->dev, "can_clk");
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment