All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v1 00/24] can: add ethtool support and reporting of timestamping capabilities
@ 2022-07-25 13:31 Vincent Mailhol
  2022-07-25 13:31 ` [PATCH v1 01/24] can: can327: use KBUILD_MODNAME instead of hard coded name Vincent Mailhol
                   ` (27 more replies)
  0 siblings, 28 replies; 92+ messages in thread
From: Vincent Mailhol @ 2022-07-25 13:31 UTC (permalink / raw)
  To: linux-can, Marc Kleine-Budde
  Cc: Stephane Grosjean, Jimmy Assarsson, Oliver Hartkopp,
	Dario Binacchi, Max Staudt, Vincent Mailhol

This series revolves around ethtool and timestamping. Its ultimate
goal is that the timestamping implementation within socketCAN meets
the specification of other network drivers in the kernel. This way,
tcpdump or other tools derived from libpcap can be used to do
timestamping on CAN devices.

*Example on a device with hardware timestamp support *

Before this series:
| # tcpdump -j adapter_unsynced -i can0
| tcpdump: WARNING: When trying to set timestamp type
| 'adapter_unsynced' on can0: That type of time stamp is not supported
| by that device

After applying this series, the warning disappears and tcpdump can be
used to get RX hardware timestamps.


This series is articulated in five major parts.

* Part 1: Report driver information through ethtool

This first part implements ethtool_ops::get_drvinfo() for all
drivers. The actual change is made in the 10th patch. The patches 1 to
8 get rid of any hardcoded string and instead relies on either
KBUILD_MODNAME or DRV_NAME macros to get the device name. Patch 9
removes the DRV_VERSION macro so that ethtool can instead rely on the
kernel version.


* Part 2: Add TX software timestamps and report the software
  timestamping capabilities through ethtool.

All the drivers using can_put_echo_skb() already support TX software
timestamps. However, the five drivers not using this function (namely
can327, janz-ican3, slcan, vcan and vxcan) lack such support. Patch 11
to 14 adds this support.  Finally, patch 15 advertises the timesamping
capabilities of all drivers not support hardware timestamps.

* Part 3: add TX hardware timestapms

This part is a single patch. In SocetCAN TX hardware is equal to the
RX hardware timestamps of the corresponding loopback frame. Reuse the
TX hardware timestamp to populate the RX hardware timestamp. While the
need of this feature can be debatable, we implement it here so that
generic timestamping tools which are agnostic of the specificity of
SocketCAN can still obtain the value. For example, tcpdump expects for
both TX and RX hardware timestamps to be supported in order to do:
| # tcpdump -j adapter_unsynced -i canX

* Part 4: report the hardware timestamping capabilities and implement
  the hardware timestamps ioctls.

The kernel documentation specifies in [1] that, for the drivers which
support hardware timestamping, SIOCSHWTSTAMP ioctl must be supported
and that SIOCGHWTSTAMP ioctl should be supported. Currently, none of
the CAN drivers do so. This is a gap.

Furthermore, even if not specified, the tools based on libpcap
(e.g. tcpdump) also expect ethtool_ops::get_ts_info to be implemented.

This last part first adds some generic implementation of
net_device_ops::ndo_eth_ioctl and ethtool_ops::get_ts_info which can
be used by the drivers with hardware timestamping capabilities.

It then uses those generic functions to add ioctl and reporting
functionalities to the drivers with hardware timestamping support
(namely: mcp251xfd, etas_es58x, kvaser_{pciefd,usb}, peak_{canfd,usb})


[1] Kernel doc: Timestamping, section 3.1 "Hardware Timestamping
Implementation: Device Drivers"
Link: https://docs.kernel.org/networking/timestamping.html#hardware-timestamping-implementation-device-drivers

Vincent Mailhol (24):
  can: can327: use KBUILD_MODNAME instead of hard coded name
  can: ems_ubs: use KBUILD_MODNAME instead of hard coded name
  can: slcan: add DRV_NAME and define pr_fmt to replace hardcoded names
  can: softing: add DRV_NAME to replace hardcoded names
  can: esd_usb: use KBUILD_MODNAME instead of hard coded name
  can: gs_ubs: use KBUILD_MODNAME instead of hard coded name
  can: softing: add DRV_NAME to replace hardcoded names
  can: ubs_8dev: use KBUILD_MODNAME instead of hard coded name
  can: etas_es58x: remove DRV_VERSION
  can: tree-wide: implement ethtool_ops::get_drvinfo()
  can: can327: add software tx timestamps
  can: janz-ican3: add software tx timestamp
  can: slcan: add software tx timestamps
  can: v(x)can: add software tx timestamps
  can: tree-wide: advertise software timestamping capabilities
  can: dev: add hardware TX timestamp
  can: dev: add generic function can_ethtool_op_get_ts_info_hwts()
  can: dev: add generic function can_eth_ioctl_hwts()
  can: mcp251xfd: advertise timestamping capabilities and add ioctl
    support
  can: etas_es58x: advertise timestamping capabilities and add ioctl
    support
  can: kvaser_pciefd: advertise timestamping capabilities and add ioctl
    support
  can: kvaser_usb: advertise timestamping capabilities and add ioctl
    support
  can: peak_canfd: advertise timestamping capabilities and add ioctl
    support
  can: peak_usb: advertise timestamping capabilities and add ioctl
    support

 drivers/net/can/at91_can.c                    | 13 +++++
 drivers/net/can/c_can/c_can_main.c            | 13 +++++
 drivers/net/can/can327.c                      | 18 ++++++-
 drivers/net/can/cc770/cc770.c                 | 13 +++++
 drivers/net/can/ctucanfd/ctucanfd_base.c      | 13 +++++
 drivers/net/can/dev/dev.c                     | 50 +++++++++++++++++++
 drivers/net/can/dev/skb.c                     |  6 +++
 drivers/net/can/flexcan/flexcan-core.c        | 13 +++++
 drivers/net/can/grcan.c                       | 13 +++++
 drivers/net/can/ifi_canfd/ifi_canfd.c         | 13 +++++
 drivers/net/can/janz-ican3.c                  | 15 ++++++
 drivers/net/can/kvaser_pciefd.c               | 14 ++++++
 drivers/net/can/m_can/m_can.c                 | 13 +++++
 drivers/net/can/mscan/mscan.c                 |  1 +
 drivers/net/can/pch_can.c                     | 13 +++++
 drivers/net/can/peak_canfd/peak_canfd.c       | 14 ++++++
 drivers/net/can/rcar/rcar_can.c               | 13 +++++
 drivers/net/can/rcar/rcar_canfd.c             | 13 +++++
 drivers/net/can/sja1000/sja1000.c             | 13 +++++
 drivers/net/can/slcan/slcan-core.c            | 30 ++++++++---
 drivers/net/can/softing/softing_main.c        | 18 ++++++-
 drivers/net/can/spi/hi311x.c                  | 13 +++++
 drivers/net/can/spi/mcp251x.c                 | 13 +++++
 .../net/can/spi/mcp251xfd/mcp251xfd-core.c    | 14 ++++++
 drivers/net/can/sun4i_can.c                   | 13 +++++
 drivers/net/can/ti_hecc.c                     | 13 +++++
 drivers/net/can/usb/ems_usb.c                 | 17 ++++++-
 drivers/net/can/usb/esd_usb.c                 | 15 +++++-
 drivers/net/can/usb/etas_es58x/es58x_core.c   | 23 ++++++---
 drivers/net/can/usb/gs_usb.c                  | 15 ++++--
 drivers/net/can/usb/kvaser_usb/kvaser_usb.h   |  1 +
 .../net/can/usb/kvaser_usb/kvaser_usb_core.c  | 39 +++++++++++++--
 drivers/net/can/usb/mcba_usb.c                | 13 +++++
 drivers/net/can/usb/peak_usb/pcan_usb.c       |  3 ++
 drivers/net/can/usb/peak_usb/pcan_usb_core.c  | 18 ++++++-
 drivers/net/can/usb/peak_usb/pcan_usb_core.h  |  6 +++
 drivers/net/can/usb/peak_usb/pcan_usb_fd.c    |  3 ++
 drivers/net/can/usb/peak_usb/pcan_usb_pro.c   |  3 ++
 drivers/net/can/usb/ucan.c                    | 13 +++++
 drivers/net/can/usb/usb_8dev.c                | 17 ++++++-
 drivers/net/can/vcan.c                        | 15 ++++++
 drivers/net/can/vxcan.c                       | 15 ++++++
 drivers/net/can/xilinx_can.c                  | 13 +++++
 include/linux/can/dev.h                       |  4 ++
 44 files changed, 592 insertions(+), 29 deletions(-)

-- 
2.35.1


^ permalink raw reply	[flat|nested] 92+ messages in thread

* [PATCH v1 01/24]  can: can327: use KBUILD_MODNAME instead of hard coded name
  2022-07-25 13:31 [PATCH v1 00/24] can: add ethtool support and reporting of timestamping capabilities Vincent Mailhol
@ 2022-07-25 13:31 ` Vincent Mailhol
  2022-07-25 13:31 ` [PATCH v1 02/24] can: ems_ubs: " Vincent Mailhol
                   ` (26 subsequent siblings)
  27 siblings, 0 replies; 92+ messages in thread
From: Vincent Mailhol @ 2022-07-25 13:31 UTC (permalink / raw)
  To: linux-can, Marc Kleine-Budde
  Cc: Stephane Grosjean, Jimmy Assarsson, Oliver Hartkopp,
	Dario Binacchi, Max Staudt, Vincent Mailhol

The driver uses the string "can327" to populate
tty_ldisc_ops::name. KBUILD_MODNAME also evaluates to "can327". Use
KBUILD_MODNAME and get rid on the hardcoded string names.

Signed-off-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
---
 drivers/net/can/can327.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/can/can327.c b/drivers/net/can/can327.c
index 5da7778d92dc..bf0cce2dbb40 100644
--- a/drivers/net/can/can327.c
+++ b/drivers/net/can/can327.c
@@ -10,7 +10,7 @@
  *                   Fred N. van Kempen <waltje@uwalt.nl.mugnet.org>
  */
 
-#define pr_fmt(fmt) "can327: " fmt
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
 #include <linux/init.h>
 #include <linux/module.h>
@@ -1100,7 +1100,7 @@ static int can327_ldisc_ioctl(struct tty_struct *tty, unsigned int cmd,
 
 static struct tty_ldisc_ops can327_ldisc = {
 	.owner = THIS_MODULE,
-	.name = "can327",
+	.name = KBUILD_MODNAME,
 	.num = N_CAN327,
 	.receive_buf = can327_ldisc_rx,
 	.write_wakeup = can327_ldisc_tx_wakeup,
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 92+ messages in thread

* [PATCH v1 02/24] can: ems_ubs: use KBUILD_MODNAME instead of hard coded name
  2022-07-25 13:31 [PATCH v1 00/24] can: add ethtool support and reporting of timestamping capabilities Vincent Mailhol
  2022-07-25 13:31 ` [PATCH v1 01/24] can: can327: use KBUILD_MODNAME instead of hard coded name Vincent Mailhol
@ 2022-07-25 13:31 ` Vincent Mailhol
  2022-07-25 13:31 ` [PATCH v1 03/24] can: slcan: add DRV_NAME and define pr_fmt to replace hardcoded names Vincent Mailhol
                   ` (25 subsequent siblings)
  27 siblings, 0 replies; 92+ messages in thread
From: Vincent Mailhol @ 2022-07-25 13:31 UTC (permalink / raw)
  To: linux-can, Marc Kleine-Budde
  Cc: Stephane Grosjean, Jimmy Assarsson, Oliver Hartkopp,
	Dario Binacchi, Max Staudt, Vincent Mailhol

The driver uses the string "ems_usb" to populate usb_driver::name and
can_bittiming_const::name. KBUILD_MODNAME also evaluates to
"ems_ubs". Use KBUILD_MODNAME and get rid on the hardcoded string
names.

Signed-off-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
---
 drivers/net/can/usb/ems_usb.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/can/usb/ems_usb.c b/drivers/net/can/usb/ems_usb.c
index bbec3311d893..89a64e05cbd7 100644
--- a/drivers/net/can/usb/ems_usb.c
+++ b/drivers/net/can/usb/ems_usb.c
@@ -880,7 +880,7 @@ static const struct net_device_ops ems_usb_netdev_ops = {
 };
 
 static const struct can_bittiming_const ems_usb_bittiming_const = {
-	.name = "ems_usb",
+	.name = KBUILD_NAME,
 	.tseg1_min = 1,
 	.tseg1_max = 16,
 	.tseg2_min = 1,
@@ -1074,7 +1074,7 @@ static void ems_usb_disconnect(struct usb_interface *intf)
 
 /* usb specific object needed to register this driver with the usb subsystem */
 static struct usb_driver ems_usb_driver = {
-	.name = "ems_usb",
+	.name = KBUILD_NAME,
 	.probe = ems_usb_probe,
 	.disconnect = ems_usb_disconnect,
 	.id_table = ems_usb_table,
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 92+ messages in thread

* [PATCH v1 03/24] can: slcan: add DRV_NAME and define pr_fmt to replace hardcoded names
  2022-07-25 13:31 [PATCH v1 00/24] can: add ethtool support and reporting of timestamping capabilities Vincent Mailhol
  2022-07-25 13:31 ` [PATCH v1 01/24] can: can327: use KBUILD_MODNAME instead of hard coded name Vincent Mailhol
  2022-07-25 13:31 ` [PATCH v1 02/24] can: ems_ubs: " Vincent Mailhol
@ 2022-07-25 13:31 ` Vincent Mailhol
  2022-07-25 13:31 ` [PATCH v1 04/24] can: softing: add DRV_NAME " Vincent Mailhol
                   ` (24 subsequent siblings)
  27 siblings, 0 replies; 92+ messages in thread
From: Vincent Mailhol @ 2022-07-25 13:31 UTC (permalink / raw)
  To: linux-can, Marc Kleine-Budde
  Cc: Stephane Grosjean, Jimmy Assarsson, Oliver Hartkopp,
	Dario Binacchi, Max Staudt, Vincent Mailhol

The driver uses the string "slcan" to populate
tty_ldisc_ops::name. Add a new macro DRV_NAME which evaluates to
"slcan" and then use DRV_NAME and to get rid on the hardcoded string
names.

Similarly, the pr_info() and pr_err() hardcoded the "slcan"
prefix. Define pr_fmt so that the "slcan" prefix gets automatically
added.

CC: Dario Binacchi <dario.binacchi@amarulasolutions.com>
Signed-off-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
---

@Dario, because you are also doing a lot of changes on slcan, our
patches might conflict. Do not hesitate to take this one and add it to
your series to simplify the merge.
---
 drivers/net/can/slcan/slcan-core.c | 15 +++++++++------
 1 file changed, 9 insertions(+), 6 deletions(-)

diff --git a/drivers/net/can/slcan/slcan-core.c b/drivers/net/can/slcan/slcan-core.c
index dc28e715bbe1..d1562f9474c9 100644
--- a/drivers/net/can/slcan/slcan-core.c
+++ b/drivers/net/can/slcan/slcan-core.c
@@ -35,6 +35,9 @@
  *
  */
 
+#define DRV_NAME "slcan"
+#define pr_fmt(fmt) DRV_NAME ": " fmt
+
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 
@@ -864,7 +867,7 @@ static struct slcan *slc_alloc(void)
 	if (!dev)
 		return NULL;
 
-	snprintf(dev->name, sizeof(dev->name), "slcan%d", i);
+	snprintf(dev->name, sizeof(dev->name), DRV_NAME "%d", i);
 	dev->netdev_ops = &slc_netdev_ops;
 	dev->base_addr  = i;
 	slcan_set_ethtool_ops(dev);
@@ -937,7 +940,7 @@ static int slcan_open(struct tty_struct *tty)
 		rtnl_unlock();
 		err = register_candev(sl->dev);
 		if (err) {
-			pr_err("slcan: can't register candev\n");
+			pr_err("can't register candev\n");
 			goto err_free_chan;
 		}
 	} else {
@@ -1028,7 +1031,7 @@ static int slcan_ioctl(struct tty_struct *tty, unsigned int cmd,
 static struct tty_ldisc_ops slc_ldisc = {
 	.owner		= THIS_MODULE,
 	.num		= N_SLCAN,
-	.name		= "slcan",
+	.name		= DRV_NAME,
 	.open		= slcan_open,
 	.close		= slcan_close,
 	.hangup		= slcan_hangup,
@@ -1044,8 +1047,8 @@ static int __init slcan_init(void)
 	if (maxdev < 4)
 		maxdev = 4; /* Sanity */
 
-	pr_info("slcan: serial line CAN interface driver\n");
-	pr_info("slcan: %d dynamic interface channels.\n", maxdev);
+	pr_info("serial line CAN interface driver\n");
+	pr_info("%d dynamic interface channels.\n", maxdev);
 
 	slcan_devs = kcalloc(maxdev, sizeof(struct net_device *), GFP_KERNEL);
 	if (!slcan_devs)
@@ -1054,7 +1057,7 @@ static int __init slcan_init(void)
 	/* Fill in our line protocol discipline, and register it */
 	status = tty_register_ldisc(&slc_ldisc);
 	if (status)  {
-		pr_err("slcan: can't register line discipline\n");
+		pr_err("can't register line discipline\n");
 		kfree(slcan_devs);
 	}
 	return status;
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 92+ messages in thread

* [PATCH v1 04/24] can: softing: add DRV_NAME to replace hardcoded names
  2022-07-25 13:31 [PATCH v1 00/24] can: add ethtool support and reporting of timestamping capabilities Vincent Mailhol
                   ` (2 preceding siblings ...)
  2022-07-25 13:31 ` [PATCH v1 03/24] can: slcan: add DRV_NAME and define pr_fmt to replace hardcoded names Vincent Mailhol
@ 2022-07-25 13:31 ` Vincent Mailhol
  2022-07-25 13:31 ` [PATCH v1 05/24] can: esd_usb: use KBUILD_MODNAME instead of hard coded name Vincent Mailhol
                   ` (23 subsequent siblings)
  27 siblings, 0 replies; 92+ messages in thread
From: Vincent Mailhol @ 2022-07-25 13:31 UTC (permalink / raw)
  To: linux-can, Marc Kleine-Budde
  Cc: Stephane Grosjean, Jimmy Assarsson, Oliver Hartkopp,
	Dario Binacchi, Max Staudt, Vincent Mailhol

The driver uses the string "softing" to populate platform_driver::name
and can_bittiming_const::name. Add a new macro DRV_NAME which
evaluates to "ems_ubs" and then use DRV_NAME and to get rid on the
hardcoded string names.

Signed-off-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
---
 drivers/net/can/softing/softing_main.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/net/can/softing/softing_main.c b/drivers/net/can/softing/softing_main.c
index 8d27ac66ca7f..d810fe6915a4 100644
--- a/drivers/net/can/softing/softing_main.c
+++ b/drivers/net/can/softing/softing_main.c
@@ -11,6 +11,7 @@
 
 #include "softing.h"
 
+#define DRV_NAME "softing"
 #define TX_ECHO_SKB_MAX (((TXMAX+1)/2)-1)
 
 /*
@@ -612,7 +613,7 @@ static const struct net_device_ops softing_netdev_ops = {
 };
 
 static const struct can_bittiming_const softing_btr_const = {
-	.name = "softing",
+	.name = DRV_NAME,
 	.tseg1_min = 1,
 	.tseg1_max = 16,
 	.tseg2_min = 1,
@@ -846,7 +847,7 @@ static int softing_pdev_probe(struct platform_device *pdev)
 
 static struct platform_driver softing_driver = {
 	.driver = {
-		.name = "softing",
+		.name = DRV_NAME,
 	},
 	.probe = softing_pdev_probe,
 	.remove = softing_pdev_remove,
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 92+ messages in thread

* [PATCH v1 05/24] can: esd_usb: use KBUILD_MODNAME instead of hard coded name
  2022-07-25 13:31 [PATCH v1 00/24] can: add ethtool support and reporting of timestamping capabilities Vincent Mailhol
                   ` (3 preceding siblings ...)
  2022-07-25 13:31 ` [PATCH v1 04/24] can: softing: add DRV_NAME " Vincent Mailhol
@ 2022-07-25 13:31 ` Vincent Mailhol
  2022-07-25 13:31 ` [PATCH v1 06/24] can: gs_ubs: " Vincent Mailhol
                   ` (22 subsequent siblings)
  27 siblings, 0 replies; 92+ messages in thread
From: Vincent Mailhol @ 2022-07-25 13:31 UTC (permalink / raw)
  To: linux-can, Marc Kleine-Budde
  Cc: Stephane Grosjean, Jimmy Assarsson, Oliver Hartkopp,
	Dario Binacchi, Max Staudt, Vincent Mailhol, Frank Jungclaus

The driver uses the string "ems_usb" to populate
usb_driver::name. KBUILD_MODNAME also evaluates to "esd_ubs". Use
KBUILD_MODNAME and get rid on the hardcoded string names.

CC: Frank Jungclaus <frank.jungclaus@esd.eu>
Signed-off-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
---
 drivers/net/can/usb/ems_usb.c | 4 ++--
 drivers/net/can/usb/esd_usb.c | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/net/can/usb/ems_usb.c b/drivers/net/can/usb/ems_usb.c
index 89a64e05cbd7..e86a2033db60 100644
--- a/drivers/net/can/usb/ems_usb.c
+++ b/drivers/net/can/usb/ems_usb.c
@@ -880,7 +880,7 @@ static const struct net_device_ops ems_usb_netdev_ops = {
 };
 
 static const struct can_bittiming_const ems_usb_bittiming_const = {
-	.name = KBUILD_NAME,
+	.name = KBUILD_MODNAME,
 	.tseg1_min = 1,
 	.tseg1_max = 16,
 	.tseg2_min = 1,
@@ -1074,7 +1074,7 @@ static void ems_usb_disconnect(struct usb_interface *intf)
 
 /* usb specific object needed to register this driver with the usb subsystem */
 static struct usb_driver ems_usb_driver = {
-	.name = KBUILD_NAME,
+	.name = KBUILD_MODNAME,
 	.probe = ems_usb_probe,
 	.disconnect = ems_usb_disconnect,
 	.id_table = ems_usb_table,
diff --git a/drivers/net/can/usb/esd_usb.c b/drivers/net/can/usb/esd_usb.c
index 177ed33e08d9..7b849bd3cc9c 100644
--- a/drivers/net/can/usb/esd_usb.c
+++ b/drivers/net/can/usb/esd_usb.c
@@ -1138,7 +1138,7 @@ static void esd_usb_disconnect(struct usb_interface *intf)
 
 /* usb specific object needed to register this driver with the usb subsystem */
 static struct usb_driver esd_usb_driver = {
-	.name = "esd_usb",
+	.name = KBUILD_MODNAME,
 	.probe = esd_usb_probe,
 	.disconnect = esd_usb_disconnect,
 	.id_table = esd_usb_table,
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 92+ messages in thread

* [PATCH v1 06/24] can: gs_ubs: use KBUILD_MODNAME instead of hard coded name
  2022-07-25 13:31 [PATCH v1 00/24] can: add ethtool support and reporting of timestamping capabilities Vincent Mailhol
                   ` (4 preceding siblings ...)
  2022-07-25 13:31 ` [PATCH v1 05/24] can: esd_usb: use KBUILD_MODNAME instead of hard coded name Vincent Mailhol
@ 2022-07-25 13:31 ` Vincent Mailhol
  2022-07-25 13:31 ` [PATCH v1 07/24] can: softing: add DRV_NAME to replace hardcoded names Vincent Mailhol
                   ` (21 subsequent siblings)
  27 siblings, 0 replies; 92+ messages in thread
From: Vincent Mailhol @ 2022-07-25 13:31 UTC (permalink / raw)
  To: linux-can, Marc Kleine-Budde
  Cc: Stephane Grosjean, Jimmy Assarsson, Oliver Hartkopp,
	Dario Binacchi, Max Staudt, Vincent Mailhol

The driver uses the string "gs_usb" to populate usb_driver::name,
can_bittiming_const::name and
can_data_bittiming_const::name. KBUILD_MODNAME evaluates to
"gs_ubs". Use KBUILD_MODNAME and get rid on the hardcoded string
names.

Signed-off-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
---
 drivers/net/can/usb/gs_usb.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/net/can/usb/gs_usb.c b/drivers/net/can/usb/gs_usb.c
index d3a658b444b5..fd239b523c42 100644
--- a/drivers/net/can/usb/gs_usb.c
+++ b/drivers/net/can/usb/gs_usb.c
@@ -993,7 +993,7 @@ static struct gs_can *gs_make_candev(unsigned int channel,
 	netdev->flags |= IFF_ECHO; /* we support full roundtrip echo */
 
 	/* dev setup */
-	strcpy(dev->bt_const.name, "gs_usb");
+	strcpy(dev->bt_const.name, KBUILD_MODNAME);
 	dev->bt_const.tseg1_min = le32_to_cpu(bt_const->tseg1_min);
 	dev->bt_const.tseg1_max = le32_to_cpu(bt_const->tseg1_max);
 	dev->bt_const.tseg2_min = le32_to_cpu(bt_const->tseg2_min);
@@ -1100,7 +1100,7 @@ static struct gs_can *gs_make_candev(unsigned int channel,
 			return ERR_PTR(rc);
 		}
 
-		strcpy(dev->data_bt_const.name, "gs_usb");
+		strcpy(dev->data_bt_const.name, KBUILD_MODNAME);
 		dev->data_bt_const.tseg1_min = le32_to_cpu(bt_const_extended->dtseg1_min);
 		dev->data_bt_const.tseg1_max = le32_to_cpu(bt_const_extended->dtseg1_max);
 		dev->data_bt_const.tseg2_min = le32_to_cpu(bt_const_extended->dtseg2_min);
@@ -1270,7 +1270,7 @@ static const struct usb_device_id gs_usb_table[] = {
 MODULE_DEVICE_TABLE(usb, gs_usb_table);
 
 static struct usb_driver gs_usb_driver = {
-	.name = "gs_usb",
+	.name = KBUILD_MODNAME,
 	.probe = gs_usb_probe,
 	.disconnect = gs_usb_disconnect,
 	.id_table = gs_usb_table,
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 92+ messages in thread

* [PATCH v1 07/24] can: softing: add DRV_NAME to replace hardcoded names
  2022-07-25 13:31 [PATCH v1 00/24] can: add ethtool support and reporting of timestamping capabilities Vincent Mailhol
                   ` (5 preceding siblings ...)
  2022-07-25 13:31 ` [PATCH v1 06/24] can: gs_ubs: " Vincent Mailhol
@ 2022-07-25 13:31 ` Vincent Mailhol
  2022-07-25 13:31 ` [PATCH v1 08/24] can: ubs_8dev: use KBUILD_MODNAME instead of hard coded name Vincent Mailhol
                   ` (20 subsequent siblings)
  27 siblings, 0 replies; 92+ messages in thread
From: Vincent Mailhol @ 2022-07-25 13:31 UTC (permalink / raw)
  To: linux-can, Marc Kleine-Budde
  Cc: Stephane Grosjean, Jimmy Assarsson, Oliver Hartkopp,
	Dario Binacchi, Max Staudt, Vincent Mailhol

The driver uses the string "kvaser_usb" to populate
usb_driver::name. Add a new macro DRV_NAME which evaluates to
"ems_ubs" and then use DRV_NAME and to get rid on the hardcoded string
names.

Signed-off-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
---
 drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c b/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c
index f211bfcb1d97..a6cff8da5a41 100644
--- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c
+++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c
@@ -29,6 +29,8 @@
 
 #include "kvaser_usb.h"
 
+#define DRV_NAME "kvaser_usb"
+
 /* Kvaser USB vendor id. */
 #define KVASER_VENDOR_ID			0x0bfd
 
@@ -869,7 +871,7 @@ static void kvaser_usb_disconnect(struct usb_interface *intf)
 }
 
 static struct usb_driver kvaser_usb_driver = {
-	.name = "kvaser_usb",
+	.name = DRV_NAME,
 	.probe = kvaser_usb_probe,
 	.disconnect = kvaser_usb_disconnect,
 	.id_table = kvaser_usb_table,
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 92+ messages in thread

* [PATCH v1 08/24] can: ubs_8dev: use KBUILD_MODNAME instead of hard coded name
  2022-07-25 13:31 [PATCH v1 00/24] can: add ethtool support and reporting of timestamping capabilities Vincent Mailhol
                   ` (6 preceding siblings ...)
  2022-07-25 13:31 ` [PATCH v1 07/24] can: softing: add DRV_NAME to replace hardcoded names Vincent Mailhol
@ 2022-07-25 13:31 ` Vincent Mailhol
  2022-07-25 13:31 ` [PATCH v1 09/24] can: etas_es58x: remove DRV_VERSION Vincent Mailhol
                   ` (19 subsequent siblings)
  27 siblings, 0 replies; 92+ messages in thread
From: Vincent Mailhol @ 2022-07-25 13:31 UTC (permalink / raw)
  To: linux-can, Marc Kleine-Budde
  Cc: Stephane Grosjean, Jimmy Assarsson, Oliver Hartkopp,
	Dario Binacchi, Max Staudt, Vincent Mailhol

The driver uses the string "usb_8dev" to populate usb_driver::name and
can_bittiming_const::name. KBUILD_MODNAME also evaluates to
"ubs_8dev". Use KBUILD_MODNAME and get rid on the hardcoded string
names.

Signed-off-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
---
 drivers/net/can/usb/usb_8dev.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/can/usb/usb_8dev.c b/drivers/net/can/usb/usb_8dev.c
index 8b7cd69e20b0..6665a66745a7 100644
--- a/drivers/net/can/usb/usb_8dev.c
+++ b/drivers/net/can/usb/usb_8dev.c
@@ -871,7 +871,7 @@ static const struct net_device_ops usb_8dev_netdev_ops = {
 };
 
 static const struct can_bittiming_const usb_8dev_bittiming_const = {
-	.name = "usb_8dev",
+	.name = KBUILD_MODNAME,
 	.tseg1_min = 1,
 	.tseg1_max = 16,
 	.tseg2_min = 1,
@@ -997,7 +997,7 @@ static void usb_8dev_disconnect(struct usb_interface *intf)
 }
 
 static struct usb_driver usb_8dev_driver = {
-	.name =		"usb_8dev",
+	.name =		KBUILD_MODNAME,
 	.probe =	usb_8dev_probe,
 	.disconnect =	usb_8dev_disconnect,
 	.id_table =	usb_8dev_table,
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 92+ messages in thread

* [PATCH v1 09/24] can: etas_es58x: remove DRV_VERSION
  2022-07-25 13:31 [PATCH v1 00/24] can: add ethtool support and reporting of timestamping capabilities Vincent Mailhol
                   ` (7 preceding siblings ...)
  2022-07-25 13:31 ` [PATCH v1 08/24] can: ubs_8dev: use KBUILD_MODNAME instead of hard coded name Vincent Mailhol
@ 2022-07-25 13:31 ` Vincent Mailhol
  2022-07-25 13:31 ` [PATCH v1 10/24] can: tree-wide: implement ethtool_ops::get_drvinfo() Vincent Mailhol
                   ` (18 subsequent siblings)
  27 siblings, 0 replies; 92+ messages in thread
From: Vincent Mailhol @ 2022-07-25 13:31 UTC (permalink / raw)
  To: linux-can, Marc Kleine-Budde
  Cc: Stephane Grosjean, Jimmy Assarsson, Oliver Hartkopp,
	Dario Binacchi, Max Staudt, Vincent Mailhol

DRV_VERSION is a leftover from when the driver was an out of tree
module. The driver version was never incremented despite of the
numerous changes made since it was mainstreamed. Keeping an
unmaintained driver version number makes no sense. Remove it and rely
on the kernel version instead.

Signed-off-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
---
 drivers/net/can/usb/etas_es58x/es58x_core.c | 7 ++-----
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/drivers/net/can/usb/etas_es58x/es58x_core.c b/drivers/net/can/usb/etas_es58x/es58x_core.c
index 7353745f92d7..3f51488bd649 100644
--- a/drivers/net/can/usb/etas_es58x/es58x_core.c
+++ b/drivers/net/can/usb/etas_es58x/es58x_core.c
@@ -18,11 +18,9 @@
 
 #include "es58x_core.h"
 
-#define DRV_VERSION "1.00"
 MODULE_AUTHOR("Vincent Mailhol <mailhol.vincent@wanadoo.fr>");
 MODULE_AUTHOR("Arunachalam Santhanam <arunachalam.santhanam@in.bosch.com>");
 MODULE_DESCRIPTION("Socket CAN driver for ETAS ES58X USB adapters");
-MODULE_VERSION(DRV_VERSION);
 MODULE_LICENSE("GPL v2");
 
 #define ES58X_MODULE_NAME "etas_es58x"
@@ -2181,9 +2179,8 @@ static struct es58x_device *es58x_init_es58x_dev(struct usb_interface *intf,
 	struct usb_endpoint_descriptor *ep_in, *ep_out;
 	int ret;
 
-	dev_info(dev,
-		 "Starting %s %s (Serial Number %s) driver version %s\n",
-		 udev->manufacturer, udev->product, udev->serial, DRV_VERSION);
+	dev_info(dev, "Starting %s %s (Serial Number %s)\n",
+		 udev->manufacturer, udev->product, udev->serial);
 
 	ret = usb_find_common_endpoints(intf->cur_altsetting, &ep_in, &ep_out,
 					NULL, NULL);
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 92+ messages in thread

* [PATCH v1 10/24] can: tree-wide: implement ethtool_ops::get_drvinfo()
  2022-07-25 13:31 [PATCH v1 00/24] can: add ethtool support and reporting of timestamping capabilities Vincent Mailhol
                   ` (8 preceding siblings ...)
  2022-07-25 13:31 ` [PATCH v1 09/24] can: etas_es58x: remove DRV_VERSION Vincent Mailhol
@ 2022-07-25 13:31 ` Vincent Mailhol
  2022-07-25 14:09   ` Marc Kleine-Budde
  2022-07-26  7:29   ` Dario Binacchi
  2022-07-25 13:31 ` [PATCH v1 11/24] can: can327: add software tx timestamps Vincent Mailhol
                   ` (17 subsequent siblings)
  27 siblings, 2 replies; 92+ messages in thread
From: Vincent Mailhol @ 2022-07-25 13:31 UTC (permalink / raw)
  To: linux-can, Marc Kleine-Budde
  Cc: Stephane Grosjean, Jimmy Assarsson, Oliver Hartkopp,
	Dario Binacchi, Max Staudt, Vincent Mailhol

For all CAN drivers, implement the get_drvinfo() function.

After this patch, it is now possible to retrieve basic information by
doing:

| $ ethtool -i canX

Signed-off-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
---
 drivers/net/can/at91_can.c                       | 12 ++++++++++++
 drivers/net/can/c_can/c_can_main.c               | 12 ++++++++++++
 drivers/net/can/can327.c                         | 11 +++++++++++
 drivers/net/can/cc770/cc770.c                    | 12 ++++++++++++
 drivers/net/can/ctucanfd/ctucanfd_base.c         | 12 ++++++++++++
 drivers/net/can/flexcan/flexcan-core.c           | 12 ++++++++++++
 drivers/net/can/grcan.c                          | 12 ++++++++++++
 drivers/net/can/ifi_canfd/ifi_canfd.c            | 12 ++++++++++++
 drivers/net/can/janz-ican3.c                     | 12 ++++++++++++
 drivers/net/can/kvaser_pciefd.c                  | 12 ++++++++++++
 drivers/net/can/m_can/m_can.c                    | 12 ++++++++++++
 drivers/net/can/mscan/mscan.c                    |  1 +
 drivers/net/can/pch_can.c                        | 12 ++++++++++++
 drivers/net/can/peak_canfd/peak_canfd.c          | 12 ++++++++++++
 drivers/net/can/rcar/rcar_can.c                  | 12 ++++++++++++
 drivers/net/can/rcar/rcar_canfd.c                | 12 ++++++++++++
 drivers/net/can/sja1000/sja1000.c                | 12 ++++++++++++
 drivers/net/can/slcan/slcan-core.c               | 12 ++++++++++++
 drivers/net/can/softing/softing_main.c           | 12 ++++++++++++
 drivers/net/can/spi/hi311x.c                     | 12 ++++++++++++
 drivers/net/can/spi/mcp251x.c                    | 12 ++++++++++++
 drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c   | 12 ++++++++++++
 drivers/net/can/sun4i_can.c                      | 12 ++++++++++++
 drivers/net/can/ti_hecc.c                        | 12 ++++++++++++
 drivers/net/can/usb/ems_usb.c                    | 12 ++++++++++++
 drivers/net/can/usb/esd_usb.c                    | 12 ++++++++++++
 drivers/net/can/usb/etas_es58x/es58x_core.c      | 12 ++++++++++++
 drivers/net/can/usb/gs_usb.c                     |  8 ++++++++
 drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c | 12 ++++++++++++
 drivers/net/can/usb/mcba_usb.c                   | 12 ++++++++++++
 drivers/net/can/usb/peak_usb/pcan_usb_core.c     |  6 ++++++
 drivers/net/can/usb/peak_usb/pcan_usb_core.h     |  2 ++
 drivers/net/can/usb/peak_usb/pcan_usb_fd.c       |  1 +
 drivers/net/can/usb/peak_usb/pcan_usb_pro.c      |  1 +
 drivers/net/can/usb/ucan.c                       | 12 ++++++++++++
 drivers/net/can/usb/usb_8dev.c                   | 12 ++++++++++++
 drivers/net/can/vcan.c                           | 12 ++++++++++++
 drivers/net/can/vxcan.c                          | 12 ++++++++++++
 drivers/net/can/xilinx_can.c                     | 12 ++++++++++++
 39 files changed, 414 insertions(+)

diff --git a/drivers/net/can/at91_can.c b/drivers/net/can/at91_can.c
index 29ed0d3cd171..637d2ca34d08 100644
--- a/drivers/net/can/at91_can.c
+++ b/drivers/net/can/at91_can.c
@@ -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>
@@ -1152,6 +1153,16 @@ static const struct net_device_ops at91_netdev_ops = {
 	.ndo_change_mtu = can_change_mtu,
 };
 
+static void at91_get_drvinfo(struct net_device *netdev,
+			     struct ethtool_drvinfo *drvinfo)
+{
+	strscpy(drvinfo->driver, KBUILD_MODNAME, sizeof(drvinfo->driver));
+}
+
+static const struct ethtool_ops at91_ethtool_ops = {
+	.get_drvinfo = at91_get_drvinfo,
+};
+
 static ssize_t mb0_id_show(struct device *dev,
 			   struct device_attribute *attr, char *buf)
 {
@@ -1293,6 +1304,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;
 
diff --git a/drivers/net/can/c_can/c_can_main.c b/drivers/net/can/c_can/c_can_main.c
index de38d8f7b5f7..fa541a7cb9c1 100644
--- a/drivers/net/can/c_can/c_can_main.c
+++ b/drivers/net/can/c_can/c_can_main.c
@@ -29,6 +29,7 @@
 #include <linux/module.h>
 #include <linux/interrupt.h>
 #include <linux/delay.h>
+#include <linux/ethtool.h>
 #include <linux/netdevice.h>
 #include <linux/if_arp.h>
 #include <linux/if_ether.h>
@@ -1353,6 +1354,16 @@ static const struct net_device_ops c_can_netdev_ops = {
 	.ndo_change_mtu = can_change_mtu,
 };
 
+static void c_can_get_drvinfo(struct net_device *netdev,
+			      struct ethtool_drvinfo *drvinfo)
+{
+	strscpy(drvinfo->driver, KBUILD_MODNAME, sizeof(drvinfo->driver));
+}
+
+static const struct ethtool_ops c_can_ethtool_ops = {
+	.get_drvinfo = c_can_get_drvinfo,
+};
+
 int register_c_can_dev(struct net_device *dev)
 {
 	/* Deactivate pins to prevent DRA7 DCAN IP from being
@@ -1364,6 +1375,7 @@ int register_c_can_dev(struct net_device *dev)
 
 	dev->flags |= IFF_ECHO;	/* we support local echo */
 	dev->netdev_ops = &c_can_netdev_ops;
+	dev->ethtool_ops = &c_can_ethtool_ops;
 	c_can_set_ethtool_ops(dev);
 
 	return register_candev(dev);
diff --git a/drivers/net/can/can327.c b/drivers/net/can/can327.c
index bf0cce2dbb40..03c9e8c6990d 100644
--- a/drivers/net/can/can327.c
+++ b/drivers/net/can/can327.c
@@ -848,6 +848,16 @@ static const struct net_device_ops can327_netdev_ops = {
 	.ndo_change_mtu = can_change_mtu,
 };
 
+static void can327_get_drvinfo(struct net_device *netdev,
+			       struct ethtool_drvinfo *drvinfo)
+{
+	strscpy(drvinfo->driver, KBUILD_MODNAME, sizeof(drvinfo->driver));
+}
+
+static const struct ethtool_ops can327_ethtool_ops = {
+	.get_drvinfo = can327_get_drvinfo,
+};
+
 static bool can327_is_valid_rx_char(u8 c)
 {
 	static const bool lut_char_is_valid['z'] = {
@@ -1032,6 +1042,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;
diff --git a/drivers/net/can/cc770/cc770.c b/drivers/net/can/cc770/cc770.c
index 797a954bb1a0..1bb30e69cb24 100644
--- a/drivers/net/can/cc770/cc770.c
+++ b/drivers/net/can/cc770/cc770.c
@@ -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>
@@ -836,6 +837,16 @@ static const struct net_device_ops cc770_netdev_ops = {
 	.ndo_change_mtu = can_change_mtu,
 };
 
+static void cc770_get_drvinfo(struct net_device *netdev,
+			      struct ethtool_drvinfo *drvinfo)
+{
+	strscpy(drvinfo->driver, KBUILD_MODNAME, sizeof(drvinfo->driver));
+}
+
+static const struct ethtool_ops cc770_ethtool_ops = {
+	.get_drvinfo = cc770_get_drvinfo,
+};
+
 int register_cc770dev(struct net_device *dev)
 {
 	struct cc770_priv *priv = netdev_priv(dev);
@@ -846,6 +857,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 */
 
diff --git a/drivers/net/can/ctucanfd/ctucanfd_base.c b/drivers/net/can/ctucanfd/ctucanfd_base.c
index 6b281f6eb9b4..fd5fd17c16f2 100644
--- a/drivers/net/can/ctucanfd/ctucanfd_base.c
+++ b/drivers/net/can/ctucanfd/ctucanfd_base.c
@@ -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>
@@ -1301,6 +1302,16 @@ static const struct net_device_ops ctucan_netdev_ops = {
 	.ndo_change_mtu	= can_change_mtu,
 };
 
+static void ctucan_get_drvinfo(struct net_device *netdev,
+			       struct ethtool_drvinfo *drvinfo)
+{
+	strscpy(drvinfo->driver, KBUILD_MODNAME, sizeof(drvinfo->driver));
+}
+
+static const struct ethtool_ops ctucan_ethtool_ops = {
+	.get_drvinfo = ctucan_get_drvinfo,
+};
+
 int ctucan_suspend(struct device *dev)
 {
 	struct net_device *ndev = dev_get_drvdata(dev);
@@ -1377,6 +1388,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) {
diff --git a/drivers/net/can/flexcan/flexcan-core.c b/drivers/net/can/flexcan/flexcan-core.c
index d060088047f1..61e3483802c6 100644
--- a/drivers/net/can/flexcan/flexcan-core.c
+++ b/drivers/net/can/flexcan/flexcan-core.c
@@ -16,6 +16,7 @@
 #include <linux/can/error.h>
 #include <linux/clk.h>
 #include <linux/delay.h>
+#include <linux/ethtool.h>
 #include <linux/firmware/imx/sci.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
@@ -1813,6 +1814,16 @@ static const struct net_device_ops flexcan_netdev_ops = {
 	.ndo_change_mtu = can_change_mtu,
 };
 
+static void flexcan_get_drvinfo(struct net_device *netdev,
+				struct ethtool_drvinfo *drvinfo)
+{
+	strscpy(drvinfo->driver, DRV_NAME, sizeof(drvinfo->driver));
+}
+
+static const struct ethtool_ops flexcan_ethtool_ops = {
+	.get_drvinfo = flexcan_get_drvinfo,
+};
+
 static int register_flexcandev(struct net_device *dev)
 {
 	struct flexcan_priv *priv = netdev_priv(dev);
@@ -2113,6 +2124,7 @@ static int flexcan_probe(struct platform_device *pdev)
 	SET_NETDEV_DEV(dev, &pdev->dev);
 
 	dev->netdev_ops = &flexcan_netdev_ops;
+	dev->ethtool_ops = &flexcan_ethtool_ops;
 	flexcan_set_ethtool_ops(dev);
 	dev->irq = irq;
 	dev->flags |= IFF_ECHO;
diff --git a/drivers/net/can/grcan.c b/drivers/net/can/grcan.c
index 24035a6187c9..ce64f2cbe9c6 100644
--- a/drivers/net/can/grcan.c
+++ b/drivers/net/can/grcan.c
@@ -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>
@@ -1561,6 +1562,16 @@ static const struct net_device_ops grcan_netdev_ops = {
 	.ndo_change_mtu = can_change_mtu,
 };
 
+static void grcan_get_drvinfo(struct net_device *netdev,
+			      struct ethtool_drvinfo *drvinfo)
+{
+	strscpy(drvinfo->driver, DRV_NAME, sizeof(drvinfo->driver));
+}
+
+static const struct ethtool_ops grcan_ethtool_ops = {
+	.get_drvinfo = grcan_get_drvinfo,
+};
+
 static int grcan_setup_netdev(struct platform_device *ofdev,
 			      void __iomem *base,
 			      int irq, u32 ambafreq, bool txbug)
@@ -1577,6 +1588,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);
diff --git a/drivers/net/can/ifi_canfd/ifi_canfd.c b/drivers/net/can/ifi_canfd/ifi_canfd.c
index 64e3be8b73af..c682401eea3d 100644
--- a/drivers/net/can/ifi_canfd/ifi_canfd.c
+++ b/drivers/net/can/ifi_canfd/ifi_canfd.c
@@ -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>
@@ -925,6 +926,16 @@ static const struct net_device_ops ifi_canfd_netdev_ops = {
 	.ndo_change_mtu	= can_change_mtu,
 };
 
+static void ifi_canfd_get_drvinfo(struct net_device *netdev,
+				  struct ethtool_drvinfo *drvinfo)
+{
+	strscpy(drvinfo->driver, KBUILD_MODNAME, sizeof(drvinfo->driver));
+}
+
+static const struct ethtool_ops ifi_canfd_ethtool_ops = {
+	.get_drvinfo = ifi_canfd_get_drvinfo,
+};
+
 static int ifi_canfd_plat_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
@@ -962,6 +973,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;
diff --git a/drivers/net/can/janz-ican3.c b/drivers/net/can/janz-ican3.c
index ccb5c5405224..2534364e8be3 100644
--- a/drivers/net/can/janz-ican3.c
+++ b/drivers/net/can/janz-ican3.c
@@ -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>
@@ -1752,6 +1753,16 @@ static const struct net_device_ops ican3_netdev_ops = {
 	.ndo_change_mtu = can_change_mtu,
 };
 
+static void ican3_get_drvinfo(struct net_device *netdev,
+			      struct ethtool_drvinfo *drvinfo)
+{
+	strscpy(drvinfo->driver, DRV_NAME, sizeof(drvinfo->driver));
+}
+
+static const struct ethtool_ops ican3_ethtool_ops = {
+	.get_drvinfo = ican3_get_drvinfo,
+};
+
 /*
  * Low-level CAN Device
  */
@@ -1923,6 +1934,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);
 
diff --git a/drivers/net/can/kvaser_pciefd.c b/drivers/net/can/kvaser_pciefd.c
index dcd2c9d50d5e..f7f7a0287a8d 100644
--- a/drivers/net/can/kvaser_pciefd.c
+++ b/drivers/net/can/kvaser_pciefd.c
@@ -9,6 +9,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/device.h>
+#include <linux/ethtool.h>
 #include <linux/pci.h>
 #include <linux/can/dev.h>
 #include <linux/timer.h>
@@ -923,6 +924,16 @@ static const struct net_device_ops kvaser_pciefd_netdev_ops = {
 	.ndo_change_mtu = can_change_mtu,
 };
 
+static void kvaser_pciefd_get_drvinfo(struct net_device *netdev,
+				      struct ethtool_drvinfo *drvinfo)
+{
+	strscpy(drvinfo->driver, KVASER_PCIEFD_DRV_NAME, sizeof(drvinfo->driver));
+}
+
+static const struct ethtool_ops kvaser_pciefd_ethtool_ops = {
+	.get_drvinfo = kvaser_pciefd_get_drvinfo,
+};
+
 static int kvaser_pciefd_setup_can_ctrls(struct kvaser_pciefd *pcie)
 {
 	int i;
@@ -939,6 +950,7 @@ static int kvaser_pciefd_setup_can_ctrls(struct kvaser_pciefd *pcie)
 
 		can = netdev_priv(netdev);
 		netdev->netdev_ops = &kvaser_pciefd_netdev_ops;
+		netdev->ethtool_ops = &kvaser_pciefd_ethtool_ops;
 		can->reg_base = pcie->reg_base + KVASER_PCIEFD_KCAN0_BASE +
 				i * KVASER_PCIEFD_KCAN_BASE_OFFSET;
 
diff --git a/drivers/net/can/m_can/m_can.c b/drivers/net/can/m_can/m_can.c
index 713a4b0edf86..dc55bfd260c9 100644
--- a/drivers/net/can/m_can/m_can.c
+++ b/drivers/net/can/m_can/m_can.c
@@ -9,6 +9,7 @@
  */
 
 #include <linux/bitfield.h>
+#include <linux/ethtool.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
 #include <linux/kernel.h>
@@ -1829,10 +1830,21 @@ static const struct net_device_ops m_can_netdev_ops = {
 	.ndo_change_mtu = can_change_mtu,
 };
 
+static void m_can_get_drvinfo(struct net_device *netdev,
+			      struct ethtool_drvinfo *drvinfo)
+{
+	strscpy(drvinfo->driver, KBUILD_MODNAME, sizeof(drvinfo->driver));
+}
+
+static const struct ethtool_ops m_can_ethtool_ops = {
+	.get_drvinfo = m_can_get_drvinfo,
+};
+
 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);
 }
diff --git a/drivers/net/can/mscan/mscan.c b/drivers/net/can/mscan/mscan.c
index 78a21ab63601..b1677588a4c8 100644
--- a/drivers/net/can/mscan/mscan.c
+++ b/drivers/net/can/mscan/mscan.c
@@ -676,6 +676,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 */
 
diff --git a/drivers/net/can/pch_can.c b/drivers/net/can/pch_can.c
index 32804fed116c..c51354b4cf0c 100644
--- a/drivers/net/can/pch_can.c
+++ b/drivers/net/can/pch_can.c
@@ -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>
@@ -938,6 +939,16 @@ static const struct net_device_ops pch_can_netdev_ops = {
 	.ndo_change_mtu		= can_change_mtu,
 };
 
+static void pch_can_get_drvinfo(struct net_device *netdev,
+				struct ethtool_drvinfo *drvinfo)
+{
+	strscpy(drvinfo->driver, KBUILD_MODNAME, sizeof(drvinfo->driver));
+}
+
+static const struct ethtool_ops pch_can_ethtool_ops = {
+	.get_drvinfo = pch_can_get_drvinfo,
+};
+
 static void pch_can_remove(struct pci_dev *pdev)
 {
 	struct net_device *ndev = pci_get_drvdata(pdev);
@@ -1188,6 +1199,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);
diff --git a/drivers/net/can/peak_canfd/peak_canfd.c b/drivers/net/can/peak_canfd/peak_canfd.c
index afb9adb3d5c2..9b94d5b4be2d 100644
--- a/drivers/net/can/peak_canfd/peak_canfd.c
+++ b/drivers/net/can/peak_canfd/peak_canfd.c
@@ -7,6 +7,7 @@
 
 #include <linux/can.h>
 #include <linux/can/dev.h>
+#include <linux/ethtool.h>
 
 #include "peak_canfd_user.h"
 
@@ -749,6 +750,16 @@ static const struct net_device_ops peak_canfd_netdev_ops = {
 	.ndo_change_mtu = can_change_mtu,
 };
 
+static void peak_canfd_get_drvinfo(struct net_device *netdev,
+				   struct ethtool_drvinfo *drvinfo)
+{
+	strscpy(drvinfo->driver, KBUILD_MODNAME, sizeof(drvinfo->driver));
+}
+
+static const struct ethtool_ops peak_canfd_ethtool_ops = {
+	.get_drvinfo = peak_canfd_get_drvinfo,
+};
+
 struct net_device *alloc_peak_canfd_dev(int sizeof_priv, int index,
 					int echo_skb_max)
 {
@@ -789,6 +800,7 @@ struct net_device *alloc_peak_canfd_dev(int sizeof_priv, int index,
 
 	ndev->flags |= IFF_ECHO;
 	ndev->netdev_ops = &peak_canfd_netdev_ops;
+	ndev->ethtool_ops = &peak_canfd_ethtool_ops;
 	ndev->dev_id = index;
 
 	return ndev;
diff --git a/drivers/net/can/rcar/rcar_can.c b/drivers/net/can/rcar/rcar_can.c
index d11db2112a4a..aa644bb79da6 100644
--- a/drivers/net/can/rcar/rcar_can.c
+++ b/drivers/net/can/rcar/rcar_can.c
@@ -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>
@@ -630,6 +631,16 @@ static const struct net_device_ops rcar_can_netdev_ops = {
 	.ndo_change_mtu = can_change_mtu,
 };
 
+static void rcar_can_get_drvinfo(struct net_device *netdev,
+				 struct ethtool_drvinfo *drvinfo)
+{
+	strscpy(drvinfo->driver, RCAR_CAN_DRV_NAME, sizeof(drvinfo->driver));
+}
+
+static const struct ethtool_ops rcar_can_ethtool_ops = {
+	.get_drvinfo = rcar_can_get_drvinfo,
+};
+
 static void rcar_can_rx_pkt(struct rcar_can_priv *priv)
 {
 	struct net_device_stats *stats = &priv->ndev->stats;
@@ -785,6 +796,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;
diff --git a/drivers/net/can/rcar/rcar_canfd.c b/drivers/net/can/rcar/rcar_canfd.c
index d3e569a02b4d..89cc28985b81 100644
--- a/drivers/net/can/rcar/rcar_canfd.c
+++ b/drivers/net/can/rcar/rcar_canfd.c
@@ -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>
@@ -1695,6 +1696,16 @@ static const struct net_device_ops rcar_canfd_netdev_ops = {
 	.ndo_change_mtu = can_change_mtu,
 };
 
+static void rcar_canfd_get_drvinfo(struct net_device *netdev,
+				   struct ethtool_drvinfo *drvinfo)
+{
+	strscpy(drvinfo->driver, RCANFD_DRV_NAME, sizeof(drvinfo->driver));
+}
+
+static const struct ethtool_ops rcar_canfd_ethtool_ops = {
+	.get_drvinfo = rcar_canfd_get_drvinfo,
+};
+
 static int rcar_canfd_channel_probe(struct rcar_canfd_global *gpriv, u32 ch,
 				    u32 fcan_freq)
 {
@@ -1711,6 +1722,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;
diff --git a/drivers/net/can/sja1000/sja1000.c b/drivers/net/can/sja1000/sja1000.c
index 75a2f9bf8c16..43967790f4c1 100644
--- a/drivers/net/can/sja1000/sja1000.c
+++ b/drivers/net/can/sja1000/sja1000.c
@@ -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>
@@ -654,6 +655,16 @@ static const struct net_device_ops sja1000_netdev_ops = {
 	.ndo_change_mtu	= can_change_mtu,
 };
 
+static void sja1000_get_drvinfo(struct net_device *netdev,
+				struct ethtool_drvinfo *drvinfo)
+{
+	strscpy(drvinfo->driver, DRV_NAME, sizeof(drvinfo->driver));
+}
+
+static const struct ethtool_ops sja1000_ethtool_ops = {
+	.get_drvinfo = sja1000_get_drvinfo,
+};
+
 int register_sja1000dev(struct net_device *dev)
 {
 	int ret;
@@ -663,6 +674,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);
diff --git a/drivers/net/can/slcan/slcan-core.c b/drivers/net/can/slcan/slcan-core.c
index d1562f9474c9..1b86001c85f8 100644
--- a/drivers/net/can/slcan/slcan-core.c
+++ b/drivers/net/can/slcan/slcan-core.c
@@ -46,6 +46,7 @@
 #include <linux/string.h>
 #include <linux/tty.h>
 #include <linux/errno.h>
+#include <linux/ethtool.h>
 #include <linux/netdevice.h>
 #include <linux/skbuff.h>
 #include <linux/rtnetlink.h>
@@ -790,6 +791,16 @@ static const struct net_device_ops slc_netdev_ops = {
 	.ndo_change_mtu         = slcan_change_mtu,
 };
 
+static void slcan_get_drvinfo(struct net_device *netdev,
+			      struct ethtool_drvinfo *drvinfo)
+{
+	strscpy(drvinfo->driver, DRV_NAME, sizeof(drvinfo->driver));
+}
+
+static const struct ethtool_ops slcan_ethtool_ops = {
+	.get_drvinfo = slcan_get_drvinfo,
+};
+
 /******************************************
  *  Routines looking at TTY side.
  ******************************************/
@@ -869,6 +880,7 @@ static struct slcan *slc_alloc(void)
 
 	snprintf(dev->name, sizeof(dev->name), DRV_NAME "%d", i);
 	dev->netdev_ops = &slc_netdev_ops;
+	dev->ethtool_ops = &slcan_ethtool_ops;
 	dev->base_addr  = i;
 	slcan_set_ethtool_ops(dev);
 	sl = netdev_priv(dev);
diff --git a/drivers/net/can/softing/softing_main.c b/drivers/net/can/softing/softing_main.c
index d810fe6915a4..d2ce61562ccc 100644
--- a/drivers/net/can/softing/softing_main.c
+++ b/drivers/net/can/softing/softing_main.c
@@ -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>
@@ -612,6 +613,16 @@ static const struct net_device_ops softing_netdev_ops = {
 	.ndo_change_mtu = can_change_mtu,
 };
 
+static void softing_get_drvinfo(struct net_device *netdev,
+				struct ethtool_drvinfo *drvinfo)
+{
+	strscpy(drvinfo->driver, DRV_NAME, sizeof(drvinfo->driver));
+}
+
+static const struct ethtool_ops softing_ethtool_ops = {
+	.get_drvinfo = softing_get_drvinfo,
+};
+
 static const struct can_bittiming_const softing_btr_const = {
 	.name = DRV_NAME,
 	.tseg1_min = 1,
@@ -650,6 +661,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;
 
diff --git a/drivers/net/can/spi/hi311x.c b/drivers/net/can/spi/hi311x.c
index 167114aae6dd..5e0c0d21aee2 100644
--- a/drivers/net/can/spi/hi311x.c
+++ b/drivers/net/can/spi/hi311x.c
@@ -20,6 +20,7 @@
 #include <linux/completion.h>
 #include <linux/delay.h>
 #include <linux/device.h>
+#include <linux/ethtool.h>
 #include <linux/freezer.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
@@ -802,6 +803,16 @@ static const struct net_device_ops hi3110_netdev_ops = {
 	.ndo_start_xmit = hi3110_hard_start_xmit,
 };
 
+static void hi3110_get_drvinfo(struct net_device *netdev,
+			       struct ethtool_drvinfo *drvinfo)
+{
+	strscpy(drvinfo->driver, DEVICE_NAME, sizeof(drvinfo->driver));
+}
+
+static const struct ethtool_ops hi3110_ethtool_ops = {
+	.get_drvinfo = hi3110_get_drvinfo,
+};
+
 static const struct of_device_id hi3110_of_match[] = {
 	{
 		.compatible	= "holt,hi3110",
@@ -856,6 +867,7 @@ static int hi3110_can_probe(struct spi_device *spi)
 		goto out_free;
 
 	net->netdev_ops = &hi3110_netdev_ops;
+	net->ethtool_ops = &hi3110_ethtool_ops;
 	net->flags |= IFF_ECHO;
 
 	priv = netdev_priv(net);
diff --git a/drivers/net/can/spi/mcp251x.c b/drivers/net/can/spi/mcp251x.c
index 666a4505a55a..2e4c03c61b15 100644
--- a/drivers/net/can/spi/mcp251x.c
+++ b/drivers/net/can/spi/mcp251x.c
@@ -26,6 +26,7 @@
 #include <linux/completion.h>
 #include <linux/delay.h>
 #include <linux/device.h>
+#include <linux/ethtool.h>
 #include <linux/freezer.h>
 #include <linux/gpio.h>
 #include <linux/gpio/driver.h>
@@ -1248,6 +1249,16 @@ static const struct net_device_ops mcp251x_netdev_ops = {
 	.ndo_change_mtu = can_change_mtu,
 };
 
+static void mcp251x_get_drvinfo(struct net_device *netdev,
+				struct ethtool_drvinfo *drvinfo)
+{
+	strscpy(drvinfo->driver, DEVICE_NAME, sizeof(drvinfo->driver));
+}
+
+static const struct ethtool_ops mcp251x_ethtool_ops = {
+	.get_drvinfo = mcp251x_get_drvinfo,
+};
+
 static const struct of_device_id mcp251x_of_match[] = {
 	{
 		.compatible	= "microchip,mcp2510",
@@ -1313,6 +1324,7 @@ static int mcp251x_can_probe(struct spi_device *spi)
 		goto out_free;
 
 	net->netdev_ops = &mcp251x_netdev_ops;
+	net->ethtool_ops = &mcp251x_ethtool_ops;
 	net->flags |= IFF_ECHO;
 
 	priv = netdev_priv(net);
diff --git a/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c b/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c
index 7fc86ed405c6..d9a7de1927d6 100644
--- a/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c
+++ b/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c
@@ -16,6 +16,7 @@
 #include <linux/bitfield.h>
 #include <linux/clk.h>
 #include <linux/device.h>
+#include <linux/ethtool.h>
 #include <linux/mod_devicetable.h>
 #include <linux/module.h>
 #include <linux/pm_runtime.h>
@@ -1674,6 +1675,16 @@ static const struct net_device_ops mcp251xfd_netdev_ops = {
 	.ndo_change_mtu = can_change_mtu,
 };
 
+static void mcp251xfd_get_drvinfo(struct net_device *netdev,
+				  struct ethtool_drvinfo *drvinfo)
+{
+	strscpy(drvinfo->driver, DEVICE_NAME, sizeof(drvinfo->driver));
+}
+
+static const struct ethtool_ops mcp251xfd_ethtool_ops = {
+	.get_drvinfo = mcp251xfd_get_drvinfo,
+};
+
 static void
 mcp251xfd_register_quirks(struct mcp251xfd_priv *priv)
 {
@@ -2050,6 +2061,7 @@ static int mcp251xfd_probe(struct spi_device *spi)
 	SET_NETDEV_DEV(ndev, &spi->dev);
 
 	ndev->netdev_ops = &mcp251xfd_netdev_ops;
+	ndev->ethtool_ops = &mcp251xfd_ethtool_ops;
 	ndev->irq = spi->irq;
 	ndev->flags |= IFF_ECHO;
 
diff --git a/drivers/net/can/sun4i_can.c b/drivers/net/can/sun4i_can.c
index b90dfb429ccd..27ea4e68b516 100644
--- a/drivers/net/can/sun4i_can.c
+++ b/drivers/net/can/sun4i_can.c
@@ -53,6 +53,7 @@
 #include <linux/can/error.h>
 #include <linux/clk.h>
 #include <linux/delay.h>
+#include <linux/ethtool.h>
 #include <linux/interrupt.h>
 #include <linux/init.h>
 #include <linux/io.h>
@@ -761,6 +762,16 @@ static const struct net_device_ops sun4ican_netdev_ops = {
 	.ndo_start_xmit = sun4ican_start_xmit,
 };
 
+static void sun4ican_get_drvinfo(struct net_device *netdev,
+				 struct ethtool_drvinfo *drvinfo)
+{
+	strscpy(drvinfo->driver, DRV_NAME, sizeof(drvinfo->driver));
+}
+
+static const struct ethtool_ops sun4ican_ethtool_ops = {
+	.get_drvinfo = sun4ican_get_drvinfo,
+};
+
 static const struct sun4ican_quirks sun4ican_quirks_a10 = {
 	.has_reset = false,
 };
@@ -851,6 +862,7 @@ static int sun4ican_probe(struct platform_device *pdev)
 	}
 
 	dev->netdev_ops = &sun4ican_netdev_ops;
+	dev->ethtool_ops = &sun4ican_ethtool_ops;
 	dev->irq = irq;
 	dev->flags |= IFF_ECHO;
 
diff --git a/drivers/net/can/ti_hecc.c b/drivers/net/can/ti_hecc.c
index afa38771520e..965376453050 100644
--- a/drivers/net/can/ti_hecc.c
+++ b/drivers/net/can/ti_hecc.c
@@ -23,6 +23,7 @@
 #include <linux/types.h>
 #include <linux/interrupt.h>
 #include <linux/errno.h>
+#include <linux/ethtool.h>
 #include <linux/netdevice.h>
 #include <linux/skbuff.h>
 #include <linux/platform_device.h>
@@ -841,6 +842,16 @@ static const struct net_device_ops ti_hecc_netdev_ops = {
 	.ndo_change_mtu		= can_change_mtu,
 };
 
+static void ti_hecc_get_drvinfo(struct net_device *netdev,
+				struct ethtool_drvinfo *drvinfo)
+{
+	strscpy(drvinfo->driver, DRV_NAME, sizeof(drvinfo->driver));
+}
+
+static const struct ethtool_ops ti_hecc_ethtool_ops = {
+	.get_drvinfo = ti_hecc_get_drvinfo,
+};
+
 static const struct of_device_id ti_hecc_dt_ids[] = {
 	{
 		.compatible = "ti,am3517-hecc",
@@ -918,6 +929,7 @@ static int ti_hecc_probe(struct platform_device *pdev)
 	platform_set_drvdata(pdev, ndev);
 	SET_NETDEV_DEV(ndev, &pdev->dev);
 	ndev->netdev_ops = &ti_hecc_netdev_ops;
+	ndev->ethtool_ops = &ti_hecc_ethtool_ops;
 
 	priv->clk = clk_get(&pdev->dev, "hecc_ck");
 	if (IS_ERR(priv->clk)) {
diff --git a/drivers/net/can/usb/ems_usb.c b/drivers/net/can/usb/ems_usb.c
index e86a2033db60..ac155f73bedd 100644
--- a/drivers/net/can/usb/ems_usb.c
+++ b/drivers/net/can/usb/ems_usb.c
@@ -4,6 +4,7 @@
  *
  * Copyright (C) 2004-2009 EMS Dr. Thomas Wuensche
  */
+#include <linux/ethtool.h>
 #include <linux/signal.h>
 #include <linux/slab.h>
 #include <linux/module.h>
@@ -879,6 +880,16 @@ static const struct net_device_ops ems_usb_netdev_ops = {
 	.ndo_change_mtu = can_change_mtu,
 };
 
+static void ems_usb_get_drvinfo(struct net_device *netdev,
+				struct ethtool_drvinfo *drvinfo)
+{
+	strscpy(drvinfo->driver, KBUILD_MODNAME, sizeof(drvinfo->driver));
+}
+
+static const struct ethtool_ops ems_usb_ethtool_ops = {
+	.get_drvinfo = ems_usb_get_drvinfo,
+};
+
 static const struct can_bittiming_const ems_usb_bittiming_const = {
 	.name = KBUILD_MODNAME,
 	.tseg1_min = 1,
@@ -990,6 +1001,7 @@ static int ems_usb_probe(struct usb_interface *intf,
 	dev->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES;
 
 	netdev->netdev_ops = &ems_usb_netdev_ops;
+	netdev->ethtool_ops = &ems_usb_ethtool_ops;
 
 	netdev->flags |= IFF_ECHO; /* we support local echo */
 
diff --git a/drivers/net/can/usb/esd_usb.c b/drivers/net/can/usb/esd_usb.c
index 7b849bd3cc9c..2367edd49eb7 100644
--- a/drivers/net/can/usb/esd_usb.c
+++ b/drivers/net/can/usb/esd_usb.c
@@ -5,6 +5,7 @@
  * 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>
  */
+#include <linux/ethtool.h>
 #include <linux/signal.h>
 #include <linux/slab.h>
 #include <linux/module.h>
@@ -882,6 +883,16 @@ static const struct net_device_ops esd_usb_netdev_ops = {
 	.ndo_change_mtu = can_change_mtu,
 };
 
+static void esd_usb_get_drvinfo(struct net_device *netdev,
+				struct ethtool_drvinfo *drvinfo)
+{
+	strscpy(drvinfo->driver, KBUILD_MODNAME, sizeof(drvinfo->driver));
+}
+
+static const struct ethtool_ops esd_usb_ethtool_ops = {
+	.get_drvinfo = esd_usb_get_drvinfo,
+};
+
 static const struct can_bittiming_const esd_usb2_bittiming_const = {
 	.name = "esd_usb2",
 	.tseg1_min = ESD_USB2_TSEG1_MIN,
@@ -1015,6 +1026,7 @@ static int esd_usb_probe_one_net(struct usb_interface *intf, int index)
 	netdev->flags |= IFF_ECHO; /* we support local echo */
 
 	netdev->netdev_ops = &esd_usb_netdev_ops;
+	netdev->ethtool_ops = &esd_usb_ethtool_ops;
 
 	SET_NETDEV_DEV(netdev, &intf->dev);
 	netdev->dev_id = index;
diff --git a/drivers/net/can/usb/etas_es58x/es58x_core.c b/drivers/net/can/usb/etas_es58x/es58x_core.c
index 3f51488bd649..0e692c2dc54d 100644
--- a/drivers/net/can/usb/etas_es58x/es58x_core.c
+++ b/drivers/net/can/usb/etas_es58x/es58x_core.c
@@ -10,6 +10,7 @@
  * Copyright (c) 2020, 2021 Vincent Mailhol <mailhol.vincent@wanadoo.fr>
  */
 
+#include <linux/ethtool.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/usb.h>
@@ -1982,6 +1983,16 @@ static const struct net_device_ops es58x_netdev_ops = {
 	.ndo_start_xmit = es58x_start_xmit
 };
 
+static void es58x_get_drvinfo(struct net_device *netdev,
+			      struct ethtool_drvinfo *drvinfo)
+{
+	strscpy(drvinfo->driver, ES58X_MODULE_NAME, sizeof(drvinfo->driver));
+}
+
+static const struct ethtool_ops es58x_ethtool_ops = {
+	.get_drvinfo = es58x_get_drvinfo,
+};
+
 /**
  * es58x_set_mode() - Change network device mode.
  * @netdev: CAN network device.
@@ -2086,6 +2097,7 @@ static int es58x_init_netdev(struct es58x_device *es58x_dev, int channel_idx)
 	es58x_init_priv(es58x_dev, es58x_priv(netdev), channel_idx);
 
 	netdev->netdev_ops = &es58x_netdev_ops;
+	netdev->ethtool_ops = &es58x_ethtool_ops;
 	netdev->flags |= IFF_ECHO;	/* We support local echo */
 	netdev->dev_port = channel_idx;
 
diff --git a/drivers/net/can/usb/gs_usb.c b/drivers/net/can/usb/gs_usb.c
index fd239b523c42..75f5e9c5059a 100644
--- a/drivers/net/can/usb/gs_usb.c
+++ b/drivers/net/can/usb/gs_usb.c
@@ -924,6 +924,12 @@ static int gs_usb_set_identify(struct net_device *netdev, bool do_identify)
 	return (rc > 0) ? 0 : rc;
 }
 
+static void gs_usb_get_drvinfo(struct net_device *netdev,
+			       struct ethtool_drvinfo *drvinfo)
+{
+	strscpy(drvinfo->driver, KBUILD_MODNAME, sizeof(drvinfo->driver));
+}
+
 /* blink LED's for finding the this interface */
 static int gs_usb_set_phys_id(struct net_device *dev,
 			      enum ethtool_phys_id_state state)
@@ -945,6 +951,7 @@ static int gs_usb_set_phys_id(struct net_device *dev,
 }
 
 static const struct ethtool_ops gs_usb_ethtool_ops = {
+	.get_drvinfo = gs_usb_get_drvinfo,
 	.set_phys_id = gs_usb_set_phys_id,
 };
 
@@ -989,6 +996,7 @@ static struct gs_can *gs_make_candev(unsigned int channel,
 	dev = netdev_priv(netdev);
 
 	netdev->netdev_ops = &gs_usb_netdev_ops;
+	netdev->ethtool_ops = &gs_usb_ethtool_ops;
 
 	netdev->flags |= IFF_ECHO; /* we support full roundtrip echo */
 
diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c b/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c
index a6cff8da5a41..964c0026383e 100644
--- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c
+++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c
@@ -13,6 +13,7 @@
 
 #include <linux/completion.h>
 #include <linux/device.h>
+#include <linux/ethtool.h>
 #include <linux/gfp.h>
 #include <linux/if.h>
 #include <linux/kernel.h>
@@ -667,6 +668,16 @@ static const struct net_device_ops kvaser_usb_netdev_ops = {
 	.ndo_change_mtu = can_change_mtu,
 };
 
+static void kvaser_usb_get_drvinfo(struct net_device *netdev,
+				   struct ethtool_drvinfo *drvinfo)
+{
+	strscpy(drvinfo->driver, DRV_NAME, sizeof(drvinfo->driver));
+}
+
+static const struct ethtool_ops kvaser_usb_ethtool_ops = {
+	.get_drvinfo = kvaser_usb_get_drvinfo,
+};
+
 static void kvaser_usb_remove_interfaces(struct kvaser_usb *dev)
 {
 	int i;
@@ -744,6 +755,7 @@ static int kvaser_usb_init_one(struct kvaser_usb *dev, int channel)
 	netdev->flags |= IFF_ECHO;
 
 	netdev->netdev_ops = &kvaser_usb_netdev_ops;
+	netdev->ethtool_ops = &kvaser_usb_ethtool_ops;
 
 	SET_NETDEV_DEV(netdev, &dev->intf->dev);
 	netdev->dev_id = channel;
diff --git a/drivers/net/can/usb/mcba_usb.c b/drivers/net/can/usb/mcba_usb.c
index 792ab9da317d..485ec697fc08 100644
--- a/drivers/net/can/usb/mcba_usb.c
+++ b/drivers/net/can/usb/mcba_usb.c
@@ -10,6 +10,7 @@
 #include <linux/can.h>
 #include <linux/can/dev.h>
 #include <linux/can/error.h>
+#include <linux/ethtool.h>
 #include <linux/module.h>
 #include <linux/netdevice.h>
 #include <linux/signal.h>
@@ -758,6 +759,16 @@ static const struct net_device_ops mcba_netdev_ops = {
 	.ndo_start_xmit = mcba_usb_start_xmit,
 };
 
+static void mcba_get_drvinfo(struct net_device *netdev,
+			     struct ethtool_drvinfo *drvinfo)
+{
+	strscpy(drvinfo->driver, MCBA_MODULE_NAME, sizeof(drvinfo->driver));
+}
+
+static const struct ethtool_ops mcba_ethtool_ops = {
+	.get_drvinfo = mcba_get_drvinfo,
+};
+
 /* Microchip CANBUS has hardcoded bittiming values by default.
  * This function sends request via USB to change the speed and align bittiming
  * values for presentation purposes only
@@ -836,6 +847,7 @@ static int mcba_usb_probe(struct usb_interface *intf,
 	priv->can.do_set_bittiming = mcba_net_set_bittiming;
 
 	netdev->netdev_ops = &mcba_netdev_ops;
+	netdev->ethtool_ops = &mcba_ethtool_ops;
 
 	netdev->flags |= IFF_ECHO; /* we support local echo */
 
diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_core.c b/drivers/net/can/usb/peak_usb/pcan_usb_core.c
index 27b0a72fd885..959448bae3ca 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb_core.c
+++ b/drivers/net/can/usb/peak_usb/pcan_usb_core.c
@@ -782,6 +782,12 @@ static const struct net_device_ops peak_usb_netdev_ops = {
 	.ndo_change_mtu = can_change_mtu,
 };
 
+void peak_usb_get_drvinfo(struct net_device *netdev,
+			  struct ethtool_drvinfo *drvinfo)
+{
+	strscpy(drvinfo->driver, PCAN_USB_DRIVER_NAME, sizeof(drvinfo->driver));
+}
+
 /*
  * create one device which is attached to CAN controller #ctrl_idx of the
  * usb adapter.
diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_core.h b/drivers/net/can/usb/peak_usb/pcan_usb_core.h
index 9c90487b9c92..da1205575379 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb_core.h
+++ b/drivers/net/can/usb/peak_usb/pcan_usb_core.h
@@ -145,5 +145,7 @@ int peak_usb_netif_rx(struct sk_buff *skb,
 int peak_usb_netif_rx_64(struct sk_buff *skb, u32 ts_low, u32 ts_high);
 void peak_usb_async_complete(struct urb *urb);
 void peak_usb_restart_complete(struct peak_usb_device *dev);
+void peak_usb_get_drvinfo(struct net_device *netdev,
+			  struct ethtool_drvinfo *drvinfo);
 
 #endif
diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_fd.c b/drivers/net/can/usb/peak_usb/pcan_usb_fd.c
index 3d7e0e370505..63122f567380 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb_fd.c
+++ b/drivers/net/can/usb/peak_usb/pcan_usb_fd.c
@@ -1079,6 +1079,7 @@ static int pcan_usb_fd_set_phys_id(struct net_device *netdev,
 }
 
 static const struct ethtool_ops pcan_usb_fd_ethtool_ops = {
+	.get_drvinfo = peak_usb_get_drvinfo,
 	.set_phys_id = pcan_usb_fd_set_phys_id,
 };
 
diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_pro.c b/drivers/net/can/usb/peak_usb/pcan_usb_pro.c
index 457887113e75..ea2d4fbceaa4 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb_pro.c
+++ b/drivers/net/can/usb/peak_usb/pcan_usb_pro.c
@@ -1021,6 +1021,7 @@ static int pcan_usb_pro_set_phys_id(struct net_device *netdev,
 }
 
 static const struct ethtool_ops pcan_usb_pro_ethtool_ops = {
+	.get_drvinfo = peak_usb_get_drvinfo,
 	.set_phys_id = pcan_usb_pro_set_phys_id,
 };
 
diff --git a/drivers/net/can/usb/ucan.c b/drivers/net/can/usb/ucan.c
index 5ae0d7c017cc..52263fa286f3 100644
--- a/drivers/net/can/usb/ucan.c
+++ b/drivers/net/can/usb/ucan.c
@@ -28,6 +28,7 @@
 #include <linux/can.h>
 #include <linux/can/dev.h>
 #include <linux/can/error.h>
+#include <linux/ethtool.h>
 #include <linux/module.h>
 #include <linux/netdevice.h>
 #include <linux/signal.h>
@@ -1233,6 +1234,16 @@ static const struct net_device_ops ucan_netdev_ops = {
 	.ndo_change_mtu = can_change_mtu,
 };
 
+static void ucan_get_drvinfo(struct net_device *netdev,
+			     struct ethtool_drvinfo *drvinfo)
+{
+	strscpy(drvinfo->driver, UCAN_DRIVER_NAME, sizeof(drvinfo->driver));
+}
+
+static const struct ethtool_ops ucan_ethtool_ops = {
+	.get_drvinfo = ucan_get_drvinfo,
+};
+
 /* Request to set bittiming
  *
  * This function generates an USB set bittiming message and transmits
@@ -1512,6 +1523,7 @@ static int ucan_probe(struct usb_interface *intf,
 	spin_lock_init(&up->context_lock);
 	spin_lock_init(&up->echo_skb_lock);
 	netdev->netdev_ops = &ucan_netdev_ops;
+	netdev->ethtool_ops = &ucan_ethtool_ops;
 
 	usb_set_intfdata(intf, up);
 	SET_NETDEV_DEV(netdev, &intf->dev);
diff --git a/drivers/net/can/usb/usb_8dev.c b/drivers/net/can/usb/usb_8dev.c
index 6665a66745a7..2a56d7c2fdb6 100644
--- a/drivers/net/can/usb/usb_8dev.c
+++ b/drivers/net/can/usb/usb_8dev.c
@@ -12,6 +12,7 @@
  * who were very cooperative and answered my questions.
  */
 
+#include <linux/ethtool.h>
 #include <linux/signal.h>
 #include <linux/slab.h>
 #include <linux/module.h>
@@ -870,6 +871,16 @@ static const struct net_device_ops usb_8dev_netdev_ops = {
 	.ndo_change_mtu = can_change_mtu,
 };
 
+static void usb_8dev_get_drvinfo(struct net_device *netdev,
+				 struct ethtool_drvinfo *drvinfo)
+{
+	strscpy(drvinfo->driver, KBUILD_MODNAME, sizeof(drvinfo->driver));
+}
+
+static const struct ethtool_ops usb_8dev_ethtool_ops = {
+	.get_drvinfo = usb_8dev_get_drvinfo,
+};
+
 static const struct can_bittiming_const usb_8dev_bittiming_const = {
 	.name = KBUILD_MODNAME,
 	.tseg1_min = 1,
@@ -927,6 +938,7 @@ static int usb_8dev_probe(struct usb_interface *intf,
 				      CAN_CTRLMODE_CC_LEN8_DLC;
 
 	netdev->netdev_ops = &usb_8dev_netdev_ops;
+	netdev->ethtool_ops = &usb_8dev_ethtool_ops;
 
 	netdev->flags |= IFF_ECHO; /* we support local echo */
 
diff --git a/drivers/net/can/vcan.c b/drivers/net/can/vcan.c
index a15619d883ec..6827c717af44 100644
--- a/drivers/net/can/vcan.c
+++ b/drivers/net/can/vcan.c
@@ -40,6 +40,7 @@
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
+#include <linux/ethtool.h>
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/netdevice.h>
@@ -146,6 +147,16 @@ static const struct net_device_ops vcan_netdev_ops = {
 	.ndo_change_mtu = vcan_change_mtu,
 };
 
+static void vcan_get_drvinfo(struct net_device *netdev,
+			     struct ethtool_drvinfo *drvinfo)
+{
+	strscpy(drvinfo->driver, KBUILD_MODNAME, sizeof(drvinfo->driver));
+}
+
+static const struct ethtool_ops vcan_ethtool_ops = {
+	.get_drvinfo = vcan_get_drvinfo,
+};
+
 static void vcan_setup(struct net_device *dev)
 {
 	dev->type		= ARPHRD_CAN;
@@ -161,6 +172,7 @@ static void vcan_setup(struct net_device *dev)
 		dev->flags |= IFF_ECHO;
 
 	dev->netdev_ops		= &vcan_netdev_ops;
+	dev->ethtool_ops	= &vcan_ethtool_ops;
 	dev->needs_free_netdev	= true;
 }
 
diff --git a/drivers/net/can/vxcan.c b/drivers/net/can/vxcan.c
index 577a80300514..a221c00fe660 100644
--- a/drivers/net/can/vxcan.c
+++ b/drivers/net/can/vxcan.c
@@ -9,6 +9,7 @@
  * Copyright (c) 2017 Oliver Hartkopp <socketcan@hartkopp.net>
  */
 
+#include <linux/ethtool.h>
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/netdevice.h>
@@ -144,6 +145,16 @@ static const struct net_device_ops vxcan_netdev_ops = {
 	.ndo_change_mtu = vxcan_change_mtu,
 };
 
+static void vxcan_get_drvinfo(struct net_device *netdev,
+			      struct ethtool_drvinfo *drvinfo)
+{
+	strscpy(drvinfo->driver, KBUILD_MODNAME, sizeof(drvinfo->driver));
+}
+
+static const struct ethtool_ops vxcan_ethtool_ops = {
+	.get_drvinfo = vxcan_get_drvinfo,
+};
+
 static void vxcan_setup(struct net_device *dev)
 {
 	struct can_ml_priv *can_ml;
@@ -155,6 +166,7 @@ static void vxcan_setup(struct net_device *dev)
 	dev->tx_queue_len	= 0;
 	dev->flags		= IFF_NOARP;
 	dev->netdev_ops		= &vxcan_netdev_ops;
+	dev->ethtool_ops	= &vxcan_ethtool_ops;
 	dev->needs_free_netdev	= true;
 
 	can_ml = netdev_priv(dev) + ALIGN(sizeof(struct vxcan_priv), NETDEV_ALIGN);
diff --git a/drivers/net/can/xilinx_can.c b/drivers/net/can/xilinx_can.c
index caa6b4cee63f..b802ddec1965 100644
--- a/drivers/net/can/xilinx_can.c
+++ b/drivers/net/can/xilinx_can.c
@@ -12,6 +12,7 @@
 #include <linux/bitfield.h>
 #include <linux/clk.h>
 #include <linux/errno.h>
+#include <linux/ethtool.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
@@ -1540,6 +1541,16 @@ static const struct net_device_ops xcan_netdev_ops = {
 	.ndo_change_mtu	= can_change_mtu,
 };
 
+static void xcan_get_drvinfo(struct net_device *netdev,
+			     struct ethtool_drvinfo *drvinfo)
+{
+	strscpy(drvinfo->driver, DRIVER_NAME, sizeof(drvinfo->driver));
+}
+
+static const struct ethtool_ops xcan_ethtool_ops = {
+	.get_drvinfo = xcan_get_drvinfo,
+};
+
 /**
  * xcan_suspend - Suspend method for the driver
  * @dev:	Address of the device structure
@@ -1821,6 +1832,7 @@ static int xcan_probe(struct platform_device *pdev)
 	platform_set_drvdata(pdev, ndev);
 	SET_NETDEV_DEV(ndev, &pdev->dev);
 	ndev->netdev_ops = &xcan_netdev_ops;
+	ndev->ethtool_ops = &xcan_ethtool_ops;
 
 	/* Getting the CAN can_clk info */
 	priv->can_clk = devm_clk_get(&pdev->dev, "can_clk");
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 92+ messages in thread

* [PATCH v1 11/24] can: can327: add software tx timestamps
  2022-07-25 13:31 [PATCH v1 00/24] can: add ethtool support and reporting of timestamping capabilities Vincent Mailhol
                   ` (9 preceding siblings ...)
  2022-07-25 13:31 ` [PATCH v1 10/24] can: tree-wide: implement ethtool_ops::get_drvinfo() Vincent Mailhol
@ 2022-07-25 13:31 ` Vincent Mailhol
  2022-07-25 13:31 ` [PATCH v1 12/24] can: janz-ican3: add software tx timestamp Vincent Mailhol
                   ` (16 subsequent siblings)
  27 siblings, 0 replies; 92+ messages in thread
From: Vincent Mailhol @ 2022-07-25 13:31 UTC (permalink / raw)
  To: linux-can, Marc Kleine-Budde
  Cc: Stephane Grosjean, Jimmy Assarsson, Oliver Hartkopp,
	Dario Binacchi, Max Staudt, Vincent Mailhol

TX timestamps were added to the can_put_echo_skb() function of can_dev
modules in [1]. However, can327 does not rely on that function and as
such does not offer TX timestamping.

Add a call to skb_tx_timestamp() in the can327_netdev_start_xmit()
function so that the module now supports TX software timestamps.

[1] commit 741b91f1b0ea ("can: dev: can_put_echo_skb(): add software
tx timestamps")
Link: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=741b91f1b0ea34f00f6a7d4539b767c409291fcf

Signed-off-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
---
 drivers/net/can/can327.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/net/can/can327.c b/drivers/net/can/can327.c
index 03c9e8c6990d..497a298c3de7 100644
--- a/drivers/net/can/can327.c
+++ b/drivers/net/can/can327.c
@@ -836,6 +836,8 @@ static netdev_tx_t can327_netdev_start_xmit(struct sk_buff *skb,
 	dev->stats.tx_packets++;
 	dev->stats.tx_bytes += frame->can_id & CAN_RTR_FLAG ? 0 : frame->len;
 
+	skb_tx_timestamp(skb);
+
 out:
 	kfree_skb(skb);
 	return NETDEV_TX_OK;
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 92+ messages in thread

* [PATCH v1 12/24] can: janz-ican3: add software tx timestamp
  2022-07-25 13:31 [PATCH v1 00/24] can: add ethtool support and reporting of timestamping capabilities Vincent Mailhol
                   ` (10 preceding siblings ...)
  2022-07-25 13:31 ` [PATCH v1 11/24] can: can327: add software tx timestamps Vincent Mailhol
@ 2022-07-25 13:31 ` Vincent Mailhol
  2022-07-25 13:31 ` [PATCH v1 13/24] can: slcan: add software tx timestamps Vincent Mailhol
                   ` (15 subsequent siblings)
  27 siblings, 0 replies; 92+ messages in thread
From: Vincent Mailhol @ 2022-07-25 13:31 UTC (permalink / raw)
  To: linux-can, Marc Kleine-Budde
  Cc: Stephane Grosjean, Jimmy Assarsson, Oliver Hartkopp,
	Dario Binacchi, Max Staudt, Vincent Mailhol

TX timestamps were added to the can_put_echo_skb() function of can_dev
modules in [1]. However, janz-ican3 does not rely on that function but
instead implements its own echo_skb logic. As such it does not offer
TX timestamping.

Add a call to skb_tx_timestamp() in the ican3_put_echo_skb() function
so that the module now supports TX software timestamps.

[1] commit 741b91f1b0ea ("can: dev: can_put_echo_skb(): add software
tx timestamps")
Link: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=741b91f1b0ea34f00f6a7d4539b767c409291fcf

Signed-off-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
---
 drivers/net/can/janz-ican3.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/net/can/janz-ican3.c b/drivers/net/can/janz-ican3.c
index 2534364e8be3..923df896512f 100644
--- a/drivers/net/can/janz-ican3.c
+++ b/drivers/net/can/janz-ican3.c
@@ -1278,6 +1278,8 @@ static void ican3_put_echo_skb(struct ican3_dev *mod, struct sk_buff *skb)
 	if (!skb)
 		return;
 
+	skb_tx_timestamp(skb);
+
 	/* save this skb for tx interrupt echo handling */
 	skb_queue_tail(&mod->echoq, skb);
 }
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 92+ messages in thread

* [PATCH v1 13/24] can: slcan: add software tx timestamps
  2022-07-25 13:31 [PATCH v1 00/24] can: add ethtool support and reporting of timestamping capabilities Vincent Mailhol
                   ` (11 preceding siblings ...)
  2022-07-25 13:31 ` [PATCH v1 12/24] can: janz-ican3: add software tx timestamp Vincent Mailhol
@ 2022-07-25 13:31 ` Vincent Mailhol
  2022-07-25 13:31 ` [PATCH v1 14/24] can: v(x)can: " Vincent Mailhol
                   ` (14 subsequent siblings)
  27 siblings, 0 replies; 92+ messages in thread
From: Vincent Mailhol @ 2022-07-25 13:31 UTC (permalink / raw)
  To: linux-can, Marc Kleine-Budde
  Cc: Stephane Grosjean, Jimmy Assarsson, Oliver Hartkopp,
	Dario Binacchi, Max Staudt, Vincent Mailhol

TX timestamps were added to the can_put_echo_skb() function of can_dev
modules in [1]. However, slcan does not rely on that function and as
such does not offer TX timestamping.

Add a call to skb_tx_timestamp() in the slc_xmit() function so that
the module now supports TX software timestamps.

[1] commit 741b91f1b0ea ("can: dev: can_put_echo_skb(): add software
tx timestamps")
Link: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=741b91f1b0ea34f00f6a7d4539b767c409291fcf

CC: Dario Binacchi <dario.binacchi@amarulasolutions.com>
Signed-off-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
---
 drivers/net/can/slcan/slcan-core.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/net/can/slcan/slcan-core.c b/drivers/net/can/slcan/slcan-core.c
index 1b86001c85f8..65f466582fa2 100644
--- a/drivers/net/can/slcan/slcan-core.c
+++ b/drivers/net/can/slcan/slcan-core.c
@@ -630,6 +630,8 @@ static netdev_tx_t slc_xmit(struct sk_buff *skb, struct net_device *dev)
 	slc_encaps(sl, (struct can_frame *)skb->data); /* encaps & send */
 	spin_unlock(&sl->lock);
 
+	skb_tx_timestamp(skb);
+
 out:
 	kfree_skb(skb);
 	return NETDEV_TX_OK;
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 92+ messages in thread

* [PATCH v1 14/24] can: v(x)can: add software tx timestamps
  2022-07-25 13:31 [PATCH v1 00/24] can: add ethtool support and reporting of timestamping capabilities Vincent Mailhol
                   ` (12 preceding siblings ...)
  2022-07-25 13:31 ` [PATCH v1 13/24] can: slcan: add software tx timestamps Vincent Mailhol
@ 2022-07-25 13:31 ` Vincent Mailhol
  2022-07-25 13:31 ` [PATCH v1 15/24] can: tree-wide: advertise software timestamping capabilities Vincent Mailhol
                   ` (13 subsequent siblings)
  27 siblings, 0 replies; 92+ messages in thread
From: Vincent Mailhol @ 2022-07-25 13:31 UTC (permalink / raw)
  To: linux-can, Marc Kleine-Budde
  Cc: Stephane Grosjean, Jimmy Assarsson, Oliver Hartkopp,
	Dario Binacchi, Max Staudt, Vincent Mailhol

TX timestamps were added to the can_put_echo_skb() function of can_dev
modules in [1]. However, vcan and vxcan do not rely on that function
and as such do not offer TX timestamping.

While it could be arguable whether TX timestamps are really needed for
virtual interfaces, we prefer to still add it so that all CAN dirvers,
without exception supports the TX software timestamps.

Add a call to skb_tx_timestamp() in the vcan_tx() and vxcan_xmit()
functions so that the modules now support TX software timestamps.

[1] commit 741b91f1b0ea ("can: dev: can_put_echo_skb(): add software
tx timestamps")
Link: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=741b91f1b0ea34f00f6a7d4539b767c409291fcf

Signed-off-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
---
 drivers/net/can/vcan.c  | 2 ++
 drivers/net/can/vxcan.c | 2 ++
 2 files changed, 4 insertions(+)

diff --git a/drivers/net/can/vcan.c b/drivers/net/can/vcan.c
index 6827c717af44..e820b2621e53 100644
--- a/drivers/net/can/vcan.c
+++ b/drivers/net/can/vcan.c
@@ -100,6 +100,8 @@ static netdev_tx_t vcan_tx(struct sk_buff *skb, struct net_device *dev)
 	/* set flag whether this packet has to be looped back */
 	loop = skb->pkt_type == PACKET_LOOPBACK;
 
+	skb_tx_timestamp(skb);
+
 	if (!echo) {
 		/* no echo handling available inside this driver */
 		if (loop) {
diff --git a/drivers/net/can/vxcan.c b/drivers/net/can/vxcan.c
index a221c00fe660..aedeb9766996 100644
--- a/drivers/net/can/vxcan.c
+++ b/drivers/net/can/vxcan.c
@@ -54,6 +54,8 @@ static netdev_tx_t vxcan_xmit(struct sk_buff *oskb, struct net_device *dev)
 		goto out_unlock;
 	}
 
+	skb_tx_timestamp(oskb);
+
 	skb = skb_clone(oskb, GFP_ATOMIC);
 	if (skb) {
 		consume_skb(oskb);
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 92+ messages in thread

* [PATCH v1 15/24] can: tree-wide: advertise software timestamping capabilities
  2022-07-25 13:31 [PATCH v1 00/24] can: add ethtool support and reporting of timestamping capabilities Vincent Mailhol
                   ` (13 preceding siblings ...)
  2022-07-25 13:31 ` [PATCH v1 14/24] can: v(x)can: " Vincent Mailhol
@ 2022-07-25 13:31 ` Vincent Mailhol
  2022-07-25 13:32 ` [PATCH v1 16/24] can: dev: add hardware TX timestamp Vincent Mailhol
                   ` (12 subsequent siblings)
  27 siblings, 0 replies; 92+ messages in thread
From: Vincent Mailhol @ 2022-07-25 13:31 UTC (permalink / raw)
  To: linux-can, Marc Kleine-Budde
  Cc: Stephane Grosjean, Jimmy Assarsson, Oliver Hartkopp,
	Dario Binacchi, Max Staudt, Vincent Mailhol

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 timespamping will be migrated
in separate patches.

Signed-off-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
---
 drivers/net/can/at91_can.c               | 1 +
 drivers/net/can/c_can/c_can_main.c       | 1 +
 drivers/net/can/can327.c                 | 1 +
 drivers/net/can/cc770/cc770.c            | 1 +
 drivers/net/can/ctucanfd/ctucanfd_base.c | 1 +
 drivers/net/can/flexcan/flexcan-core.c   | 1 +
 drivers/net/can/grcan.c                  | 1 +
 drivers/net/can/ifi_canfd/ifi_canfd.c    | 1 +
 drivers/net/can/janz-ican3.c             | 1 +
 drivers/net/can/m_can/m_can.c            | 1 +
 drivers/net/can/pch_can.c                | 1 +
 drivers/net/can/rcar/rcar_can.c          | 1 +
 drivers/net/can/rcar/rcar_canfd.c        | 1 +
 drivers/net/can/sja1000/sja1000.c        | 1 +
 drivers/net/can/slcan/slcan-core.c       | 1 +
 drivers/net/can/softing/softing_main.c   | 1 +
 drivers/net/can/spi/hi311x.c             | 1 +
 drivers/net/can/spi/mcp251x.c            | 1 +
 drivers/net/can/sun4i_can.c              | 1 +
 drivers/net/can/ti_hecc.c                | 1 +
 drivers/net/can/usb/ems_usb.c            | 1 +
 drivers/net/can/usb/esd_usb.c            | 1 +
 drivers/net/can/usb/gs_usb.c             | 1 +
 drivers/net/can/usb/mcba_usb.c           | 1 +
 drivers/net/can/usb/ucan.c               | 1 +
 drivers/net/can/usb/usb_8dev.c           | 1 +
 drivers/net/can/vcan.c                   | 1 +
 drivers/net/can/vxcan.c                  | 1 +
 drivers/net/can/xilinx_can.c             | 1 +
 29 files changed, 29 insertions(+)

diff --git a/drivers/net/can/at91_can.c b/drivers/net/can/at91_can.c
index 637d2ca34d08..7fbf22401579 100644
--- a/drivers/net/can/at91_can.c
+++ b/drivers/net/can/at91_can.c
@@ -1161,6 +1161,7 @@ static void at91_get_drvinfo(struct net_device *netdev,
 
 static const struct ethtool_ops at91_ethtool_ops = {
 	.get_drvinfo = at91_get_drvinfo,
+	.get_ts_info = ethtool_op_get_ts_info,
 };
 
 static ssize_t mb0_id_show(struct device *dev,
diff --git a/drivers/net/can/c_can/c_can_main.c b/drivers/net/can/c_can/c_can_main.c
index fa541a7cb9c1..c828324d018f 100644
--- a/drivers/net/can/c_can/c_can_main.c
+++ b/drivers/net/can/c_can/c_can_main.c
@@ -1362,6 +1362,7 @@ static void c_can_get_drvinfo(struct net_device *netdev,
 
 static const struct ethtool_ops c_can_ethtool_ops = {
 	.get_drvinfo = c_can_get_drvinfo,
+	.get_ts_info = ethtool_op_get_ts_info,
 };
 
 int register_c_can_dev(struct net_device *dev)
diff --git a/drivers/net/can/can327.c b/drivers/net/can/can327.c
index 497a298c3de7..fbf61437b1e0 100644
--- a/drivers/net/can/can327.c
+++ b/drivers/net/can/can327.c
@@ -858,6 +858,7 @@ static void can327_get_drvinfo(struct net_device *netdev,
 
 static const struct ethtool_ops can327_ethtool_ops = {
 	.get_drvinfo = can327_get_drvinfo,
+	.get_ts_info = ethtool_op_get_ts_info,
 };
 
 static bool can327_is_valid_rx_char(u8 c)
diff --git a/drivers/net/can/cc770/cc770.c b/drivers/net/can/cc770/cc770.c
index 1bb30e69cb24..e57d1f3f4268 100644
--- a/drivers/net/can/cc770/cc770.c
+++ b/drivers/net/can/cc770/cc770.c
@@ -845,6 +845,7 @@ static void cc770_get_drvinfo(struct net_device *netdev,
 
 static const struct ethtool_ops cc770_ethtool_ops = {
 	.get_drvinfo = cc770_get_drvinfo,
+	.get_ts_info = ethtool_op_get_ts_info,
 };
 
 int register_cc770dev(struct net_device *dev)
diff --git a/drivers/net/can/ctucanfd/ctucanfd_base.c b/drivers/net/can/ctucanfd/ctucanfd_base.c
index fd5fd17c16f2..6b579e0da967 100644
--- a/drivers/net/can/ctucanfd/ctucanfd_base.c
+++ b/drivers/net/can/ctucanfd/ctucanfd_base.c
@@ -1310,6 +1310,7 @@ static void ctucan_get_drvinfo(struct net_device *netdev,
 
 static const struct ethtool_ops ctucan_ethtool_ops = {
 	.get_drvinfo = ctucan_get_drvinfo,
+	.get_ts_info = ethtool_op_get_ts_info,
 };
 
 int ctucan_suspend(struct device *dev)
diff --git a/drivers/net/can/flexcan/flexcan-core.c b/drivers/net/can/flexcan/flexcan-core.c
index 61e3483802c6..bec3166c0293 100644
--- a/drivers/net/can/flexcan/flexcan-core.c
+++ b/drivers/net/can/flexcan/flexcan-core.c
@@ -1822,6 +1822,7 @@ static void flexcan_get_drvinfo(struct net_device *netdev,
 
 static const struct ethtool_ops flexcan_ethtool_ops = {
 	.get_drvinfo = flexcan_get_drvinfo,
+	.get_ts_info = ethtool_op_get_ts_info,
 };
 
 static int register_flexcandev(struct net_device *dev)
diff --git a/drivers/net/can/grcan.c b/drivers/net/can/grcan.c
index ce64f2cbe9c6..f755e15860b7 100644
--- a/drivers/net/can/grcan.c
+++ b/drivers/net/can/grcan.c
@@ -1570,6 +1570,7 @@ static void grcan_get_drvinfo(struct net_device *netdev,
 
 static const struct ethtool_ops grcan_ethtool_ops = {
 	.get_drvinfo = grcan_get_drvinfo,
+	.get_ts_info = ethtool_op_get_ts_info,
 };
 
 static int grcan_setup_netdev(struct platform_device *ofdev,
diff --git a/drivers/net/can/ifi_canfd/ifi_canfd.c b/drivers/net/can/ifi_canfd/ifi_canfd.c
index c682401eea3d..0a4d4a52c296 100644
--- a/drivers/net/can/ifi_canfd/ifi_canfd.c
+++ b/drivers/net/can/ifi_canfd/ifi_canfd.c
@@ -934,6 +934,7 @@ static void ifi_canfd_get_drvinfo(struct net_device *netdev,
 
 static const struct ethtool_ops ifi_canfd_ethtool_ops = {
 	.get_drvinfo = ifi_canfd_get_drvinfo,
+	.get_ts_info = ethtool_op_get_ts_info,
 };
 
 static int ifi_canfd_plat_probe(struct platform_device *pdev)
diff --git a/drivers/net/can/janz-ican3.c b/drivers/net/can/janz-ican3.c
index 923df896512f..f2056d366369 100644
--- a/drivers/net/can/janz-ican3.c
+++ b/drivers/net/can/janz-ican3.c
@@ -1763,6 +1763,7 @@ static void ican3_get_drvinfo(struct net_device *netdev,
 
 static const struct ethtool_ops ican3_ethtool_ops = {
 	.get_drvinfo = ican3_get_drvinfo,
+	.get_ts_info = ethtool_op_get_ts_info,
 };
 
 /*
diff --git a/drivers/net/can/m_can/m_can.c b/drivers/net/can/m_can/m_can.c
index dc55bfd260c9..1cf14d646493 100644
--- a/drivers/net/can/m_can/m_can.c
+++ b/drivers/net/can/m_can/m_can.c
@@ -1838,6 +1838,7 @@ static void m_can_get_drvinfo(struct net_device *netdev,
 
 static const struct ethtool_ops m_can_ethtool_ops = {
 	.get_drvinfo = m_can_get_drvinfo,
+	.get_ts_info = ethtool_op_get_ts_info,
 };
 
 static int register_m_can_dev(struct net_device *dev)
diff --git a/drivers/net/can/pch_can.c b/drivers/net/can/pch_can.c
index c51354b4cf0c..59cf1f077520 100644
--- a/drivers/net/can/pch_can.c
+++ b/drivers/net/can/pch_can.c
@@ -947,6 +947,7 @@ static void pch_can_get_drvinfo(struct net_device *netdev,
 
 static const struct ethtool_ops pch_can_ethtool_ops = {
 	.get_drvinfo = pch_can_get_drvinfo,
+	.get_ts_info = ethtool_op_get_ts_info,
 };
 
 static void pch_can_remove(struct pci_dev *pdev)
diff --git a/drivers/net/can/rcar/rcar_can.c b/drivers/net/can/rcar/rcar_can.c
index aa644bb79da6..41d053e13f8a 100644
--- a/drivers/net/can/rcar/rcar_can.c
+++ b/drivers/net/can/rcar/rcar_can.c
@@ -639,6 +639,7 @@ static void rcar_can_get_drvinfo(struct net_device *netdev,
 
 static const struct ethtool_ops rcar_can_ethtool_ops = {
 	.get_drvinfo = rcar_can_get_drvinfo,
+	.get_ts_info = ethtool_op_get_ts_info,
 };
 
 static void rcar_can_rx_pkt(struct rcar_can_priv *priv)
diff --git a/drivers/net/can/rcar/rcar_canfd.c b/drivers/net/can/rcar/rcar_canfd.c
index 89cc28985b81..9c4312b098ae 100644
--- a/drivers/net/can/rcar/rcar_canfd.c
+++ b/drivers/net/can/rcar/rcar_canfd.c
@@ -1704,6 +1704,7 @@ static void rcar_canfd_get_drvinfo(struct net_device *netdev,
 
 static const struct ethtool_ops rcar_canfd_ethtool_ops = {
 	.get_drvinfo = rcar_canfd_get_drvinfo,
+	.get_ts_info = ethtool_op_get_ts_info,
 };
 
 static int rcar_canfd_channel_probe(struct rcar_canfd_global *gpriv, u32 ch,
diff --git a/drivers/net/can/sja1000/sja1000.c b/drivers/net/can/sja1000/sja1000.c
index 43967790f4c1..bf9dbf27ed2a 100644
--- a/drivers/net/can/sja1000/sja1000.c
+++ b/drivers/net/can/sja1000/sja1000.c
@@ -663,6 +663,7 @@ static void sja1000_get_drvinfo(struct net_device *netdev,
 
 static const struct ethtool_ops sja1000_ethtool_ops = {
 	.get_drvinfo = sja1000_get_drvinfo,
+	.get_ts_info = ethtool_op_get_ts_info,
 };
 
 int register_sja1000dev(struct net_device *dev)
diff --git a/drivers/net/can/slcan/slcan-core.c b/drivers/net/can/slcan/slcan-core.c
index 65f466582fa2..b7a8e35a5922 100644
--- a/drivers/net/can/slcan/slcan-core.c
+++ b/drivers/net/can/slcan/slcan-core.c
@@ -801,6 +801,7 @@ static void slcan_get_drvinfo(struct net_device *netdev,
 
 static const struct ethtool_ops slcan_ethtool_ops = {
 	.get_drvinfo = slcan_get_drvinfo,
+	.get_ts_info = ethtool_op_get_ts_info,
 };
 
 /******************************************
diff --git a/drivers/net/can/softing/softing_main.c b/drivers/net/can/softing/softing_main.c
index d2ce61562ccc..23862891a40f 100644
--- a/drivers/net/can/softing/softing_main.c
+++ b/drivers/net/can/softing/softing_main.c
@@ -621,6 +621,7 @@ static void softing_get_drvinfo(struct net_device *netdev,
 
 static const struct ethtool_ops softing_ethtool_ops = {
 	.get_drvinfo = softing_get_drvinfo,
+	.get_ts_info = ethtool_op_get_ts_info,
 };
 
 static const struct can_bittiming_const softing_btr_const = {
diff --git a/drivers/net/can/spi/hi311x.c b/drivers/net/can/spi/hi311x.c
index 5e0c0d21aee2..8fd8ff2c80bb 100644
--- a/drivers/net/can/spi/hi311x.c
+++ b/drivers/net/can/spi/hi311x.c
@@ -811,6 +811,7 @@ static void hi3110_get_drvinfo(struct net_device *netdev,
 
 static const struct ethtool_ops hi3110_ethtool_ops = {
 	.get_drvinfo = hi3110_get_drvinfo,
+	.get_ts_info = ethtool_op_get_ts_info,
 };
 
 static const struct of_device_id hi3110_of_match[] = {
diff --git a/drivers/net/can/spi/mcp251x.c b/drivers/net/can/spi/mcp251x.c
index 2e4c03c61b15..972da0918d88 100644
--- a/drivers/net/can/spi/mcp251x.c
+++ b/drivers/net/can/spi/mcp251x.c
@@ -1257,6 +1257,7 @@ static void mcp251x_get_drvinfo(struct net_device *netdev,
 
 static const struct ethtool_ops mcp251x_ethtool_ops = {
 	.get_drvinfo = mcp251x_get_drvinfo,
+	.get_ts_info = ethtool_op_get_ts_info,
 };
 
 static const struct of_device_id mcp251x_of_match[] = {
diff --git a/drivers/net/can/sun4i_can.c b/drivers/net/can/sun4i_can.c
index 27ea4e68b516..8902c80442f4 100644
--- a/drivers/net/can/sun4i_can.c
+++ b/drivers/net/can/sun4i_can.c
@@ -770,6 +770,7 @@ static void sun4ican_get_drvinfo(struct net_device *netdev,
 
 static const struct ethtool_ops sun4ican_ethtool_ops = {
 	.get_drvinfo = sun4ican_get_drvinfo,
+	.get_ts_info = ethtool_op_get_ts_info,
 };
 
 static const struct sun4ican_quirks sun4ican_quirks_a10 = {
diff --git a/drivers/net/can/ti_hecc.c b/drivers/net/can/ti_hecc.c
index 965376453050..1cb66d092f3c 100644
--- a/drivers/net/can/ti_hecc.c
+++ b/drivers/net/can/ti_hecc.c
@@ -850,6 +850,7 @@ static void ti_hecc_get_drvinfo(struct net_device *netdev,
 
 static const struct ethtool_ops ti_hecc_ethtool_ops = {
 	.get_drvinfo = ti_hecc_get_drvinfo,
+	.get_ts_info = ethtool_op_get_ts_info,
 };
 
 static const struct of_device_id ti_hecc_dt_ids[] = {
diff --git a/drivers/net/can/usb/ems_usb.c b/drivers/net/can/usb/ems_usb.c
index ac155f73bedd..bbb6129243e0 100644
--- a/drivers/net/can/usb/ems_usb.c
+++ b/drivers/net/can/usb/ems_usb.c
@@ -888,6 +888,7 @@ static void ems_usb_get_drvinfo(struct net_device *netdev,
 
 static const struct ethtool_ops ems_usb_ethtool_ops = {
 	.get_drvinfo = ems_usb_get_drvinfo,
+	.get_ts_info = ethtool_op_get_ts_info,
 };
 
 static const struct can_bittiming_const ems_usb_bittiming_const = {
diff --git a/drivers/net/can/usb/esd_usb.c b/drivers/net/can/usb/esd_usb.c
index 2367edd49eb7..a2a8473e7d8d 100644
--- a/drivers/net/can/usb/esd_usb.c
+++ b/drivers/net/can/usb/esd_usb.c
@@ -891,6 +891,7 @@ static void esd_usb_get_drvinfo(struct net_device *netdev,
 
 static const struct ethtool_ops esd_usb_ethtool_ops = {
 	.get_drvinfo = esd_usb_get_drvinfo,
+	.get_ts_info = ethtool_op_get_ts_info,
 };
 
 static const struct can_bittiming_const esd_usb2_bittiming_const = {
diff --git a/drivers/net/can/usb/gs_usb.c b/drivers/net/can/usb/gs_usb.c
index 75f5e9c5059a..85174a99a52b 100644
--- a/drivers/net/can/usb/gs_usb.c
+++ b/drivers/net/can/usb/gs_usb.c
@@ -953,6 +953,7 @@ static int gs_usb_set_phys_id(struct net_device *dev,
 static const struct ethtool_ops gs_usb_ethtool_ops = {
 	.get_drvinfo = gs_usb_get_drvinfo,
 	.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,
diff --git a/drivers/net/can/usb/mcba_usb.c b/drivers/net/can/usb/mcba_usb.c
index 485ec697fc08..2a28203294a8 100644
--- a/drivers/net/can/usb/mcba_usb.c
+++ b/drivers/net/can/usb/mcba_usb.c
@@ -767,6 +767,7 @@ static void mcba_get_drvinfo(struct net_device *netdev,
 
 static const struct ethtool_ops mcba_ethtool_ops = {
 	.get_drvinfo = mcba_get_drvinfo,
+	.get_ts_info = ethtool_op_get_ts_info,
 };
 
 /* Microchip CANBUS has hardcoded bittiming values by default.
diff --git a/drivers/net/can/usb/ucan.c b/drivers/net/can/usb/ucan.c
index 52263fa286f3..b8352a17bc34 100644
--- a/drivers/net/can/usb/ucan.c
+++ b/drivers/net/can/usb/ucan.c
@@ -1242,6 +1242,7 @@ static void ucan_get_drvinfo(struct net_device *netdev,
 
 static const struct ethtool_ops ucan_ethtool_ops = {
 	.get_drvinfo = ucan_get_drvinfo,
+	.get_ts_info = ethtool_op_get_ts_info,
 };
 
 /* Request to set bittiming
diff --git a/drivers/net/can/usb/usb_8dev.c b/drivers/net/can/usb/usb_8dev.c
index 2a56d7c2fdb6..209ec6e593a5 100644
--- a/drivers/net/can/usb/usb_8dev.c
+++ b/drivers/net/can/usb/usb_8dev.c
@@ -879,6 +879,7 @@ static void usb_8dev_get_drvinfo(struct net_device *netdev,
 
 static const struct ethtool_ops usb_8dev_ethtool_ops = {
 	.get_drvinfo = usb_8dev_get_drvinfo,
+	.get_ts_info = ethtool_op_get_ts_info,
 };
 
 static const struct can_bittiming_const usb_8dev_bittiming_const = {
diff --git a/drivers/net/can/vcan.c b/drivers/net/can/vcan.c
index e820b2621e53..bb98206c04d1 100644
--- a/drivers/net/can/vcan.c
+++ b/drivers/net/can/vcan.c
@@ -157,6 +157,7 @@ static void vcan_get_drvinfo(struct net_device *netdev,
 
 static const struct ethtool_ops vcan_ethtool_ops = {
 	.get_drvinfo = vcan_get_drvinfo,
+	.get_ts_info = ethtool_op_get_ts_info,
 };
 
 static void vcan_setup(struct net_device *dev)
diff --git a/drivers/net/can/vxcan.c b/drivers/net/can/vxcan.c
index aedeb9766996..68d3043e2ced 100644
--- a/drivers/net/can/vxcan.c
+++ b/drivers/net/can/vxcan.c
@@ -155,6 +155,7 @@ static void vxcan_get_drvinfo(struct net_device *netdev,
 
 static const struct ethtool_ops vxcan_ethtool_ops = {
 	.get_drvinfo = vxcan_get_drvinfo,
+	.get_ts_info = ethtool_op_get_ts_info,
 };
 
 static void vxcan_setup(struct net_device *dev)
diff --git a/drivers/net/can/xilinx_can.c b/drivers/net/can/xilinx_can.c
index b802ddec1965..1b79474018c9 100644
--- a/drivers/net/can/xilinx_can.c
+++ b/drivers/net/can/xilinx_can.c
@@ -1549,6 +1549,7 @@ static void xcan_get_drvinfo(struct net_device *netdev,
 
 static const struct ethtool_ops xcan_ethtool_ops = {
 	.get_drvinfo = xcan_get_drvinfo,
+	.get_ts_info = ethtool_op_get_ts_info,
 };
 
 /**
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 92+ messages in thread

* [PATCH v1 16/24] can: dev: add hardware TX timestamp
  2022-07-25 13:31 [PATCH v1 00/24] can: add ethtool support and reporting of timestamping capabilities Vincent Mailhol
                   ` (14 preceding siblings ...)
  2022-07-25 13:31 ` [PATCH v1 15/24] can: tree-wide: advertise software timestamping capabilities Vincent Mailhol
@ 2022-07-25 13:32 ` Vincent Mailhol
  2022-07-25 13:32 ` [PATCH v1 17/24] can: dev: add generic function can_ethtool_op_get_ts_info_hwts() Vincent Mailhol
                   ` (11 subsequent siblings)
  27 siblings, 0 replies; 92+ messages in thread
From: Vincent Mailhol @ 2022-07-25 13:32 UTC (permalink / raw)
  To: linux-can, Marc Kleine-Budde
  Cc: Stephane Grosjean, Jimmy Assarsson, Oliver Hartkopp,
	Dario Binacchi, Max Staudt, Vincent Mailhol

Because of the loopback feature of socket CAN, hardware TX timestamps
are nothing else than the hardware RX timespamp of the corresponding
loopback packet. This patch simply reuses the hardware RX timestamp.

The rationale to clone this timestamp value is that existing tools
which rely of libpcap (such as tcpdump) expect support for both TX and
RX hardware timestamps in order to activate the feature (i.e. no
granular control to activate either of TX or RX hardware timestamps).

Signed-off-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
---
 drivers/net/can/dev/skb.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/net/can/dev/skb.c b/drivers/net/can/dev/skb.c
index 8bb62dd864c8..07e0feac8629 100644
--- a/drivers/net/can/dev/skb.c
+++ b/drivers/net/can/dev/skb.c
@@ -72,6 +72,9 @@ int can_put_echo_skb(struct sk_buff *skb, struct net_device *dev,
 		/* save frame_len to reuse it when transmission is completed */
 		can_skb_prv(skb)->frame_len = frame_len;
 
+		if (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)
+			skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;
+
 		skb_tx_timestamp(skb);
 
 		/* save this skb for tx interrupt echo handling */
@@ -107,6 +110,9 @@ __can_get_echo_skb(struct net_device *dev, unsigned int idx, u8 *len_ptr,
 		struct can_skb_priv *can_skb_priv = can_skb_prv(skb);
 		struct canfd_frame *cf = (struct canfd_frame *)skb->data;
 
+		if (skb_shinfo(skb)->tx_flags & SKBTX_IN_PROGRESS)
+			skb_tstamp_tx(skb, skb_hwtstamps(skb));
+
 		/* get the real payload length for netdev statistics */
 		if (cf->can_id & CAN_RTR_FLAG)
 			*len_ptr = 0;
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 92+ messages in thread

* [PATCH v1 17/24] can: dev: add generic function can_ethtool_op_get_ts_info_hwts()
  2022-07-25 13:31 [PATCH v1 00/24] can: add ethtool support and reporting of timestamping capabilities Vincent Mailhol
                   ` (15 preceding siblings ...)
  2022-07-25 13:32 ` [PATCH v1 16/24] can: dev: add hardware TX timestamp Vincent Mailhol
@ 2022-07-25 13:32 ` Vincent Mailhol
  2022-07-25 13:32 ` [PATCH v1 18/24] can: dev: add generic function can_eth_ioctl_hwts() Vincent Mailhol
                   ` (10 subsequent siblings)
  27 siblings, 0 replies; 92+ messages in thread
From: Vincent Mailhol @ 2022-07-25 13:32 UTC (permalink / raw)
  To: linux-can, Marc Kleine-Budde
  Cc: Stephane Grosjean, Jimmy Assarsson, Oliver Hartkopp,
	Dario Binacchi, Max Staudt, Vincent Mailhol

Add function can_ethtool_op_get_ts_info_hwts(). This function will be
used by CAN devices with hardware TX/RX timestamping support to
implement ethtool_ops::get_ts_info. This function does not offer
support to activate/deactivate hardware timestamps at device level nor
support the filter options (which is currently the case for all CAN
devices with hardware timestamping support).

The fact that hardware timestamp can not be deactivated at hardware
level does not impact the userland. As long as the user do not set
SO_TIMESTAMPING using a setsockopt() or ioctl(), the kernel will not
emit TX timestamps (RX timestamps will still be reproted as it is the
case currently).

Drivers which need more fine grained control remains free to implement
their own function, but we foresee that the generic function
introduced here will be sufficient for the majority.

Signed-off-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
---
 drivers/net/can/dev/dev.c | 21 +++++++++++++++++++++
 include/linux/can/dev.h   |  3 +++
 2 files changed, 24 insertions(+)

diff --git a/drivers/net/can/dev/dev.c b/drivers/net/can/dev/dev.c
index 523eaacfe29e..7ad56d31cec9 100644
--- a/drivers/net/can/dev/dev.c
+++ b/drivers/net/can/dev/dev.c
@@ -322,6 +322,27 @@ int can_change_mtu(struct net_device *dev, int new_mtu)
 }
 EXPORT_SYMBOL_GPL(can_change_mtu);
 
+/* generic implementation of ethtool_ops::get_ts_info for CAN devices
+ * supporting hardware RX timestamps
+ */
+int can_ethtool_op_get_ts_info_hwts(struct net_device *dev,
+				    struct ethtool_ts_info *info)
+{
+	info->so_timestamping =
+		SOF_TIMESTAMPING_TX_SOFTWARE |
+		SOF_TIMESTAMPING_RX_SOFTWARE |
+		SOF_TIMESTAMPING_SOFTWARE |
+		SOF_TIMESTAMPING_TX_HARDWARE |
+		SOF_TIMESTAMPING_RX_HARDWARE |
+		SOF_TIMESTAMPING_RAW_HARDWARE;
+	info->phc_index = -1;
+	info->tx_types = BIT(HWTSTAMP_TX_ON);
+	info->rx_filters = BIT(HWTSTAMP_FILTER_ALL);
+
+	return 0;
+}
+EXPORT_SYMBOL(can_ethtool_op_get_ts_info_hwts);
+
 /* Common open function when the device gets opened.
  *
  * This function should be called in the open function of the device
diff --git a/include/linux/can/dev.h b/include/linux/can/dev.h
index e22dc03c850e..752bd45d8ebf 100644
--- a/include/linux/can/dev.h
+++ b/include/linux/can/dev.h
@@ -20,6 +20,7 @@
 #include <linux/can/length.h>
 #include <linux/can/netlink.h>
 #include <linux/can/skb.h>
+#include <linux/ethtool.h>
 #include <linux/netdevice.h>
 
 /*
@@ -162,6 +163,8 @@ struct can_priv *safe_candev_priv(struct net_device *dev);
 int open_candev(struct net_device *dev);
 void close_candev(struct net_device *dev);
 int can_change_mtu(struct net_device *dev, int new_mtu);
+int can_ethtool_op_get_ts_info_hwts(struct net_device *dev,
+				    struct ethtool_ts_info *info);
 
 int register_candev(struct net_device *dev);
 void unregister_candev(struct net_device *dev);
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 92+ messages in thread

* [PATCH v1 18/24] can: dev: add generic function can_eth_ioctl_hwts()
  2022-07-25 13:31 [PATCH v1 00/24] can: add ethtool support and reporting of timestamping capabilities Vincent Mailhol
                   ` (16 preceding siblings ...)
  2022-07-25 13:32 ` [PATCH v1 17/24] can: dev: add generic function can_ethtool_op_get_ts_info_hwts() Vincent Mailhol
@ 2022-07-25 13:32 ` Vincent Mailhol
  2022-07-25 14:22   ` Marc Kleine-Budde
  2022-07-25 13:32 ` [PATCH v1 19/24] can: mcp251xfd: advertise timestamping capabilities and add ioctl support Vincent Mailhol
                   ` (9 subsequent siblings)
  27 siblings, 1 reply; 92+ messages in thread
From: Vincent Mailhol @ 2022-07-25 13:32 UTC (permalink / raw)
  To: linux-can, Marc Kleine-Budde
  Cc: Stephane Grosjean, Jimmy Assarsson, Oliver Hartkopp,
	Dario Binacchi, Max Staudt, Vincent Mailhol

Tools based on libpcap (such as tcpdump) expect the SIOCSHWTSTAMP
ioctl call to be supported. This is also specified in the kernel doc
[1]. The purpose of this ioctl is to toggle the hardware timestamps.

Currently, CAN devices which support hardware timestamping have those
always activated. can_eth_ioctl_hwts() is a dumb function that will
always succeed when requested to set tx_type to HWTSTAMP_TX_ON or
rx_filter to HWTSTAMP_FILTER_ALL.

[1] Kernel doc: Timestamping, section 3.1 "Hardware Timestamping
Implementation: Device Drivers"
Link: https://docs.kernel.org/networking/timestamping.html#hardware-timestamping-implementation-device-drivers

Signed-off-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
---
 drivers/net/can/dev/dev.c | 29 +++++++++++++++++++++++++++++
 include/linux/can/dev.h   |  1 +
 2 files changed, 30 insertions(+)

diff --git a/drivers/net/can/dev/dev.c b/drivers/net/can/dev/dev.c
index 7ad56d31cec9..750dc7cae9d4 100644
--- a/drivers/net/can/dev/dev.c
+++ b/drivers/net/can/dev/dev.c
@@ -322,6 +322,35 @@ int can_change_mtu(struct net_device *dev, int new_mtu)
 }
 EXPORT_SYMBOL_GPL(can_change_mtu);
 
+/* generic implementation of netdev_ops::ndo_eth_ioctl for CAN devices
+ * supporting hardware RX timestamps
+ */
+int can_eth_ioctl_hwts(struct net_device *netdev, struct ifreq *ifr, int cmd)
+{
+	struct hwtstamp_config hwts_cfg = { 0 };
+
+	switch (cmd) {
+	case SIOCSHWTSTAMP: /* set */
+		if (copy_from_user(&hwts_cfg, ifr->ifr_data, sizeof(hwts_cfg)))
+			return -EFAULT;
+		if (hwts_cfg.tx_type == HWTSTAMP_TX_ON &&
+		    hwts_cfg.rx_filter == HWTSTAMP_FILTER_ALL)
+			return 0;
+		return -ERANGE;
+
+	case SIOCGHWTSTAMP: /* get */
+		hwts_cfg.tx_type = HWTSTAMP_TX_ON;
+		hwts_cfg.rx_filter = HWTSTAMP_FILTER_ALL;
+		if (copy_to_user(ifr->ifr_data, &hwts_cfg, sizeof(hwts_cfg)))
+			return -EFAULT;
+		return 0;
+
+	default:
+		return -EOPNOTSUPP;
+	}
+}
+EXPORT_SYMBOL(can_eth_ioctl_hwts);
+
 /* generic implementation of ethtool_ops::get_ts_info for CAN devices
  * supporting hardware RX timestamps
  */
diff --git a/include/linux/can/dev.h b/include/linux/can/dev.h
index 752bd45d8ebf..c3e50e537e39 100644
--- a/include/linux/can/dev.h
+++ b/include/linux/can/dev.h
@@ -163,6 +163,7 @@ struct can_priv *safe_candev_priv(struct net_device *dev);
 int open_candev(struct net_device *dev);
 void close_candev(struct net_device *dev);
 int can_change_mtu(struct net_device *dev, int new_mtu);
+int can_eth_ioctl_hwts(struct net_device *netdev, struct ifreq *ifr, int cmd);
 int can_ethtool_op_get_ts_info_hwts(struct net_device *dev,
 				    struct ethtool_ts_info *info);
 
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 92+ messages in thread

* [PATCH v1 19/24] can: mcp251xfd: advertise timestamping capabilities and add ioctl support
  2022-07-25 13:31 [PATCH v1 00/24] can: add ethtool support and reporting of timestamping capabilities Vincent Mailhol
                   ` (17 preceding siblings ...)
  2022-07-25 13:32 ` [PATCH v1 18/24] can: dev: add generic function can_eth_ioctl_hwts() Vincent Mailhol
@ 2022-07-25 13:32 ` Vincent Mailhol
  2022-07-25 13:32 ` [PATCH v1 20/24] can: etas_es58x: " Vincent Mailhol
                   ` (8 subsequent siblings)
  27 siblings, 0 replies; 92+ messages in thread
From: Vincent Mailhol @ 2022-07-25 13:32 UTC (permalink / raw)
  To: linux-can, Marc Kleine-Budde
  Cc: Stephane Grosjean, Jimmy Assarsson, Oliver Hartkopp,
	Dario Binacchi, Max Staudt, Vincent Mailhol

Currently, userland has no methods to query which timestamping
features are supported by the mcp251xfd driver (aside maybe of getting
RX messages and obseverse whether or not hardware timestamps stay at
zero).

The canonical way for a network driver to advertise what kind of
timestamping it supports is to implement
ethtool_ops::get_ts_info(). Here, we use the CAN specific
can_ethtool_op_get_ts_info_hwts() function to achieve this.

In addition, the driver currently does not support the hardware
timestamps ioctls. According to [1], SIOCSHWTSTAMP is "must" and
SIOCGHWTSTAMP is "should". This patch fills up that gap by
implementing net_device_ops::ndo_eth_ioctl() using the CAN specific
function can_eth_ioctl_hwts().

[1] kernel doc Timestamping, section 3.1: "Hardware Timestamping
Implementation: Device Drivers"
Link: https://docs.kernel.org/networking/timestamping.html#hardware-timestamping-implementation-device-drivers

Signed-off-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
---
 drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c b/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c
index d9a7de1927d6..f3196c603459 100644
--- a/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c
+++ b/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c
@@ -1672,6 +1672,7 @@ static const struct net_device_ops mcp251xfd_netdev_ops = {
 	.ndo_open = mcp251xfd_open,
 	.ndo_stop = mcp251xfd_stop,
 	.ndo_start_xmit	= mcp251xfd_start_xmit,
+	.ndo_eth_ioctl = can_eth_ioctl_hwts,
 	.ndo_change_mtu = can_change_mtu,
 };
 
@@ -1683,6 +1684,7 @@ static void mcp251xfd_get_drvinfo(struct net_device *netdev,
 
 static const struct ethtool_ops mcp251xfd_ethtool_ops = {
 	.get_drvinfo = mcp251xfd_get_drvinfo,
+	.get_ts_info = can_ethtool_op_get_ts_info_hwts,
 };
 
 static void
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 92+ messages in thread

* [PATCH v1 20/24] can: etas_es58x: advertise timestamping capabilities and add ioctl support
  2022-07-25 13:31 [PATCH v1 00/24] can: add ethtool support and reporting of timestamping capabilities Vincent Mailhol
                   ` (18 preceding siblings ...)
  2022-07-25 13:32 ` [PATCH v1 19/24] can: mcp251xfd: advertise timestamping capabilities and add ioctl support Vincent Mailhol
@ 2022-07-25 13:32 ` Vincent Mailhol
  2022-07-25 13:32 ` [PATCH v1 21/24] can: kvaser_pciefd: " Vincent Mailhol
                   ` (7 subsequent siblings)
  27 siblings, 0 replies; 92+ messages in thread
From: Vincent Mailhol @ 2022-07-25 13:32 UTC (permalink / raw)
  To: linux-can, Marc Kleine-Budde
  Cc: Stephane Grosjean, Jimmy Assarsson, Oliver Hartkopp,
	Dario Binacchi, Max Staudt, Vincent Mailhol

Currently, userland has no method to query which timestamping features
are supported by the etas_es58x driver (aside maybe of getting RX
messages and obseverse whever or not hardware timestamps stay at
zero).

The canonical way for a network driver to advertise what kind of
timestamping is supports is to implement
ethtool_ops::get_ts_info(). Here, we use the CAN specific
can_ethtool_op_get_ts_info_hwts() function to achieve this.

In addition, the driver currently does not support the hardware
timestamps ioctls. According to [1], SIOCSHWTSTAMP is "must" and
SIOCGHWTSTAMP is "should". This patch fills up that gap by
implementing net_device_ops::ndo_eth_ioctl() using the CAN specific
function can_eth_ioctl_hwts().

[1] kernel doc Timestamping, section 3.1: "Hardware Timestamping
Implementation: Device Drivers"
Link: https://docs.kernel.org/networking/timestamping.html#hardware-timestamping-implementation-device-drivers

Signed-off-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
---
 drivers/net/can/usb/etas_es58x/es58x_core.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/net/can/usb/etas_es58x/es58x_core.c b/drivers/net/can/usb/etas_es58x/es58x_core.c
index 0e692c2dc54d..aba203af39ea 100644
--- a/drivers/net/can/usb/etas_es58x/es58x_core.c
+++ b/drivers/net/can/usb/etas_es58x/es58x_core.c
@@ -1980,7 +1980,8 @@ static netdev_tx_t es58x_start_xmit(struct sk_buff *skb,
 static const struct net_device_ops es58x_netdev_ops = {
 	.ndo_open = es58x_open,
 	.ndo_stop = es58x_stop,
-	.ndo_start_xmit = es58x_start_xmit
+	.ndo_start_xmit = es58x_start_xmit,
+	.ndo_eth_ioctl = can_eth_ioctl_hwts,
 };
 
 static void es58x_get_drvinfo(struct net_device *netdev,
@@ -1991,6 +1992,7 @@ static void es58x_get_drvinfo(struct net_device *netdev,
 
 static const struct ethtool_ops es58x_ethtool_ops = {
 	.get_drvinfo = es58x_get_drvinfo,
+	.get_ts_info = can_ethtool_op_get_ts_info_hwts,
 };
 
 /**
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 92+ messages in thread

* [PATCH v1 21/24] can: kvaser_pciefd: advertise timestamping capabilities and add ioctl support
  2022-07-25 13:31 [PATCH v1 00/24] can: add ethtool support and reporting of timestamping capabilities Vincent Mailhol
                   ` (19 preceding siblings ...)
  2022-07-25 13:32 ` [PATCH v1 20/24] can: etas_es58x: " Vincent Mailhol
@ 2022-07-25 13:32 ` Vincent Mailhol
  2022-07-25 13:32 ` [PATCH v1 22/24] can: kvaser_usb: " Vincent Mailhol
                   ` (6 subsequent siblings)
  27 siblings, 0 replies; 92+ messages in thread
From: Vincent Mailhol @ 2022-07-25 13:32 UTC (permalink / raw)
  To: linux-can, Marc Kleine-Budde
  Cc: Stephane Grosjean, Jimmy Assarsson, Oliver Hartkopp,
	Dario Binacchi, Max Staudt, Vincent Mailhol

Currently, userland has no method to query which timestamping features
are supported by the kvaser_pciefd driver (aside maybe of getting RX
messages and obseverse whever or not hardware timestamps stay at
zero).

The canonical way for a network driver to advertise what kind of
timestamping it supports is to implement
ethtool_ops::get_ts_info(). Here, we use the CAN specific
can_ethtool_op_get_ts_info_hwts() function to achieve this.

In addition, the driver currently does not support the hardware
timestamps ioctls. According to [1], SIOCSHWTSTAMP is "must" and
SIOCGHWTSTAMP is "should". This patch fills up that gap by
implementing net_device_ops::ndo_eth_ioctl() using the CAN specific
function can_eth_ioctl_hwts().

[1] kernel doc Timestamping, section 3.1: "Hardware Timestamping
Implementation: Device Drivers"
Link: https://docs.kernel.org/networking/timestamping.html#hardware-timestamping-implementation-device-drivers

CC: Jimmy Assarsson <extja@kvaser.com>
Signed-off-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
---
 drivers/net/can/kvaser_pciefd.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/net/can/kvaser_pciefd.c b/drivers/net/can/kvaser_pciefd.c
index f7f7a0287a8d..2109f904b052 100644
--- a/drivers/net/can/kvaser_pciefd.c
+++ b/drivers/net/can/kvaser_pciefd.c
@@ -920,6 +920,7 @@ static void kvaser_pciefd_bec_poll_timer(struct timer_list *data)
 static const struct net_device_ops kvaser_pciefd_netdev_ops = {
 	.ndo_open = kvaser_pciefd_open,
 	.ndo_stop = kvaser_pciefd_stop,
+	.ndo_eth_ioctl = can_eth_ioctl_hwts,
 	.ndo_start_xmit = kvaser_pciefd_start_xmit,
 	.ndo_change_mtu = can_change_mtu,
 };
@@ -932,6 +933,7 @@ static void kvaser_pciefd_get_drvinfo(struct net_device *netdev,
 
 static const struct ethtool_ops kvaser_pciefd_ethtool_ops = {
 	.get_drvinfo = kvaser_pciefd_get_drvinfo,
+	.get_ts_info = can_ethtool_op_get_ts_info_hwts,
 };
 
 static int kvaser_pciefd_setup_can_ctrls(struct kvaser_pciefd *pcie)
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 92+ messages in thread

* [PATCH v1 22/24] can: kvaser_usb: advertise timestamping capabilities and add ioctl support
  2022-07-25 13:31 [PATCH v1 00/24] can: add ethtool support and reporting of timestamping capabilities Vincent Mailhol
                   ` (20 preceding siblings ...)
  2022-07-25 13:32 ` [PATCH v1 21/24] can: kvaser_pciefd: " Vincent Mailhol
@ 2022-07-25 13:32 ` Vincent Mailhol
  2022-07-25 13:32 ` [PATCH v1 23/24] can: peak_canfd: " Vincent Mailhol
                   ` (5 subsequent siblings)
  27 siblings, 0 replies; 92+ messages in thread
From: Vincent Mailhol @ 2022-07-25 13:32 UTC (permalink / raw)
  To: linux-can, Marc Kleine-Budde
  Cc: Stephane Grosjean, Jimmy Assarsson, Oliver Hartkopp,
	Dario Binacchi, Max Staudt, Vincent Mailhol

Currently, userland has no method to query which timestamping features
are supported by the kvaser_usb driver (aside maybe of getting RX
messages and obseverse whever or not hardware timestamps stay at
zero).

The canonical way for a network driver to advertise what kind of
timestamping it supports is to implement
ethtool_ops::get_ts_info(). Here, we use the CAN specific
can_ethtool_op_get_ts_info_hwts() function to achieve this.

In addition, the driver currently does not support the hardware
timestamps ioctls. According to [1], SIOCSHWTSTAMP is "must" and
SIOCGHWTSTAMP is "should". This patch fills up that gap by
implementing net_device_ops::ndo_eth_ioctl() using the CAN specific
function can_eth_ioctl_hwts().

[1] kernel doc Timestamping, section 3.1: "Hardware Timestamping
Implementation: Device Drivers"
Link: https://docs.kernel.org/networking/timestamping.html#hardware-timestamping-implementation-device-drivers

CC: Jimmy Assarsson <extja@kvaser.com>
Signed-off-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
---

Hi Jimmy, as far as I understand, only the hydra has the hardware
timestamping. If not the case, let me know.

This is not tested. If you find any issue or if you want to modify,
feel free to pick up that patch and resend it.
---
 drivers/net/can/usb/kvaser_usb/kvaser_usb.h   |  1 +
 .../net/can/usb/kvaser_usb/kvaser_usb_core.c  | 25 ++++++++++++++++---
 2 files changed, 23 insertions(+), 3 deletions(-)

diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb.h b/drivers/net/can/usb/kvaser_usb/kvaser_usb.h
index eefcbe3aadce..841da29cef93 100644
--- a/drivers/net/can/usb/kvaser_usb/kvaser_usb.h
+++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb.h
@@ -39,6 +39,7 @@
 #define KVASER_USB_QUIRK_HAS_SILENT_MODE	BIT(0)
 #define KVASER_USB_QUIRK_HAS_TXRX_ERRORS	BIT(1)
 #define KVASER_USB_QUIRK_IGNORE_CLK_FREQ	BIT(2)
+#define KVASER_USB_QUIRK_HAS_HARDWARE_TIMESTAMP	BIT(3)
 
 /* Device capabilities */
 #define KVASER_USB_CAP_BERR_CAP			0x01
diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c b/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c
index 964c0026383e..36e896dbd94b 100644
--- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c
+++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c
@@ -92,7 +92,7 @@
 #define USB_HYBRID_PRO_CANLIN_PRODUCT_ID	278
 
 static const struct kvaser_usb_driver_info kvaser_usb_driver_info_hydra = {
-	.quirks = 0,
+	.quirks = KVASER_USB_QUIRK_HAS_HARDWARE_TIMESTAMP,
 	.ops = &kvaser_usb_hydra_dev_ops,
 };
 
@@ -668,6 +668,14 @@ static const struct net_device_ops kvaser_usb_netdev_ops = {
 	.ndo_change_mtu = can_change_mtu,
 };
 
+static const struct net_device_ops kvaser_usb_netdev_ops_hwts = {
+	.ndo_open = kvaser_usb_open,
+	.ndo_stop = kvaser_usb_close,
+	.ndo_eth_ioctl = can_eth_ioctl_hwts,
+	.ndo_start_xmit = kvaser_usb_start_xmit,
+	.ndo_change_mtu = can_change_mtu,
+};
+
 static void kvaser_usb_get_drvinfo(struct net_device *netdev,
 				   struct ethtool_drvinfo *drvinfo)
 {
@@ -676,6 +684,12 @@ static void kvaser_usb_get_drvinfo(struct net_device *netdev,
 
 static const struct ethtool_ops kvaser_usb_ethtool_ops = {
 	.get_drvinfo = kvaser_usb_get_drvinfo,
+	.get_ts_info = ethtool_op_get_ts_info,
+};
+
+static const struct ethtool_ops kvaser_usb_ethtool_ops_hwts = {
+	.get_drvinfo = kvaser_usb_get_drvinfo,
+	.get_ts_info = can_ethtool_op_get_ts_info_hwts,
 };
 
 static void kvaser_usb_remove_interfaces(struct kvaser_usb *dev)
@@ -755,8 +769,13 @@ static int kvaser_usb_init_one(struct kvaser_usb *dev, int channel)
 	netdev->flags |= IFF_ECHO;
 
 	netdev->netdev_ops = &kvaser_usb_netdev_ops;
-	netdev->ethtool_ops = &kvaser_usb_ethtool_ops;
-
+	if (driver_info->quirks & KVASER_USB_QUIRK_HAS_HARDWARE_TIMESTAMP) {
+		netdev->netdev_ops = &kvaser_usb_netdev_ops_hwts;
+		netdev->ethtool_ops = &kvaser_usb_ethtool_ops_hwts;
+	} else {
+		netdev->netdev_ops = &kvaser_usb_netdev_ops;
+		netdev->ethtool_ops = &kvaser_usb_ethtool_ops;
+	}
 	SET_NETDEV_DEV(netdev, &dev->intf->dev);
 	netdev->dev_id = channel;
 
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 92+ messages in thread

* [PATCH v1 23/24] can: peak_canfd: advertise timestamping capabilities and add ioctl support
  2022-07-25 13:31 [PATCH v1 00/24] can: add ethtool support and reporting of timestamping capabilities Vincent Mailhol
                   ` (21 preceding siblings ...)
  2022-07-25 13:32 ` [PATCH v1 22/24] can: kvaser_usb: " Vincent Mailhol
@ 2022-07-25 13:32 ` Vincent Mailhol
  2022-07-25 13:32 ` [PATCH v1 24/24] can: peak_usb: " Vincent Mailhol
                   ` (4 subsequent siblings)
  27 siblings, 0 replies; 92+ messages in thread
From: Vincent Mailhol @ 2022-07-25 13:32 UTC (permalink / raw)
  To: linux-can, Marc Kleine-Budde
  Cc: Stephane Grosjean, Jimmy Assarsson, Oliver Hartkopp,
	Dario Binacchi, Max Staudt, Vincent Mailhol

Currently, userland has no method to query which timestamping features
are supported by the peak_canfd driver (aside maybe of getting RX
messages and obseverse whever or not hardware timestamps stay at
zero).

The canonical way for a network driver to advertise what kind of
timestamping it supports is to implement
ethtool_ops::get_ts_info(). Here, we use the CAN specific
can_ethtool_op_get_ts_info_hwts() function to achieve this.

In addition, the driver currently does not support the hardware
timestamps ioctls. According to [1], SIOCSHWTSTAMP is "must" and
SIOCGHWTSTAMP is "should". This patch fills up that gap by
implementing net_device_ops::ndo_eth_ioctl() using the CAN specific
function can_eth_ioctl_hwts().

[1] kernel doc Timestamping, section 3.1: "Hardware Timestamping
Implementation: Device Drivers"
Link: https://docs.kernel.org/networking/timestamping.html#hardware-timestamping-implementation-device-drivers

CC: Stephane Grosjean <s.grosjean@peak-system.com>
Signed-off-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
---
 drivers/net/can/peak_canfd/peak_canfd.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/net/can/peak_canfd/peak_canfd.c b/drivers/net/can/peak_canfd/peak_canfd.c
index 9b94d5b4be2d..b0915cc80cc8 100644
--- a/drivers/net/can/peak_canfd/peak_canfd.c
+++ b/drivers/net/can/peak_canfd/peak_canfd.c
@@ -746,6 +746,7 @@ static netdev_tx_t peak_canfd_start_xmit(struct sk_buff *skb,
 static const struct net_device_ops peak_canfd_netdev_ops = {
 	.ndo_open = peak_canfd_open,
 	.ndo_stop = peak_canfd_close,
+	.ndo_eth_ioctl = can_eth_ioctl_hwts,
 	.ndo_start_xmit = peak_canfd_start_xmit,
 	.ndo_change_mtu = can_change_mtu,
 };
@@ -758,6 +759,7 @@ static void peak_canfd_get_drvinfo(struct net_device *netdev,
 
 static const struct ethtool_ops peak_canfd_ethtool_ops = {
 	.get_drvinfo = peak_canfd_get_drvinfo,
+	.get_ts_info = can_ethtool_op_get_ts_info_hwts,
 };
 
 struct net_device *alloc_peak_canfd_dev(int sizeof_priv, int index,
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 92+ messages in thread

* [PATCH v1 24/24] can: peak_usb: advertise timestamping capabilities and add ioctl support
  2022-07-25 13:31 [PATCH v1 00/24] can: add ethtool support and reporting of timestamping capabilities Vincent Mailhol
                   ` (22 preceding siblings ...)
  2022-07-25 13:32 ` [PATCH v1 23/24] can: peak_canfd: " Vincent Mailhol
@ 2022-07-25 13:32 ` Vincent Mailhol
  2022-07-25 13:53 ` [PATCH v1 00/24] can: add ethtool support and reporting of timestamping capabilities Vincent MAILHOL
                   ` (3 subsequent siblings)
  27 siblings, 0 replies; 92+ messages in thread
From: Vincent Mailhol @ 2022-07-25 13:32 UTC (permalink / raw)
  To: linux-can, Marc Kleine-Budde
  Cc: Stephane Grosjean, Jimmy Assarsson, Oliver Hartkopp,
	Dario Binacchi, Max Staudt, Vincent Mailhol

Currently, userland has no method to query which timestamping features
are supported by the peak_usb driver (aside maybe of getting RX
messages and obseverse whever or not hardware timestamps stay at
zero).

The canonical way for a network driver to advertise what kind of
timestamping it supports is to implement
ethtool_ops::get_ts_info(). Here, we use the CAN specific
can_ethtool_op_get_ts_info_hwts() function to achieve this.

In addition, the driver currently does not support the hardware
timestamps ioctls. According to [1], SIOCSHWTSTAMP is "must" and
SIOCGHWTSTAMP is "should". This patch fills up that gap by
implementing net_device_ops::ndo_eth_ioctl() using the CAN specific
function can_eth_ioctl_hwts().

[1] kernel doc Timestamping, section 3.1: "Hardware Timestamping
Implementation: Device Drivers"
Link: https://docs.kernel.org/networking/timestamping.html#hardware-timestamping-implementation-device-drivers

CC: Stephane Grosjean <s.grosjean@peak-system.com>
Signed-off-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
---

Hi Stéphane, as far as I understand, the pcan_usb and the pacn_usb_pro
support hardware timestamps but the pcan_usb_fd doesn't. If not the
case, let me know.

This is not tested. If you find any issue or if you want to modify,
feel free to pick up that patch and resend it.
---
 drivers/net/can/usb/peak_usb/pcan_usb.c      |  3 +++
 drivers/net/can/usb/peak_usb/pcan_usb_core.c | 12 ++++++++++--
 drivers/net/can/usb/peak_usb/pcan_usb_core.h |  4 ++++
 drivers/net/can/usb/peak_usb/pcan_usb_fd.c   |  2 ++
 drivers/net/can/usb/peak_usb/pcan_usb_pro.c  |  2 ++
 5 files changed, 21 insertions(+), 2 deletions(-)

diff --git a/drivers/net/can/usb/peak_usb/pcan_usb.c b/drivers/net/can/usb/peak_usb/pcan_usb.c
index d07b7ee79e3e..4cd7bd894276 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb.c
+++ b/drivers/net/can/usb/peak_usb/pcan_usb.c
@@ -964,7 +964,9 @@ static int pcan_usb_set_phys_id(struct net_device *netdev,
 }
 
 static const struct ethtool_ops pcan_usb_ethtool_ops = {
+	.get_drvinfo = peak_usb_get_drvinfo,
 	.set_phys_id = pcan_usb_set_phys_id,
+	.get_ts_info = can_ethtool_op_get_ts_info_hwts,
 };
 
 /*
@@ -996,6 +998,7 @@ const struct peak_usb_adapter pcan_usb = {
 	/* size of device private data */
 	.sizeof_dev_private = sizeof(struct pcan_usb),
 
+	.netdev_ops = &pcan_usb_netdev_ops,
 	.ethtool_ops = &pcan_usb_ethtool_ops,
 
 	/* timestamps usage */
diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_core.c b/drivers/net/can/usb/peak_usb/pcan_usb_core.c
index 959448bae3ca..2712e08ffaba 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb_core.c
+++ b/drivers/net/can/usb/peak_usb/pcan_usb_core.c
@@ -775,13 +775,21 @@ static int peak_usb_set_data_bittiming(struct net_device *netdev)
 	return 0;
 }
 
-static const struct net_device_ops peak_usb_netdev_ops = {
+const struct net_device_ops pcan_usb_netdev_ops = {
 	.ndo_open = peak_usb_ndo_open,
 	.ndo_stop = peak_usb_ndo_stop,
 	.ndo_start_xmit = peak_usb_ndo_start_xmit,
 	.ndo_change_mtu = can_change_mtu,
 };
 
+const struct net_device_ops pcan_usb_netdev_ops_hwts = {
+	.ndo_open = peak_usb_ndo_open,
+	.ndo_stop = peak_usb_ndo_stop,
+	.ndo_eth_ioctl = can_eth_ioctl_hwts,
+	.ndo_start_xmit = peak_usb_ndo_start_xmit,
+	.ndo_change_mtu = can_change_mtu,
+};
+
 void peak_usb_get_drvinfo(struct net_device *netdev,
 			  struct ethtool_drvinfo *drvinfo)
 {
@@ -839,7 +847,7 @@ static int peak_usb_create_dev(const struct peak_usb_adapter *peak_usb_adapter,
 	dev->can.do_get_berr_counter = peak_usb_adapter->do_get_berr_counter;
 	dev->can.ctrlmode_supported = peak_usb_adapter->ctrlmode_supported;
 
-	netdev->netdev_ops = &peak_usb_netdev_ops;
+	netdev->netdev_ops = peak_usb_adapter->netdev_ops;
 
 	netdev->flags |= IFF_ECHO; /* we support local echo */
 
diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_core.h b/drivers/net/can/usb/peak_usb/pcan_usb_core.h
index da1205575379..cfb25bebb54f 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb_core.h
+++ b/drivers/net/can/usb/peak_usb/pcan_usb_core.h
@@ -46,6 +46,7 @@ struct peak_usb_adapter {
 	const struct can_bittiming_const * const data_bittiming_const;
 	unsigned int ctrl_count;
 
+	const struct net_device_ops *netdev_ops;
 	const struct ethtool_ops *ethtool_ops;
 
 	int (*intf_probe)(struct usb_interface *intf);
@@ -88,6 +89,9 @@ extern const struct peak_usb_adapter pcan_usb_chip;
 extern const struct peak_usb_adapter pcan_usb_pro_fd;
 extern const struct peak_usb_adapter pcan_usb_x6;
 
+extern const struct net_device_ops pcan_usb_netdev_ops;
+extern const struct net_device_ops pcan_usb_netdev_ops_hwts;
+
 struct peak_time_ref {
 	ktime_t tv_host_0, tv_host;
 	u32 ts_dev_1, ts_dev_2;
diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_fd.c b/drivers/net/can/usb/peak_usb/pcan_usb_fd.c
index 63122f567380..3c0dc9391bec 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb_fd.c
+++ b/drivers/net/can/usb/peak_usb/pcan_usb_fd.c
@@ -1081,6 +1081,7 @@ static int pcan_usb_fd_set_phys_id(struct net_device *netdev,
 static const struct ethtool_ops pcan_usb_fd_ethtool_ops = {
 	.get_drvinfo = peak_usb_get_drvinfo,
 	.set_phys_id = pcan_usb_fd_set_phys_id,
+	.get_ts_info = ethtool_op_get_ts_info,
 };
 
 /* describes the PCAN-USB FD adapter */
@@ -1124,6 +1125,7 @@ const struct peak_usb_adapter pcan_usb_fd = {
 	/* size of device private data */
 	.sizeof_dev_private = sizeof(struct pcan_usb_fd_device),
 
+	.netdev_ops = &pcan_usb_netdev_ops_hwts,
 	.ethtool_ops = &pcan_usb_fd_ethtool_ops,
 
 	/* timestamps usage */
diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_pro.c b/drivers/net/can/usb/peak_usb/pcan_usb_pro.c
index ea2d4fbceaa4..7189fa70c08e 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb_pro.c
+++ b/drivers/net/can/usb/peak_usb/pcan_usb_pro.c
@@ -1023,6 +1023,7 @@ static int pcan_usb_pro_set_phys_id(struct net_device *netdev,
 static const struct ethtool_ops pcan_usb_pro_ethtool_ops = {
 	.get_drvinfo = peak_usb_get_drvinfo,
 	.set_phys_id = pcan_usb_pro_set_phys_id,
+	.get_ts_info = can_ethtool_op_get_ts_info_hwts,
 };
 
 /*
@@ -1054,6 +1055,7 @@ const struct peak_usb_adapter pcan_usb_pro = {
 	/* size of device private data */
 	.sizeof_dev_private = sizeof(struct pcan_usb_pro_device),
 
+	.netdev_ops = &pcan_usb_netdev_ops_hwts,
 	.ethtool_ops = &pcan_usb_pro_ethtool_ops,
 
 	/* timestamps usage */
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 92+ messages in thread

* Re: [PATCH v1 00/24] can: add ethtool support and reporting of timestamping capabilities
  2022-07-25 13:31 [PATCH v1 00/24] can: add ethtool support and reporting of timestamping capabilities Vincent Mailhol
                   ` (23 preceding siblings ...)
  2022-07-25 13:32 ` [PATCH v1 24/24] can: peak_usb: " Vincent Mailhol
@ 2022-07-25 13:53 ` Vincent MAILHOL
  2022-07-25 15:53 ` [PATCH v2 00/14] " Vincent Mailhol
                   ` (2 subsequent siblings)
  27 siblings, 0 replies; 92+ messages in thread
From: Vincent MAILHOL @ 2022-07-25 13:53 UTC (permalink / raw)
  To: linux-can, Marc Kleine-Budde
  Cc: Stephane Grosjean, Jimmy Assarsson, Oliver Hartkopp,
	Dario Binacchi, Max Staudt

On Sun. 25 Jul. 2022 at 22:32, Vincent Mailhol
<mailhol.vincent@wanadoo.fr> wrote:
> This series revolves around ethtool and timestamping. Its ultimate
> goal is that the timestamping implementation within socketCAN meets
> the specification of other network drivers in the kernel. This way,
> tcpdump or other tools derived from libpcap can be used to do
> timestamping on CAN devices.

For those of you who would like to test it, please have a look at the
other series I just sent:
https://lore.kernel.org/linux-can/20220725134345.432367-1-mailhol.vincent@wanadoo.fr/T/

@Marc, this is a long series (25 patches but many trivial ones) just
one week before the merge windows. Overall, I have a good confidence
on this series, except for the last four patches:
  can: kvaser_pciefd: advertise timestamping capabilities and add ioctl support
  can: kvaser_usb: advertise timestamping capabilities and add ioctl support
  can: peak_canfd: advertise timestamping capabilities and add ioctl support
  can: peak_usb: advertise timestamping capabilities and add ioctl support

For those last four patches, I would like to get the feedback from
Jimmy and Stéphane before it gets merged. If additional time is needed
for testing, it might be wise to just merge the first 21 patches and
leave those last 4 ones for the next cycle.

Yours sincerely,
Vincent Mailhol

^ permalink raw reply	[flat|nested] 92+ messages in thread

* Re: [PATCH v1 10/24] can: tree-wide: implement ethtool_ops::get_drvinfo()
  2022-07-25 13:31 ` [PATCH v1 10/24] can: tree-wide: implement ethtool_ops::get_drvinfo() Vincent Mailhol
@ 2022-07-25 14:09   ` Marc Kleine-Budde
  2022-07-25 14:29     ` Vincent MAILHOL
  2022-07-26  7:29   ` Dario Binacchi
  1 sibling, 1 reply; 92+ messages in thread
From: Marc Kleine-Budde @ 2022-07-25 14:09 UTC (permalink / raw)
  To: Vincent Mailhol
  Cc: linux-can, Stephane Grosjean, Jimmy Assarsson, Oliver Hartkopp,
	Dario Binacchi, Max Staudt

[-- Attachment #1: Type: text/plain, Size: 1081 bytes --]

On 25.07.2022 22:31:54, Vincent Mailhol wrote:
> For all CAN drivers, implement the get_drvinfo() function.
> 
> After this patch, it is now possible to retrieve basic information by
> doing:
> 
> | $ ethtool -i canX

This is the output of unpatched mcp251xfd driver. 

| $ ethtool -i mcp251xfd0
| driver: mcp251xfd
| version: 5.18.10-v8+
| firmware-version: 
| expansion-rom-version: 
| bus-info: spi0.0
| supports-statistics: no
| supports-test: no
| supports-eeprom-access: no
| supports-register-dump: no
| supports-priv-flags: no

(v5.19/patched is currently compiling}

IMHO there's no need to implement a default .get_drvinfo callback. BTW:
I removed one from the c_can driver some time ago:

https://lore.kernel.org/all/20220124215642.3474154-10-mkl@pengutronix.de/

Marc

-- 
Pengutronix e.K.                 | Marc Kleine-Budde           |
Embedded Linux                   | https://www.pengutronix.de  |
Vertretung West/Dortmund         | Phone: +49-231-2826-924     |
Amtsgericht Hildesheim, HRA 2686 | Fax:   +49-5121-206917-5555 |

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 92+ messages in thread

* Re: [PATCH v1 18/24] can: dev: add generic function can_eth_ioctl_hwts()
  2022-07-25 13:32 ` [PATCH v1 18/24] can: dev: add generic function can_eth_ioctl_hwts() Vincent Mailhol
@ 2022-07-25 14:22   ` Marc Kleine-Budde
  2022-07-25 14:41     ` Vincent MAILHOL
  0 siblings, 1 reply; 92+ messages in thread
From: Marc Kleine-Budde @ 2022-07-25 14:22 UTC (permalink / raw)
  To: Vincent Mailhol
  Cc: linux-can, Stephane Grosjean, Jimmy Assarsson, Oliver Hartkopp,
	Dario Binacchi, Max Staudt

[-- Attachment #1: Type: text/plain, Size: 2760 bytes --]

On 25.07.2022 22:32:02, Vincent Mailhol wrote:
> Tools based on libpcap (such as tcpdump) expect the SIOCSHWTSTAMP
> ioctl call to be supported. This is also specified in the kernel doc
> [1]. The purpose of this ioctl is to toggle the hardware timestamps.
> 
> Currently, CAN devices which support hardware timestamping have those
> always activated. can_eth_ioctl_hwts() is a dumb function that will
> always succeed when requested to set tx_type to HWTSTAMP_TX_ON or
> rx_filter to HWTSTAMP_FILTER_ALL.
> 
> [1] Kernel doc: Timestamping, section 3.1 "Hardware Timestamping
> Implementation: Device Drivers"
> Link: https://docs.kernel.org/networking/timestamping.html#hardware-timestamping-implementation-device-drivers
> 
> Signed-off-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
> ---
>  drivers/net/can/dev/dev.c | 29 +++++++++++++++++++++++++++++
>  include/linux/can/dev.h   |  1 +
>  2 files changed, 30 insertions(+)
> 
> diff --git a/drivers/net/can/dev/dev.c b/drivers/net/can/dev/dev.c
> index 7ad56d31cec9..750dc7cae9d4 100644
> --- a/drivers/net/can/dev/dev.c
> +++ b/drivers/net/can/dev/dev.c
> @@ -322,6 +322,35 @@ int can_change_mtu(struct net_device *dev, int new_mtu)
>  }
>  EXPORT_SYMBOL_GPL(can_change_mtu);
>  
> +/* generic implementation of netdev_ops::ndo_eth_ioctl for CAN devices
> + * supporting hardware RX timestamps
> + */
> +int can_eth_ioctl_hwts(struct net_device *netdev, struct ifreq *ifr, int cmd)
> +{
> +	struct hwtstamp_config hwts_cfg = { 0 };
> +
> +	switch (cmd) {
> +	case SIOCSHWTSTAMP: /* set */
> +		if (copy_from_user(&hwts_cfg, ifr->ifr_data, sizeof(hwts_cfg)))
> +			return -EFAULT;
> +		if (hwts_cfg.tx_type == HWTSTAMP_TX_ON &&
> +		    hwts_cfg.rx_filter == HWTSTAMP_FILTER_ALL)
> +			return 0;

I have a WIP hwts patch series for the mcp251xfd. IIRC the driver is
allowed to add RX timestamps to more packages than requested without
failing, so the relevant code my WIP patches looks like this:

+       switch (config.tx_type) {
+       case HWTSTAMP_TX_OFF:
+               break;
+       default:
+               return -ERANGE;
+       }
+
+       switch (config.rx_filter) {
+       case HWTSTAMP_FILTER_NONE:
+               clear_bit(MCP251XFD_FLAGS_TIMESTAMP_RX, priv->flags);
+               break;
+       default:
+               set_bit(MCP251XFD_FLAGS_TIMESTAMP_RX, priv->flags);
+               config.rx_filter = HWTSTAMP_FILTER_ALL;
+       }

Marc

-- 
Pengutronix e.K.                 | Marc Kleine-Budde           |
Embedded Linux                   | https://www.pengutronix.de  |
Vertretung West/Dortmund         | Phone: +49-231-2826-924     |
Amtsgericht Hildesheim, HRA 2686 | Fax:   +49-5121-206917-5555 |

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 92+ messages in thread

* Re: [PATCH v1 10/24] can: tree-wide: implement ethtool_ops::get_drvinfo()
  2022-07-25 14:09   ` Marc Kleine-Budde
@ 2022-07-25 14:29     ` Vincent MAILHOL
  0 siblings, 0 replies; 92+ messages in thread
From: Vincent MAILHOL @ 2022-07-25 14:29 UTC (permalink / raw)
  To: Marc Kleine-Budde
  Cc: linux-can, Stephane Grosjean, Jimmy Assarsson, Oliver Hartkopp,
	Dario Binacchi, Max Staudt

On Mon. 25 Jul. 2022 at 23:09, Marc Kleine-Budde <mkl@pengutronix.de> wrote:
> On 25.07.2022 22:31:54, Vincent Mailhol wrote:
> > For all CAN drivers, implement the get_drvinfo() function.
> >
> > After this patch, it is now possible to retrieve basic information by
> > doing:
> >
> > | $ ethtool -i canX
>
> This is the output of unpatched mcp251xfd driver.
>
> | $ ethtool -i mcp251xfd0
> | driver: mcp251xfd
> | version: 5.18.10-v8+
> | firmware-version:
> | expansion-rom-version:
> | bus-info: spi0.0
> | supports-statistics: no
> | supports-test: no
> | supports-eeprom-access: no
> | supports-register-dump: no
> | supports-priv-flags: no
>
> (v5.19/patched is currently compiling}
>
> IMHO there's no need to implement a default .get_drvinfo callback. BTW:
> I removed one from the c_can driver some time ago:
>
> https://lore.kernel.org/all/20220124215642.3474154-10-mkl@pengutronix.de/

Oh! struct ethtool_ops does not document that .get_drvinfo has a
default implementation. I will remove it. With this removed, patch 1
to 9 are not related anymore so I will split the series in two.


Yours sincerely,
Vincent Mailhol

^ permalink raw reply	[flat|nested] 92+ messages in thread

* Re: [PATCH v1 18/24] can: dev: add generic function can_eth_ioctl_hwts()
  2022-07-25 14:22   ` Marc Kleine-Budde
@ 2022-07-25 14:41     ` Vincent MAILHOL
  2022-07-25 16:19       ` Marc Kleine-Budde
  0 siblings, 1 reply; 92+ messages in thread
From: Vincent MAILHOL @ 2022-07-25 14:41 UTC (permalink / raw)
  To: Marc Kleine-Budde
  Cc: linux-can, Stephane Grosjean, Jimmy Assarsson, Oliver Hartkopp,
	Dario Binacchi, Max Staudt

On Mon. 25 juil. 2022 at 23:31, Marc Kleine-Budde <mkl@pengutronix.de> wrote:
> On 25.07.2022 22:32:02, Vincent Mailhol wrote:
> > Tools based on libpcap (such as tcpdump) expect the SIOCSHWTSTAMP
> > ioctl call to be supported. This is also specified in the kernel doc
> > [1]. The purpose of this ioctl is to toggle the hardware timestamps.
> >
> > Currently, CAN devices which support hardware timestamping have those
> > always activated. can_eth_ioctl_hwts() is a dumb function that will
> > always succeed when requested to set tx_type to HWTSTAMP_TX_ON or
> > rx_filter to HWTSTAMP_FILTER_ALL.
> >
> > [1] Kernel doc: Timestamping, section 3.1 "Hardware Timestamping
> > Implementation: Device Drivers"
> > Link: https://docs.kernel.org/networking/timestamping.html#hardware-timestamping-implementation-device-drivers
> >
> > Signed-off-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
> > ---
> >  drivers/net/can/dev/dev.c | 29 +++++++++++++++++++++++++++++
> >  include/linux/can/dev.h   |  1 +
> >  2 files changed, 30 insertions(+)
> >
> > diff --git a/drivers/net/can/dev/dev.c b/drivers/net/can/dev/dev.c
> > index 7ad56d31cec9..750dc7cae9d4 100644
> > --- a/drivers/net/can/dev/dev.c
> > +++ b/drivers/net/can/dev/dev.c
> > @@ -322,6 +322,35 @@ int can_change_mtu(struct net_device *dev, int new_mtu)
> >  }
> >  EXPORT_SYMBOL_GPL(can_change_mtu);
> >
> > +/* generic implementation of netdev_ops::ndo_eth_ioctl for CAN devices
> > + * supporting hardware RX timestamps
> > + */
> > +int can_eth_ioctl_hwts(struct net_device *netdev, struct ifreq *ifr, int cmd)
> > +{
> > +     struct hwtstamp_config hwts_cfg = { 0 };
> > +
> > +     switch (cmd) {
> > +     case SIOCSHWTSTAMP: /* set */
> > +             if (copy_from_user(&hwts_cfg, ifr->ifr_data, sizeof(hwts_cfg)))
> > +                     return -EFAULT;
> > +             if (hwts_cfg.tx_type == HWTSTAMP_TX_ON &&
> > +                 hwts_cfg.rx_filter == HWTSTAMP_FILTER_ALL)
> > +                     return 0;
>
> I have a WIP hwts patch series for the mcp251xfd. IIRC the driver is
> allowed to add RX timestamps to more packages than requested without
> failing, so the relevant code my WIP patches looks like this:
>
> +       switch (config.tx_type) {
> +       case HWTSTAMP_TX_OFF:
> +               break;
> +       default:
> +               return -ERANGE;
> +       }
> +
> +       switch (config.rx_filter) {
> +       case HWTSTAMP_FILTER_NONE:
> +               clear_bit(MCP251XFD_FLAGS_TIMESTAMP_RX, priv->flags);
> +               break;
> +       default:
> +               set_bit(MCP251XFD_FLAGS_TIMESTAMP_RX, priv->flags);
> +               config.rx_filter = HWTSTAMP_FILTER_ALL;
> +       }

What is the default value for rx_filter? Currently, candump -H
implicitly expects rx_filter to be HWTSTAMP_FILTER_ALL. Defaulting to
HWTSTAMP_FILTER_NONE would break the current versions of candump. so I
was wondering if it would be better for CAN to start with hardware
timestamps as active (in my series, I assume that HWTSTAMP_FILTER_NONE
is not supported and thus avoid this problem).

Moving forward, should I keep mcp251xfd in this series or should I
remove it and let you take care of it?


Yours sincerely,
Vincent Mailhol

^ permalink raw reply	[flat|nested] 92+ messages in thread

* [PATCH v2 00/14] can: add ethtool support and reporting of timestamping capabilities
  2022-07-25 13:31 [PATCH v1 00/24] can: add ethtool support and reporting of timestamping capabilities Vincent Mailhol
                   ` (24 preceding siblings ...)
  2022-07-25 13:53 ` [PATCH v1 00/24] can: add ethtool support and reporting of timestamping capabilities Vincent MAILHOL
@ 2022-07-25 15:53 ` Vincent Mailhol
  2022-07-25 15:53   ` [PATCH v2 01/14] can: can327: add software tx timestamps Vincent Mailhol
                     ` (13 more replies)
  2022-07-26 10:24 ` [PATCH v3 00/14] Vincent Mailhol
  2022-07-27 10:16 ` [PATCH v4 00/14] can: add ethtool support and reporting of timestamping capabilities Vincent Mailhol
  27 siblings, 14 replies; 92+ messages in thread
From: Vincent Mailhol @ 2022-07-25 15:53 UTC (permalink / raw)
  To: linux-can, Marc Kleine-Budde
  Cc: Stephane Grosjean, Jimmy Assarsson, Oliver Hartkopp,
	Dario Binacchi, Max Staudt, Vincent Mailhol

This series revolves around ethtool and timestamping. Its ultimate
goal is that the timestamping implementation within socketCAN meets
the specification of other network drivers in the kernel. This way,
tcpdump or other tools derived from libpcap can be used to do
timestamping on CAN devices.

* Example on a device with hardware timestamp support *

Before this series:
| # tcpdump -j adapter_unsynced -i can0
| tcpdump: WARNING: When trying to set timestamp type
| 'adapter_unsynced' on can0: That type of time stamp is not supported
| by that device

After applying this series, the warning disappears and tcpdump can be
used to get RX hardware timestamps.


This series is articulated in three major parts.

* Part 1: Add TX software timestamps and report the software
  timestamping capabilities through ethtool.

All the drivers using can_put_echo_skb() already support TX software
timestamps. However, the five drivers not using this function (namely
can327, janz-ican3, slcan, vcan and vxcan) lack such support. Patch 1
to 4 adds this support.  Finally, patch 5 advertises the timesamping
capabilities of all drivers which do not support hardware timestamps.


* Part 2: add TX hardware timestapms

This part is a single patch. In SocetCAN TX hardware is equal to the
RX hardware timestamps of the corresponding loopback frame. Reuse the
TX hardware timestamp to populate the RX hardware timestamp. While the
need of this feature can be debatable, we implement it here so that
generic timestamping tools which are agnostic of the specificity of
SocketCAN can still obtain the value. For example, tcpdump expects for
both TX and RX hardware timestamps to be supported in order to do:
| # tcpdump -j adapter_unsynced -i canX


* Part 3: report the hardware timestamping capabilities and implement
  the hardware timestamps ioctls.

The kernel documentation specifies in [1] that, for the drivers which
support hardware timestamping, SIOCSHWTSTAMP ioctl must be supported
and that SIOCGHWTSTAMP ioctl should be supported. Currently, none of
the CAN drivers do so. This is a gap.

Furthermore, even if not specified, the tools based on libpcap
(e.g. tcpdump) also expect ethtool_ops::get_ts_info to be implemented.

This last part first adds some generic implementation of
net_device_ops::ndo_eth_ioctl and ethtool_ops::get_ts_info which can
be used by the drivers with hardware timestamping capabilities.

It then uses those generic functions to add ioctl and reporting
functionalities to the drivers with hardware timestamping support
(namely: mcp251xfd, etas_es58x, kvaser_{pciefd,usb}, peak_{canfd,usb})


[1] Kernel doc: Timestamping, section 3.1 "Hardware Timestamping
Implementation: Device Drivers"
Link: https://docs.kernel.org/networking/timestamping.html#hardware-timestamping-implementation-device-drivers


* Testing *

I also developed a tool to test all the different timestamps. For
those who would also like to test it, please have a look at:
https://lore.kernel.org/linux-can/20220725134345.432367-1-mailhol.vincent@wanadoo.fr/T/


* Changelog *

v1 -> v2

  * First series had a patch to implement
    ethtool_ops::get_drvinfo. This proved to be useless. This patch
    was removed and all the clean-up patches made in preparation of
    that one were moved to a separate series:

    https://lore.kernel.org/linux-can/20220725153124.467061-1-mailhol.vincent@wanadoo.fr/T/#u

Vincent Mailhol (14):
  can: can327: add software tx timestamps
  can: janz-ican3: add software tx timestamp
  can: slcan: add software tx timestamps
  can: v(x)can: add software tx timestamps
  can: tree-wide: advertise software timestamping capabilities
  can: dev: add hardware TX timestamp
  can: dev: add generic function can_ethtool_op_get_ts_info_hwts()
  can: dev: add generic function can_eth_ioctl_hwts()
  can: mcp251xfd: advertise timestamping capabilities and add ioctl
    support
  can: etas_es58x: advertise timestamping capabilities and add ioctl
    support
  can: kvaser_pciefd: advertise timestamping capabilities and add ioctl
    support
  can: kvaser_usb: advertise timestamping capabilities and add ioctl
    support
  can: peak_canfd: advertise timestamping capabilities and add ioctl
    support
  can: peak_usb: advertise timestamping capabilities and add ioctl
    support

 drivers/net/can/at91_can.c                    |  6 +++
 drivers/net/can/c_can/c_can_main.c            |  6 +++
 drivers/net/can/can327.c                      |  7 +++
 drivers/net/can/cc770/cc770.c                 |  6 +++
 drivers/net/can/ctucanfd/ctucanfd_base.c      |  6 +++
 drivers/net/can/dev/dev.c                     | 50 +++++++++++++++++++
 drivers/net/can/dev/skb.c                     |  6 +++
 drivers/net/can/flexcan/flexcan-core.c        |  6 +++
 drivers/net/can/grcan.c                       |  6 +++
 drivers/net/can/ifi_canfd/ifi_canfd.c         |  6 +++
 drivers/net/can/janz-ican3.c                  |  8 +++
 drivers/net/can/kvaser_pciefd.c               |  7 +++
 drivers/net/can/m_can/m_can.c                 |  6 +++
 drivers/net/can/mscan/mscan.c                 |  1 +
 drivers/net/can/pch_can.c                     |  6 +++
 drivers/net/can/peak_canfd/peak_canfd.c       |  7 +++
 drivers/net/can/rcar/rcar_can.c               |  6 +++
 drivers/net/can/rcar/rcar_canfd.c             |  6 +++
 drivers/net/can/sja1000/sja1000.c             |  6 +++
 drivers/net/can/slcan/slcan-core.c            |  8 +++
 drivers/net/can/softing/softing_main.c        |  6 +++
 drivers/net/can/spi/hi311x.c                  |  6 +++
 drivers/net/can/spi/mcp251x.c                 |  6 +++
 .../net/can/spi/mcp251xfd/mcp251xfd-core.c    |  7 +++
 drivers/net/can/sun4i_can.c                   |  6 +++
 drivers/net/can/ti_hecc.c                     |  6 +++
 drivers/net/can/usb/ems_usb.c                 |  6 +++
 drivers/net/can/usb/esd_usb.c                 |  6 +++
 drivers/net/can/usb/etas_es58x/es58x_core.c   |  9 +++-
 drivers/net/can/usb/gs_usb.c                  |  2 +
 drivers/net/can/usb/kvaser_usb/kvaser_usb.h   |  1 +
 .../net/can/usb/kvaser_usb/kvaser_usb_core.c  | 27 +++++++++-
 drivers/net/can/usb/mcba_usb.c                |  6 +++
 drivers/net/can/usb/peak_usb/pcan_usb.c       |  2 +
 drivers/net/can/usb/peak_usb/pcan_usb_core.c  | 12 ++++-
 drivers/net/can/usb/peak_usb/pcan_usb_core.h  |  4 ++
 drivers/net/can/usb/peak_usb/pcan_usb_fd.c    |  2 +
 drivers/net/can/usb/peak_usb/pcan_usb_pro.c   |  2 +
 drivers/net/can/usb/ucan.c                    |  6 +++
 drivers/net/can/usb/usb_8dev.c                |  6 +++
 drivers/net/can/vcan.c                        |  8 +++
 drivers/net/can/vxcan.c                       |  8 +++
 drivers/net/can/xilinx_can.c                  |  6 +++
 include/linux/can/dev.h                       |  4 ++
 44 files changed, 315 insertions(+), 5 deletions(-)

-- 
2.35.1


^ permalink raw reply	[flat|nested] 92+ messages in thread

* [PATCH v2 01/14] can: can327: add software tx timestamps
  2022-07-25 15:53 ` [PATCH v2 00/14] " Vincent Mailhol
@ 2022-07-25 15:53   ` Vincent Mailhol
  2022-07-25 15:53   ` [PATCH v2 02/14] can: janz-ican3: add software tx timestamp Vincent Mailhol
                     ` (12 subsequent siblings)
  13 siblings, 0 replies; 92+ messages in thread
From: Vincent Mailhol @ 2022-07-25 15:53 UTC (permalink / raw)
  To: linux-can, Marc Kleine-Budde
  Cc: Stephane Grosjean, Jimmy Assarsson, Oliver Hartkopp,
	Dario Binacchi, Max Staudt, Vincent Mailhol

TX timestamps were added to the can_put_echo_skb() function of can_dev
modules in [1]. However, can327 does not rely on that function and as
such does not offer TX timestamping.

Add a call to skb_tx_timestamp() in the can327_netdev_start_xmit()
function so that the module now supports TX software timestamps.

[1] commit 741b91f1b0ea ("can: dev: can_put_echo_skb(): add software
tx timestamps")
Link: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=741b91f1b0ea34f00f6a7d4539b767c409291fcf

Signed-off-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
---
 drivers/net/can/can327.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/net/can/can327.c b/drivers/net/can/can327.c
index 5da7778d92dc..88718d0cc569 100644
--- a/drivers/net/can/can327.c
+++ b/drivers/net/can/can327.c
@@ -836,6 +836,8 @@ static netdev_tx_t can327_netdev_start_xmit(struct sk_buff *skb,
 	dev->stats.tx_packets++;
 	dev->stats.tx_bytes += frame->can_id & CAN_RTR_FLAG ? 0 : frame->len;
 
+	skb_tx_timestamp(skb);
+
 out:
 	kfree_skb(skb);
 	return NETDEV_TX_OK;
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 92+ messages in thread

* [PATCH v2 02/14] can: janz-ican3: add software tx timestamp
  2022-07-25 15:53 ` [PATCH v2 00/14] " Vincent Mailhol
  2022-07-25 15:53   ` [PATCH v2 01/14] can: can327: add software tx timestamps Vincent Mailhol
@ 2022-07-25 15:53   ` Vincent Mailhol
  2022-07-25 15:53   ` [PATCH v2 03/14] can: slcan: add software tx timestamps Vincent Mailhol
                     ` (11 subsequent siblings)
  13 siblings, 0 replies; 92+ messages in thread
From: Vincent Mailhol @ 2022-07-25 15:53 UTC (permalink / raw)
  To: linux-can, Marc Kleine-Budde
  Cc: Stephane Grosjean, Jimmy Assarsson, Oliver Hartkopp,
	Dario Binacchi, Max Staudt, Vincent Mailhol

TX timestamps were added to the can_put_echo_skb() function of can_dev
modules in [1]. However, janz-ican3 does not rely on that function but
instead implements its own echo_skb logic. As such it does not offer
TX timestamping.

Add a call to skb_tx_timestamp() in the ican3_put_echo_skb() function
so that the module now supports TX software timestamps.

[1] commit 741b91f1b0ea ("can: dev: can_put_echo_skb(): add software
tx timestamps")
Link: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=741b91f1b0ea34f00f6a7d4539b767c409291fcf

Signed-off-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
---
 drivers/net/can/janz-ican3.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/net/can/janz-ican3.c b/drivers/net/can/janz-ican3.c
index ccb5c5405224..78d9190a4220 100644
--- a/drivers/net/can/janz-ican3.c
+++ b/drivers/net/can/janz-ican3.c
@@ -1277,6 +1277,8 @@ static void ican3_put_echo_skb(struct ican3_dev *mod, struct sk_buff *skb)
 	if (!skb)
 		return;
 
+	skb_tx_timestamp(skb);
+
 	/* save this skb for tx interrupt echo handling */
 	skb_queue_tail(&mod->echoq, skb);
 }
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 92+ messages in thread

* [PATCH v2 03/14] can: slcan: add software tx timestamps
  2022-07-25 15:53 ` [PATCH v2 00/14] " Vincent Mailhol
  2022-07-25 15:53   ` [PATCH v2 01/14] can: can327: add software tx timestamps Vincent Mailhol
  2022-07-25 15:53   ` [PATCH v2 02/14] can: janz-ican3: add software tx timestamp Vincent Mailhol
@ 2022-07-25 15:53   ` Vincent Mailhol
  2022-07-25 15:53   ` [PATCH v2 04/14] can: v(x)can: " Vincent Mailhol
                     ` (10 subsequent siblings)
  13 siblings, 0 replies; 92+ messages in thread
From: Vincent Mailhol @ 2022-07-25 15:53 UTC (permalink / raw)
  To: linux-can, Marc Kleine-Budde
  Cc: Stephane Grosjean, Jimmy Assarsson, Oliver Hartkopp,
	Dario Binacchi, Max Staudt, Vincent Mailhol

TX timestamps were added to the can_put_echo_skb() function of can_dev
modules in [1]. However, slcan does not rely on that function and as
such does not offer TX timestamping.

Add a call to skb_tx_timestamp() in the slc_xmit() function so that
the module now supports TX software timestamps.

[1] commit 741b91f1b0ea ("can: dev: can_put_echo_skb(): add software
tx timestamps")
Link: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=741b91f1b0ea34f00f6a7d4539b767c409291fcf

CC: Dario Binacchi <dario.binacchi@amarulasolutions.com>
Signed-off-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
---
 drivers/net/can/slcan/slcan-core.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/net/can/slcan/slcan-core.c b/drivers/net/can/slcan/slcan-core.c
index dc28e715bbe1..d4dbeb849432 100644
--- a/drivers/net/can/slcan/slcan-core.c
+++ b/drivers/net/can/slcan/slcan-core.c
@@ -626,6 +626,8 @@ static netdev_tx_t slc_xmit(struct sk_buff *skb, struct net_device *dev)
 	slc_encaps(sl, (struct can_frame *)skb->data); /* encaps & send */
 	spin_unlock(&sl->lock);
 
+	skb_tx_timestamp(skb);
+
 out:
 	kfree_skb(skb);
 	return NETDEV_TX_OK;
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 92+ messages in thread

* [PATCH v2 04/14] can: v(x)can: add software tx timestamps
  2022-07-25 15:53 ` [PATCH v2 00/14] " Vincent Mailhol
                     ` (2 preceding siblings ...)
  2022-07-25 15:53   ` [PATCH v2 03/14] can: slcan: add software tx timestamps Vincent Mailhol
@ 2022-07-25 15:53   ` Vincent Mailhol
  2022-07-25 15:53   ` [PATCH v2 05/14] can: tree-wide: advertise software timestamping capabilities Vincent Mailhol
                     ` (9 subsequent siblings)
  13 siblings, 0 replies; 92+ messages in thread
From: Vincent Mailhol @ 2022-07-25 15:53 UTC (permalink / raw)
  To: linux-can, Marc Kleine-Budde
  Cc: Stephane Grosjean, Jimmy Assarsson, Oliver Hartkopp,
	Dario Binacchi, Max Staudt, Vincent Mailhol

TX timestamps were added to the can_put_echo_skb() function of can_dev
modules in [1]. However, vcan and vxcan do not rely on that function
and as such do not offer TX timestamping.

While it could be arguable whether TX timestamps are really needed for
virtual interfaces, we prefer to still add it so that all CAN dirvers,
without exception supports the TX software timestamps.

Add a call to skb_tx_timestamp() in the vcan_tx() and vxcan_xmit()
functions so that the modules now support TX software timestamps.

[1] commit 741b91f1b0ea ("can: dev: can_put_echo_skb(): add software
tx timestamps")
Link: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=741b91f1b0ea34f00f6a7d4539b767c409291fcf

Signed-off-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
---
 drivers/net/can/vcan.c  | 2 ++
 drivers/net/can/vxcan.c | 2 ++
 2 files changed, 4 insertions(+)

diff --git a/drivers/net/can/vcan.c b/drivers/net/can/vcan.c
index a15619d883ec..4a363cfcf97c 100644
--- a/drivers/net/can/vcan.c
+++ b/drivers/net/can/vcan.c
@@ -99,6 +99,8 @@ static netdev_tx_t vcan_tx(struct sk_buff *skb, struct net_device *dev)
 	/* set flag whether this packet has to be looped back */
 	loop = skb->pkt_type == PACKET_LOOPBACK;
 
+	skb_tx_timestamp(skb);
+
 	if (!echo) {
 		/* no echo handling available inside this driver */
 		if (loop) {
diff --git a/drivers/net/can/vxcan.c b/drivers/net/can/vxcan.c
index 577a80300514..61b6eca383f8 100644
--- a/drivers/net/can/vxcan.c
+++ b/drivers/net/can/vxcan.c
@@ -53,6 +53,8 @@ static netdev_tx_t vxcan_xmit(struct sk_buff *oskb, struct net_device *dev)
 		goto out_unlock;
 	}
 
+	skb_tx_timestamp(oskb);
+
 	skb = skb_clone(oskb, GFP_ATOMIC);
 	if (skb) {
 		consume_skb(oskb);
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 92+ messages in thread

* [PATCH v2 05/14] can: tree-wide: advertise software timestamping capabilities
  2022-07-25 15:53 ` [PATCH v2 00/14] " Vincent Mailhol
                     ` (3 preceding siblings ...)
  2022-07-25 15:53   ` [PATCH v2 04/14] can: v(x)can: " Vincent Mailhol
@ 2022-07-25 15:53   ` Vincent Mailhol
  2022-07-25 15:53   ` [PATCH v2 06/14] can: dev: add hardware TX timestamp Vincent Mailhol
                     ` (8 subsequent siblings)
  13 siblings, 0 replies; 92+ messages in thread
From: Vincent Mailhol @ 2022-07-25 15:53 UTC (permalink / raw)
  To: linux-can, Marc Kleine-Budde
  Cc: Stephane Grosjean, Jimmy Assarsson, Oliver Hartkopp,
	Dario Binacchi, Max Staudt, Vincent Mailhol

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 timespamping will be migrated
in separate patches.

Signed-off-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
---
 drivers/net/can/at91_can.c               | 6 ++++++
 drivers/net/can/c_can/c_can_main.c       | 6 ++++++
 drivers/net/can/can327.c                 | 5 +++++
 drivers/net/can/cc770/cc770.c            | 6 ++++++
 drivers/net/can/ctucanfd/ctucanfd_base.c | 6 ++++++
 drivers/net/can/flexcan/flexcan-core.c   | 6 ++++++
 drivers/net/can/grcan.c                  | 6 ++++++
 drivers/net/can/ifi_canfd/ifi_canfd.c    | 6 ++++++
 drivers/net/can/janz-ican3.c             | 6 ++++++
 drivers/net/can/m_can/m_can.c            | 6 ++++++
 drivers/net/can/mscan/mscan.c            | 1 +
 drivers/net/can/pch_can.c                | 6 ++++++
 drivers/net/can/rcar/rcar_can.c          | 6 ++++++
 drivers/net/can/rcar/rcar_canfd.c        | 6 ++++++
 drivers/net/can/sja1000/sja1000.c        | 6 ++++++
 drivers/net/can/slcan/slcan-core.c       | 6 ++++++
 drivers/net/can/softing/softing_main.c   | 6 ++++++
 drivers/net/can/spi/hi311x.c             | 6 ++++++
 drivers/net/can/spi/mcp251x.c            | 6 ++++++
 drivers/net/can/sun4i_can.c              | 6 ++++++
 drivers/net/can/ti_hecc.c                | 6 ++++++
 drivers/net/can/usb/ems_usb.c            | 6 ++++++
 drivers/net/can/usb/esd_usb.c            | 6 ++++++
 drivers/net/can/usb/gs_usb.c             | 2 ++
 drivers/net/can/usb/mcba_usb.c           | 6 ++++++
 drivers/net/can/usb/ucan.c               | 6 ++++++
 drivers/net/can/usb/usb_8dev.c           | 6 ++++++
 drivers/net/can/vcan.c                   | 6 ++++++
 drivers/net/can/vxcan.c                  | 6 ++++++
 drivers/net/can/xilinx_can.c             | 6 ++++++
 30 files changed, 170 insertions(+)

diff --git a/drivers/net/can/at91_can.c b/drivers/net/can/at91_can.c
index 29ed0d3cd171..3a2d109a3792 100644
--- a/drivers/net/can/at91_can.c
+++ b/drivers/net/can/at91_can.c
@@ -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>
@@ -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)
 {
@@ -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;
 
diff --git a/drivers/net/can/c_can/c_can_main.c b/drivers/net/can/c_can/c_can_main.c
index de38d8f7b5f7..4df834774333 100644
--- a/drivers/net/can/c_can/c_can_main.c
+++ b/drivers/net/can/c_can/c_can_main.c
@@ -29,6 +29,7 @@
 #include <linux/module.h>
 #include <linux/interrupt.h>
 #include <linux/delay.h>
+#include <linux/ethtool.h>
 #include <linux/netdevice.h>
 #include <linux/if_arp.h>
 #include <linux/if_ether.h>
@@ -1353,6 +1354,10 @@ static const struct net_device_ops c_can_netdev_ops = {
 	.ndo_change_mtu = can_change_mtu,
 };
 
+static const struct ethtool_ops c_can_ethtool_ops = {
+	.get_ts_info = ethtool_op_get_ts_info,
+};
+
 int register_c_can_dev(struct net_device *dev)
 {
 	/* Deactivate pins to prevent DRA7 DCAN IP from being
@@ -1364,6 +1369,7 @@ int register_c_can_dev(struct net_device *dev)
 
 	dev->flags |= IFF_ECHO;	/* we support local echo */
 	dev->netdev_ops = &c_can_netdev_ops;
+	dev->ethtool_ops = &c_can_ethtool_ops;
 	c_can_set_ethtool_ops(dev);
 
 	return register_candev(dev);
diff --git a/drivers/net/can/can327.c b/drivers/net/can/can327.c
index 88718d0cc569..bfa33f5e7fbe 100644
--- a/drivers/net/can/can327.c
+++ b/drivers/net/can/can327.c
@@ -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'] = {
@@ -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;
diff --git a/drivers/net/can/cc770/cc770.c b/drivers/net/can/cc770/cc770.c
index 797a954bb1a0..0b9dfc76e769 100644
--- a/drivers/net/can/cc770/cc770.c
+++ b/drivers/net/can/cc770/cc770.c
@@ -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>
@@ -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);
@@ -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 */
 
diff --git a/drivers/net/can/ctucanfd/ctucanfd_base.c b/drivers/net/can/ctucanfd/ctucanfd_base.c
index 6b281f6eb9b4..3c18d028bd8c 100644
--- a/drivers/net/can/ctucanfd/ctucanfd_base.c
+++ b/drivers/net/can/ctucanfd/ctucanfd_base.c
@@ -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>
@@ -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);
@@ -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) {
diff --git a/drivers/net/can/flexcan/flexcan-core.c b/drivers/net/can/flexcan/flexcan-core.c
index d060088047f1..3f8138c65a54 100644
--- a/drivers/net/can/flexcan/flexcan-core.c
+++ b/drivers/net/can/flexcan/flexcan-core.c
@@ -16,6 +16,7 @@
 #include <linux/can/error.h>
 #include <linux/clk.h>
 #include <linux/delay.h>
+#include <linux/ethtool.h>
 #include <linux/firmware/imx/sci.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
@@ -1813,6 +1814,10 @@ static const struct net_device_ops flexcan_netdev_ops = {
 	.ndo_change_mtu = can_change_mtu,
 };
 
+static const struct ethtool_ops flexcan_ethtool_ops = {
+	.get_ts_info = ethtool_op_get_ts_info,
+};
+
 static int register_flexcandev(struct net_device *dev)
 {
 	struct flexcan_priv *priv = netdev_priv(dev);
@@ -2113,6 +2118,7 @@ static int flexcan_probe(struct platform_device *pdev)
 	SET_NETDEV_DEV(dev, &pdev->dev);
 
 	dev->netdev_ops = &flexcan_netdev_ops;
+	dev->ethtool_ops = &flexcan_ethtool_ops;
 	flexcan_set_ethtool_ops(dev);
 	dev->irq = irq;
 	dev->flags |= IFF_ECHO;
diff --git a/drivers/net/can/grcan.c b/drivers/net/can/grcan.c
index 24035a6187c9..6c37aab93eb3 100644
--- a/drivers/net/can/grcan.c
+++ b/drivers/net/can/grcan.c
@@ -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>
@@ -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)
@@ -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);
diff --git a/drivers/net/can/ifi_canfd/ifi_canfd.c b/drivers/net/can/ifi_canfd/ifi_canfd.c
index 64e3be8b73af..ad7a89b95da7 100644
--- a/drivers/net/can/ifi_canfd/ifi_canfd.c
+++ b/drivers/net/can/ifi_canfd/ifi_canfd.c
@@ -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>
@@ -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;
@@ -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;
diff --git a/drivers/net/can/janz-ican3.c b/drivers/net/can/janz-ican3.c
index 78d9190a4220..71a2caae0757 100644
--- a/drivers/net/can/janz-ican3.c
+++ b/drivers/net/can/janz-ican3.c
@@ -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>
@@ -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
  */
@@ -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);
 
diff --git a/drivers/net/can/m_can/m_can.c b/drivers/net/can/m_can/m_can.c
index 713a4b0edf86..4709c012b1dc 100644
--- a/drivers/net/can/m_can/m_can.c
+++ b/drivers/net/can/m_can/m_can.c
@@ -9,6 +9,7 @@
  */
 
 #include <linux/bitfield.h>
+#include <linux/ethtool.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
 #include <linux/kernel.h>
@@ -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);
 }
diff --git a/drivers/net/can/mscan/mscan.c b/drivers/net/can/mscan/mscan.c
index 78a21ab63601..b1677588a4c8 100644
--- a/drivers/net/can/mscan/mscan.c
+++ b/drivers/net/can/mscan/mscan.c
@@ -676,6 +676,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 */
 
diff --git a/drivers/net/can/pch_can.c b/drivers/net/can/pch_can.c
index 32804fed116c..0558ff67ec6a 100644
--- a/drivers/net/can/pch_can.c
+++ b/drivers/net/can/pch_can.c
@@ -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>
@@ -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);
@@ -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);
diff --git a/drivers/net/can/rcar/rcar_can.c b/drivers/net/can/rcar/rcar_can.c
index d11db2112a4a..6ee968c59ac9 100644
--- a/drivers/net/can/rcar/rcar_can.c
+++ b/drivers/net/can/rcar/rcar_can.c
@@ -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>
@@ -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;
@@ -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;
diff --git a/drivers/net/can/rcar/rcar_canfd.c b/drivers/net/can/rcar/rcar_canfd.c
index d3e569a02b4d..27085b796e75 100644
--- a/drivers/net/can/rcar/rcar_canfd.c
+++ b/drivers/net/can/rcar/rcar_canfd.c
@@ -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>
@@ -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)
 {
@@ -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;
diff --git a/drivers/net/can/sja1000/sja1000.c b/drivers/net/can/sja1000/sja1000.c
index 75a2f9bf8c16..98dfd5f295a7 100644
--- a/drivers/net/can/sja1000/sja1000.c
+++ b/drivers/net/can/sja1000/sja1000.c
@@ -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>
@@ -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;
@@ -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);
diff --git a/drivers/net/can/slcan/slcan-core.c b/drivers/net/can/slcan/slcan-core.c
index d4dbeb849432..0c2783520068 100644
--- a/drivers/net/can/slcan/slcan-core.c
+++ b/drivers/net/can/slcan/slcan-core.c
@@ -43,6 +43,7 @@
 #include <linux/string.h>
 #include <linux/tty.h>
 #include <linux/errno.h>
+#include <linux/ethtool.h>
 #include <linux/netdevice.h>
 #include <linux/skbuff.h>
 #include <linux/rtnetlink.h>
@@ -789,6 +790,10 @@ static const struct net_device_ops slc_netdev_ops = {
 	.ndo_change_mtu         = slcan_change_mtu,
 };
 
+static const struct ethtool_ops slcan_ethtool_ops = {
+	.get_ts_info = ethtool_op_get_ts_info,
+};
+
 /******************************************
  *  Routines looking at TTY side.
  ******************************************/
@@ -868,6 +873,7 @@ static struct slcan *slc_alloc(void)
 
 	snprintf(dev->name, sizeof(dev->name), "slcan%d", i);
 	dev->netdev_ops = &slc_netdev_ops;
+	dev->ethtool_ops = &slcan_ethtool_ops;
 	dev->base_addr  = i;
 	slcan_set_ethtool_ops(dev);
 	sl = netdev_priv(dev);
diff --git a/drivers/net/can/softing/softing_main.c b/drivers/net/can/softing/softing_main.c
index 8d27ac66ca7f..27579f99ef74 100644
--- a/drivers/net/can/softing/softing_main.c
+++ b/drivers/net/can/softing/softing_main.c
@@ -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>
@@ -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 = "softing",
 	.tseg1_min = 1,
@@ -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;
 
diff --git a/drivers/net/can/spi/hi311x.c b/drivers/net/can/spi/hi311x.c
index 167114aae6dd..b87dc420428d 100644
--- a/drivers/net/can/spi/hi311x.c
+++ b/drivers/net/can/spi/hi311x.c
@@ -20,6 +20,7 @@
 #include <linux/completion.h>
 #include <linux/delay.h>
 #include <linux/device.h>
+#include <linux/ethtool.h>
 #include <linux/freezer.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
@@ -802,6 +803,10 @@ static const struct net_device_ops hi3110_netdev_ops = {
 	.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[] = {
 	{
 		.compatible	= "holt,hi3110",
@@ -856,6 +861,7 @@ static int hi3110_can_probe(struct spi_device *spi)
 		goto out_free;
 
 	net->netdev_ops = &hi3110_netdev_ops;
+	net->ethtool_ops = &hi3110_ethtool_ops;
 	net->flags |= IFF_ECHO;
 
 	priv = netdev_priv(net);
diff --git a/drivers/net/can/spi/mcp251x.c b/drivers/net/can/spi/mcp251x.c
index 666a4505a55a..e750d13c8841 100644
--- a/drivers/net/can/spi/mcp251x.c
+++ b/drivers/net/can/spi/mcp251x.c
@@ -26,6 +26,7 @@
 #include <linux/completion.h>
 #include <linux/delay.h>
 #include <linux/device.h>
+#include <linux/ethtool.h>
 #include <linux/freezer.h>
 #include <linux/gpio.h>
 #include <linux/gpio/driver.h>
@@ -1248,6 +1249,10 @@ static const struct net_device_ops mcp251x_netdev_ops = {
 	.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[] = {
 	{
 		.compatible	= "microchip,mcp2510",
@@ -1313,6 +1318,7 @@ static int mcp251x_can_probe(struct spi_device *spi)
 		goto out_free;
 
 	net->netdev_ops = &mcp251x_netdev_ops;
+	net->ethtool_ops = &mcp251x_ethtool_ops;
 	net->flags |= IFF_ECHO;
 
 	priv = netdev_priv(net);
diff --git a/drivers/net/can/sun4i_can.c b/drivers/net/can/sun4i_can.c
index b90dfb429ccd..525309da1320 100644
--- a/drivers/net/can/sun4i_can.c
+++ b/drivers/net/can/sun4i_can.c
@@ -53,6 +53,7 @@
 #include <linux/can/error.h>
 #include <linux/clk.h>
 #include <linux/delay.h>
+#include <linux/ethtool.h>
 #include <linux/interrupt.h>
 #include <linux/init.h>
 #include <linux/io.h>
@@ -761,6 +762,10 @@ static const struct net_device_ops sun4ican_netdev_ops = {
 	.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 = {
 	.has_reset = false,
 };
@@ -851,6 +856,7 @@ static int sun4ican_probe(struct platform_device *pdev)
 	}
 
 	dev->netdev_ops = &sun4ican_netdev_ops;
+	dev->ethtool_ops = &sun4ican_ethtool_ops;
 	dev->irq = irq;
 	dev->flags |= IFF_ECHO;
 
diff --git a/drivers/net/can/ti_hecc.c b/drivers/net/can/ti_hecc.c
index afa38771520e..ec0ffeeb2015 100644
--- a/drivers/net/can/ti_hecc.c
+++ b/drivers/net/can/ti_hecc.c
@@ -23,6 +23,7 @@
 #include <linux/types.h>
 #include <linux/interrupt.h>
 #include <linux/errno.h>
+#include <linux/ethtool.h>
 #include <linux/netdevice.h>
 #include <linux/skbuff.h>
 #include <linux/platform_device.h>
@@ -841,6 +842,10 @@ static const struct net_device_ops ti_hecc_netdev_ops = {
 	.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[] = {
 	{
 		.compatible = "ti,am3517-hecc",
@@ -918,6 +923,7 @@ static int ti_hecc_probe(struct platform_device *pdev)
 	platform_set_drvdata(pdev, ndev);
 	SET_NETDEV_DEV(ndev, &pdev->dev);
 	ndev->netdev_ops = &ti_hecc_netdev_ops;
+	ndev->ethtool_ops = &ti_hecc_ethtool_ops;
 
 	priv->clk = clk_get(&pdev->dev, "hecc_ck");
 	if (IS_ERR(priv->clk)) {
diff --git a/drivers/net/can/usb/ems_usb.c b/drivers/net/can/usb/ems_usb.c
index bbec3311d893..429fc53761d1 100644
--- a/drivers/net/can/usb/ems_usb.c
+++ b/drivers/net/can/usb/ems_usb.c
@@ -4,6 +4,7 @@
  *
  * Copyright (C) 2004-2009 EMS Dr. Thomas Wuensche
  */
+#include <linux/ethtool.h>
 #include <linux/signal.h>
 #include <linux/slab.h>
 #include <linux/module.h>
@@ -879,6 +880,10 @@ static const struct net_device_ops ems_usb_netdev_ops = {
 	.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 = {
 	.name = "ems_usb",
 	.tseg1_min = 1,
@@ -990,6 +995,7 @@ static int ems_usb_probe(struct usb_interface *intf,
 	dev->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES;
 
 	netdev->netdev_ops = &ems_usb_netdev_ops;
+	netdev->ethtool_ops = &ems_usb_ethtool_ops;
 
 	netdev->flags |= IFF_ECHO; /* we support local echo */
 
diff --git a/drivers/net/can/usb/esd_usb.c b/drivers/net/can/usb/esd_usb.c
index 177ed33e08d9..646cb85b3108 100644
--- a/drivers/net/can/usb/esd_usb.c
+++ b/drivers/net/can/usb/esd_usb.c
@@ -5,6 +5,7 @@
  * 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>
  */
+#include <linux/ethtool.h>
 #include <linux/signal.h>
 #include <linux/slab.h>
 #include <linux/module.h>
@@ -882,6 +883,10 @@ static const struct net_device_ops esd_usb_netdev_ops = {
 	.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 = {
 	.name = "esd_usb2",
 	.tseg1_min = ESD_USB2_TSEG1_MIN,
@@ -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->netdev_ops = &esd_usb_netdev_ops;
+	netdev->ethtool_ops = &esd_usb_ethtool_ops;
 
 	SET_NETDEV_DEV(netdev, &intf->dev);
 	netdev->dev_id = index;
diff --git a/drivers/net/can/usb/gs_usb.c b/drivers/net/can/usb/gs_usb.c
index d3a658b444b5..0b2172bc57f1 100644
--- a/drivers/net/can/usb/gs_usb.c
+++ b/drivers/net/can/usb/gs_usb.c
@@ -946,6 +946,7 @@ static int gs_usb_set_phys_id(struct net_device *dev,
 
 static const struct ethtool_ops gs_usb_ethtool_ops = {
 	.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,
@@ -989,6 +990,7 @@ static struct gs_can *gs_make_candev(unsigned int channel,
 	dev = netdev_priv(netdev);
 
 	netdev->netdev_ops = &gs_usb_netdev_ops;
+	netdev->ethtool_ops = &gs_usb_ethtool_ops;
 
 	netdev->flags |= IFF_ECHO; /* we support full roundtrip echo */
 
diff --git a/drivers/net/can/usb/mcba_usb.c b/drivers/net/can/usb/mcba_usb.c
index 792ab9da317d..69346c63021f 100644
--- a/drivers/net/can/usb/mcba_usb.c
+++ b/drivers/net/can/usb/mcba_usb.c
@@ -10,6 +10,7 @@
 #include <linux/can.h>
 #include <linux/can/dev.h>
 #include <linux/can/error.h>
+#include <linux/ethtool.h>
 #include <linux/module.h>
 #include <linux/netdevice.h>
 #include <linux/signal.h>
@@ -758,6 +759,10 @@ static const struct net_device_ops mcba_netdev_ops = {
 	.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.
  * This function sends request via USB to change the speed and align bittiming
  * values for presentation purposes only
@@ -836,6 +841,7 @@ static int mcba_usb_probe(struct usb_interface *intf,
 	priv->can.do_set_bittiming = mcba_net_set_bittiming;
 
 	netdev->netdev_ops = &mcba_netdev_ops;
+	netdev->ethtool_ops = &mcba_ethtool_ops;
 
 	netdev->flags |= IFF_ECHO; /* we support local echo */
 
diff --git a/drivers/net/can/usb/ucan.c b/drivers/net/can/usb/ucan.c
index 5ae0d7c017cc..7c35f50fda4e 100644
--- a/drivers/net/can/usb/ucan.c
+++ b/drivers/net/can/usb/ucan.c
@@ -28,6 +28,7 @@
 #include <linux/can.h>
 #include <linux/can/dev.h>
 #include <linux/can/error.h>
+#include <linux/ethtool.h>
 #include <linux/module.h>
 #include <linux/netdevice.h>
 #include <linux/signal.h>
@@ -1233,6 +1234,10 @@ static const struct net_device_ops ucan_netdev_ops = {
 	.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
  *
  * This function generates an USB set bittiming message and transmits
@@ -1512,6 +1517,7 @@ static int ucan_probe(struct usb_interface *intf,
 	spin_lock_init(&up->context_lock);
 	spin_lock_init(&up->echo_skb_lock);
 	netdev->netdev_ops = &ucan_netdev_ops;
+	netdev->ethtool_ops = &ucan_ethtool_ops;
 
 	usb_set_intfdata(intf, up);
 	SET_NETDEV_DEV(netdev, &intf->dev);
diff --git a/drivers/net/can/usb/usb_8dev.c b/drivers/net/can/usb/usb_8dev.c
index 8b7cd69e20b0..9453956303c0 100644
--- a/drivers/net/can/usb/usb_8dev.c
+++ b/drivers/net/can/usb/usb_8dev.c
@@ -12,6 +12,7 @@
  * who were very cooperative and answered my questions.
  */
 
+#include <linux/ethtool.h>
 #include <linux/signal.h>
 #include <linux/slab.h>
 #include <linux/module.h>
@@ -870,6 +871,10 @@ static const struct net_device_ops usb_8dev_netdev_ops = {
 	.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 = {
 	.name = "usb_8dev",
 	.tseg1_min = 1,
@@ -927,6 +932,7 @@ static int usb_8dev_probe(struct usb_interface *intf,
 				      CAN_CTRLMODE_CC_LEN8_DLC;
 
 	netdev->netdev_ops = &usb_8dev_netdev_ops;
+	netdev->ethtool_ops = &usb_8dev_ethtool_ops;
 
 	netdev->flags |= IFF_ECHO; /* we support local echo */
 
diff --git a/drivers/net/can/vcan.c b/drivers/net/can/vcan.c
index 4a363cfcf97c..36b6310a2e5b 100644
--- a/drivers/net/can/vcan.c
+++ b/drivers/net/can/vcan.c
@@ -40,6 +40,7 @@
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
+#include <linux/ethtool.h>
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/netdevice.h>
@@ -148,6 +149,10 @@ static const struct net_device_ops vcan_netdev_ops = {
 	.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)
 {
 	dev->type		= ARPHRD_CAN;
@@ -163,6 +168,7 @@ static void vcan_setup(struct net_device *dev)
 		dev->flags |= IFF_ECHO;
 
 	dev->netdev_ops		= &vcan_netdev_ops;
+	dev->ethtool_ops	= &vcan_ethtool_ops;
 	dev->needs_free_netdev	= true;
 }
 
diff --git a/drivers/net/can/vxcan.c b/drivers/net/can/vxcan.c
index 61b6eca383f8..cffd107d8b28 100644
--- a/drivers/net/can/vxcan.c
+++ b/drivers/net/can/vxcan.c
@@ -9,6 +9,7 @@
  * Copyright (c) 2017 Oliver Hartkopp <socketcan@hartkopp.net>
  */
 
+#include <linux/ethtool.h>
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/netdevice.h>
@@ -146,6 +147,10 @@ static const struct net_device_ops vxcan_netdev_ops = {
 	.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)
 {
 	struct can_ml_priv *can_ml;
@@ -157,6 +162,7 @@ static void vxcan_setup(struct net_device *dev)
 	dev->tx_queue_len	= 0;
 	dev->flags		= IFF_NOARP;
 	dev->netdev_ops		= &vxcan_netdev_ops;
+	dev->ethtool_ops	= &vxcan_ethtool_ops;
 	dev->needs_free_netdev	= true;
 
 	can_ml = netdev_priv(dev) + ALIGN(sizeof(struct vxcan_priv), NETDEV_ALIGN);
diff --git a/drivers/net/can/xilinx_can.c b/drivers/net/can/xilinx_can.c
index caa6b4cee63f..5d3172795ad0 100644
--- a/drivers/net/can/xilinx_can.c
+++ b/drivers/net/can/xilinx_can.c
@@ -12,6 +12,7 @@
 #include <linux/bitfield.h>
 #include <linux/clk.h>
 #include <linux/errno.h>
+#include <linux/ethtool.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
@@ -1540,6 +1541,10 @@ static const struct net_device_ops xcan_netdev_ops = {
 	.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
  * @dev:	Address of the device structure
@@ -1821,6 +1826,7 @@ static int xcan_probe(struct platform_device *pdev)
 	platform_set_drvdata(pdev, ndev);
 	SET_NETDEV_DEV(ndev, &pdev->dev);
 	ndev->netdev_ops = &xcan_netdev_ops;
+	ndev->ethtool_ops = &xcan_ethtool_ops;
 
 	/* Getting the CAN can_clk info */
 	priv->can_clk = devm_clk_get(&pdev->dev, "can_clk");
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 92+ messages in thread

* [PATCH v2 06/14] can: dev: add hardware TX timestamp
  2022-07-25 15:53 ` [PATCH v2 00/14] " Vincent Mailhol
                     ` (4 preceding siblings ...)
  2022-07-25 15:53   ` [PATCH v2 05/14] can: tree-wide: advertise software timestamping capabilities Vincent Mailhol
@ 2022-07-25 15:53   ` Vincent Mailhol
  2022-07-25 15:53   ` [PATCH v2 07/14] can: dev: add generic function can_ethtool_op_get_ts_info_hwts() Vincent Mailhol
                     ` (7 subsequent siblings)
  13 siblings, 0 replies; 92+ messages in thread
From: Vincent Mailhol @ 2022-07-25 15:53 UTC (permalink / raw)
  To: linux-can, Marc Kleine-Budde
  Cc: Stephane Grosjean, Jimmy Assarsson, Oliver Hartkopp,
	Dario Binacchi, Max Staudt, Vincent Mailhol

Because of the loopback feature of socket CAN, hardware TX timestamps
are nothing else than the hardware RX timespamp of the corresponding
loopback packet. This patch simply reuses the hardware RX timestamp.

The rationale to clone this timestamp value is that existing tools
which rely of libpcap (such as tcpdump) expect support for both TX and
RX hardware timestamps in order to activate the feature (i.e. no
granular control to activate either of TX or RX hardware timestamps).

Signed-off-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
---
 drivers/net/can/dev/skb.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/net/can/dev/skb.c b/drivers/net/can/dev/skb.c
index 8bb62dd864c8..07e0feac8629 100644
--- a/drivers/net/can/dev/skb.c
+++ b/drivers/net/can/dev/skb.c
@@ -72,6 +72,9 @@ int can_put_echo_skb(struct sk_buff *skb, struct net_device *dev,
 		/* save frame_len to reuse it when transmission is completed */
 		can_skb_prv(skb)->frame_len = frame_len;
 
+		if (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)
+			skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;
+
 		skb_tx_timestamp(skb);
 
 		/* save this skb for tx interrupt echo handling */
@@ -107,6 +110,9 @@ __can_get_echo_skb(struct net_device *dev, unsigned int idx, u8 *len_ptr,
 		struct can_skb_priv *can_skb_priv = can_skb_prv(skb);
 		struct canfd_frame *cf = (struct canfd_frame *)skb->data;
 
+		if (skb_shinfo(skb)->tx_flags & SKBTX_IN_PROGRESS)
+			skb_tstamp_tx(skb, skb_hwtstamps(skb));
+
 		/* get the real payload length for netdev statistics */
 		if (cf->can_id & CAN_RTR_FLAG)
 			*len_ptr = 0;
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 92+ messages in thread

* [PATCH v2 07/14] can: dev: add generic function can_ethtool_op_get_ts_info_hwts()
  2022-07-25 15:53 ` [PATCH v2 00/14] " Vincent Mailhol
                     ` (5 preceding siblings ...)
  2022-07-25 15:53   ` [PATCH v2 06/14] can: dev: add hardware TX timestamp Vincent Mailhol
@ 2022-07-25 15:53   ` Vincent Mailhol
  2022-07-25 15:53   ` [PATCH v2 08/14] can: dev: add generic function can_eth_ioctl_hwts() Vincent Mailhol
                     ` (6 subsequent siblings)
  13 siblings, 0 replies; 92+ messages in thread
From: Vincent Mailhol @ 2022-07-25 15:53 UTC (permalink / raw)
  To: linux-can, Marc Kleine-Budde
  Cc: Stephane Grosjean, Jimmy Assarsson, Oliver Hartkopp,
	Dario Binacchi, Max Staudt, Vincent Mailhol

Add function can_ethtool_op_get_ts_info_hwts(). This function will be
used by CAN devices with hardware TX/RX timestamping support to
implement ethtool_ops::get_ts_info. This function does not offer
support to activate/deactivate hardware timestamps at device level nor
support the filter options (which is currently the case for all CAN
devices with hardware timestamping support).

The fact that hardware timestamp can not be deactivated at hardware
level does not impact the userland. As long as the user do not set
SO_TIMESTAMPING using a setsockopt() or ioctl(), the kernel will not
emit TX timestamps (RX timestamps will still be reproted as it is the
case currently).

Drivers which need more fine grained control remains free to implement
their own function, but we foresee that the generic function
introduced here will be sufficient for the majority.

Signed-off-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
---
 drivers/net/can/dev/dev.c | 21 +++++++++++++++++++++
 include/linux/can/dev.h   |  3 +++
 2 files changed, 24 insertions(+)

diff --git a/drivers/net/can/dev/dev.c b/drivers/net/can/dev/dev.c
index 523eaacfe29e..f307034ff4fd 100644
--- a/drivers/net/can/dev/dev.c
+++ b/drivers/net/can/dev/dev.c
@@ -322,6 +322,27 @@ int can_change_mtu(struct net_device *dev, int new_mtu)
 }
 EXPORT_SYMBOL_GPL(can_change_mtu);
 
+/* generic implementation of ethtool_ops::get_ts_info for CAN devices
+ * supporting hardware timestamps
+ */
+int can_ethtool_op_get_ts_info_hwts(struct net_device *dev,
+				    struct ethtool_ts_info *info)
+{
+	info->so_timestamping =
+		SOF_TIMESTAMPING_TX_SOFTWARE |
+		SOF_TIMESTAMPING_RX_SOFTWARE |
+		SOF_TIMESTAMPING_SOFTWARE |
+		SOF_TIMESTAMPING_TX_HARDWARE |
+		SOF_TIMESTAMPING_RX_HARDWARE |
+		SOF_TIMESTAMPING_RAW_HARDWARE;
+	info->phc_index = -1;
+	info->tx_types = BIT(HWTSTAMP_TX_ON);
+	info->rx_filters = BIT(HWTSTAMP_FILTER_ALL);
+
+	return 0;
+}
+EXPORT_SYMBOL(can_ethtool_op_get_ts_info_hwts);
+
 /* Common open function when the device gets opened.
  *
  * This function should be called in the open function of the device
diff --git a/include/linux/can/dev.h b/include/linux/can/dev.h
index e22dc03c850e..752bd45d8ebf 100644
--- a/include/linux/can/dev.h
+++ b/include/linux/can/dev.h
@@ -20,6 +20,7 @@
 #include <linux/can/length.h>
 #include <linux/can/netlink.h>
 #include <linux/can/skb.h>
+#include <linux/ethtool.h>
 #include <linux/netdevice.h>
 
 /*
@@ -162,6 +163,8 @@ struct can_priv *safe_candev_priv(struct net_device *dev);
 int open_candev(struct net_device *dev);
 void close_candev(struct net_device *dev);
 int can_change_mtu(struct net_device *dev, int new_mtu);
+int can_ethtool_op_get_ts_info_hwts(struct net_device *dev,
+				    struct ethtool_ts_info *info);
 
 int register_candev(struct net_device *dev);
 void unregister_candev(struct net_device *dev);
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 92+ messages in thread

* [PATCH v2 08/14] can: dev: add generic function can_eth_ioctl_hwts()
  2022-07-25 15:53 ` [PATCH v2 00/14] " Vincent Mailhol
                     ` (6 preceding siblings ...)
  2022-07-25 15:53   ` [PATCH v2 07/14] can: dev: add generic function can_ethtool_op_get_ts_info_hwts() Vincent Mailhol
@ 2022-07-25 15:53   ` Vincent Mailhol
  2022-07-25 15:53   ` [PATCH v2 09/14] can: mcp251xfd: advertise timestamping capabilities and add ioctl support Vincent Mailhol
                     ` (5 subsequent siblings)
  13 siblings, 0 replies; 92+ messages in thread
From: Vincent Mailhol @ 2022-07-25 15:53 UTC (permalink / raw)
  To: linux-can, Marc Kleine-Budde
  Cc: Stephane Grosjean, Jimmy Assarsson, Oliver Hartkopp,
	Dario Binacchi, Max Staudt, Vincent Mailhol

Tools based on libpcap (such as tcpdump) expect the SIOCSHWTSTAMP
ioctl call to be supported. This is also specified in the kernel doc
[1]. The purpose of this ioctl is to toggle the hardware timestamps.

Currently, CAN devices which support hardware timestamping have those
always activated. can_eth_ioctl_hwts() is a dumb function that will
always succeed when requested to set tx_type to HWTSTAMP_TX_ON or
rx_filter to HWTSTAMP_FILTER_ALL.

[1] Kernel doc: Timestamping, section 3.1 "Hardware Timestamping
Implementation: Device Drivers"
Link: https://docs.kernel.org/networking/timestamping.html#hardware-timestamping-implementation-device-drivers

Signed-off-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
---
 drivers/net/can/dev/dev.c | 29 +++++++++++++++++++++++++++++
 include/linux/can/dev.h   |  1 +
 2 files changed, 30 insertions(+)

diff --git a/drivers/net/can/dev/dev.c b/drivers/net/can/dev/dev.c
index f307034ff4fd..c1956b1e9faf 100644
--- a/drivers/net/can/dev/dev.c
+++ b/drivers/net/can/dev/dev.c
@@ -322,6 +322,35 @@ int can_change_mtu(struct net_device *dev, int new_mtu)
 }
 EXPORT_SYMBOL_GPL(can_change_mtu);
 
+/* generic implementation of netdev_ops::ndo_eth_ioctl for CAN devices
+ * supporting hardware timestamps
+ */
+int can_eth_ioctl_hwts(struct net_device *netdev, struct ifreq *ifr, int cmd)
+{
+	struct hwtstamp_config hwts_cfg = { 0 };
+
+	switch (cmd) {
+	case SIOCSHWTSTAMP: /* set */
+		if (copy_from_user(&hwts_cfg, ifr->ifr_data, sizeof(hwts_cfg)))
+			return -EFAULT;
+		if (hwts_cfg.tx_type == HWTSTAMP_TX_ON &&
+		    hwts_cfg.rx_filter == HWTSTAMP_FILTER_ALL)
+			return 0;
+		return -ERANGE;
+
+	case SIOCGHWTSTAMP: /* get */
+		hwts_cfg.tx_type = HWTSTAMP_TX_ON;
+		hwts_cfg.rx_filter = HWTSTAMP_FILTER_ALL;
+		if (copy_to_user(ifr->ifr_data, &hwts_cfg, sizeof(hwts_cfg)))
+			return -EFAULT;
+		return 0;
+
+	default:
+		return -EOPNOTSUPP;
+	}
+}
+EXPORT_SYMBOL(can_eth_ioctl_hwts);
+
 /* generic implementation of ethtool_ops::get_ts_info for CAN devices
  * supporting hardware timestamps
  */
diff --git a/include/linux/can/dev.h b/include/linux/can/dev.h
index 752bd45d8ebf..c3e50e537e39 100644
--- a/include/linux/can/dev.h
+++ b/include/linux/can/dev.h
@@ -163,6 +163,7 @@ struct can_priv *safe_candev_priv(struct net_device *dev);
 int open_candev(struct net_device *dev);
 void close_candev(struct net_device *dev);
 int can_change_mtu(struct net_device *dev, int new_mtu);
+int can_eth_ioctl_hwts(struct net_device *netdev, struct ifreq *ifr, int cmd);
 int can_ethtool_op_get_ts_info_hwts(struct net_device *dev,
 				    struct ethtool_ts_info *info);
 
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 92+ messages in thread

* [PATCH v2 09/14] can: mcp251xfd: advertise timestamping capabilities and add ioctl support
  2022-07-25 15:53 ` [PATCH v2 00/14] " Vincent Mailhol
                     ` (7 preceding siblings ...)
  2022-07-25 15:53   ` [PATCH v2 08/14] can: dev: add generic function can_eth_ioctl_hwts() Vincent Mailhol
@ 2022-07-25 15:53   ` Vincent Mailhol
  2022-07-25 15:53   ` [PATCH v2 10/14] can: etas_es58x: " Vincent Mailhol
                     ` (4 subsequent siblings)
  13 siblings, 0 replies; 92+ messages in thread
From: Vincent Mailhol @ 2022-07-25 15:53 UTC (permalink / raw)
  To: linux-can, Marc Kleine-Budde
  Cc: Stephane Grosjean, Jimmy Assarsson, Oliver Hartkopp,
	Dario Binacchi, Max Staudt, Vincent Mailhol

Currently, userland has no methods to query which timestamping
features are supported by the mcp251xfd driver (aside maybe of getting
RX messages and obseverse whether or not hardware timestamps stay at
zero).

The canonical way for a network driver to advertise what kind of
timestamping it supports is to implement
ethtool_ops::get_ts_info(). Here, we use the CAN specific
can_ethtool_op_get_ts_info_hwts() function to achieve this.

In addition, the driver currently does not support the hardware
timestamps ioctls. According to [1], SIOCSHWTSTAMP is "must" and
SIOCGHWTSTAMP is "should". This patch fills up that gap by
implementing net_device_ops::ndo_eth_ioctl() using the CAN specific
function can_eth_ioctl_hwts().

[1] kernel doc Timestamping, section 3.1: "Hardware Timestamping
Implementation: Device Drivers"
Link: https://docs.kernel.org/networking/timestamping.html#hardware-timestamping-implementation-device-drivers

Signed-off-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
---
 drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c b/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c
index 7fc86ed405c6..5cd2c296d1c9 100644
--- a/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c
+++ b/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c
@@ -16,6 +16,7 @@
 #include <linux/bitfield.h>
 #include <linux/clk.h>
 #include <linux/device.h>
+#include <linux/ethtool.h>
 #include <linux/mod_devicetable.h>
 #include <linux/module.h>
 #include <linux/pm_runtime.h>
@@ -1671,9 +1672,14 @@ static const struct net_device_ops mcp251xfd_netdev_ops = {
 	.ndo_open = mcp251xfd_open,
 	.ndo_stop = mcp251xfd_stop,
 	.ndo_start_xmit	= mcp251xfd_start_xmit,
+	.ndo_eth_ioctl = can_eth_ioctl_hwts,
 	.ndo_change_mtu = can_change_mtu,
 };
 
+static const struct ethtool_ops mcp251xfd_ethtool_ops = {
+	.get_ts_info = can_ethtool_op_get_ts_info_hwts,
+};
+
 static void
 mcp251xfd_register_quirks(struct mcp251xfd_priv *priv)
 {
@@ -2050,6 +2056,7 @@ static int mcp251xfd_probe(struct spi_device *spi)
 	SET_NETDEV_DEV(ndev, &spi->dev);
 
 	ndev->netdev_ops = &mcp251xfd_netdev_ops;
+	ndev->ethtool_ops = &mcp251xfd_ethtool_ops;
 	ndev->irq = spi->irq;
 	ndev->flags |= IFF_ECHO;
 
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 92+ messages in thread

* [PATCH v2 10/14] can: etas_es58x: advertise timestamping capabilities and add ioctl support
  2022-07-25 15:53 ` [PATCH v2 00/14] " Vincent Mailhol
                     ` (8 preceding siblings ...)
  2022-07-25 15:53   ` [PATCH v2 09/14] can: mcp251xfd: advertise timestamping capabilities and add ioctl support Vincent Mailhol
@ 2022-07-25 15:53   ` Vincent Mailhol
  2022-07-25 15:53   ` [PATCH v2 11/14] can: kvaser_pciefd: " Vincent Mailhol
                     ` (3 subsequent siblings)
  13 siblings, 0 replies; 92+ messages in thread
From: Vincent Mailhol @ 2022-07-25 15:53 UTC (permalink / raw)
  To: linux-can, Marc Kleine-Budde
  Cc: Stephane Grosjean, Jimmy Assarsson, Oliver Hartkopp,
	Dario Binacchi, Max Staudt, Vincent Mailhol

Currently, userland has no method to query which timestamping features
are supported by the etas_es58x driver (aside maybe of getting RX
messages and obseverse whever or not hardware timestamps stay at
zero).

The canonical way for a network driver to advertise what kind of
timestamping is supports is to implement
ethtool_ops::get_ts_info(). Here, we use the CAN specific
can_ethtool_op_get_ts_info_hwts() function to achieve this.

In addition, the driver currently does not support the hardware
timestamps ioctls. According to [1], SIOCSHWTSTAMP is "must" and
SIOCGHWTSTAMP is "should". This patch fills up that gap by
implementing net_device_ops::ndo_eth_ioctl() using the CAN specific
function can_eth_ioctl_hwts().

[1] kernel doc Timestamping, section 3.1: "Hardware Timestamping
Implementation: Device Drivers"
Link: https://docs.kernel.org/networking/timestamping.html#hardware-timestamping-implementation-device-drivers

Signed-off-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
---
 drivers/net/can/usb/etas_es58x/es58x_core.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/net/can/usb/etas_es58x/es58x_core.c b/drivers/net/can/usb/etas_es58x/es58x_core.c
index 7353745f92d7..5e2585c85500 100644
--- a/drivers/net/can/usb/etas_es58x/es58x_core.c
+++ b/drivers/net/can/usb/etas_es58x/es58x_core.c
@@ -10,6 +10,7 @@
  * Copyright (c) 2020, 2021 Vincent Mailhol <mailhol.vincent@wanadoo.fr>
  */
 
+#include <linux/ethtool.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/usb.h>
@@ -1981,7 +1982,12 @@ static netdev_tx_t es58x_start_xmit(struct sk_buff *skb,
 static const struct net_device_ops es58x_netdev_ops = {
 	.ndo_open = es58x_open,
 	.ndo_stop = es58x_stop,
-	.ndo_start_xmit = es58x_start_xmit
+	.ndo_start_xmit = es58x_start_xmit,
+	.ndo_eth_ioctl = can_eth_ioctl_hwts,
+};
+
+static const struct ethtool_ops es58x_ethtool_ops = {
+	.get_ts_info = can_ethtool_op_get_ts_info_hwts,
 };
 
 /**
@@ -2088,6 +2094,7 @@ static int es58x_init_netdev(struct es58x_device *es58x_dev, int channel_idx)
 	es58x_init_priv(es58x_dev, es58x_priv(netdev), channel_idx);
 
 	netdev->netdev_ops = &es58x_netdev_ops;
+	netdev->ethtool_ops = &es58x_ethtool_ops;
 	netdev->flags |= IFF_ECHO;	/* We support local echo */
 	netdev->dev_port = channel_idx;
 
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 92+ messages in thread

* [PATCH v2 11/14] can: kvaser_pciefd: advertise timestamping capabilities and add ioctl support
  2022-07-25 15:53 ` [PATCH v2 00/14] " Vincent Mailhol
                     ` (9 preceding siblings ...)
  2022-07-25 15:53   ` [PATCH v2 10/14] can: etas_es58x: " Vincent Mailhol
@ 2022-07-25 15:53   ` Vincent Mailhol
  2022-07-25 15:53   ` [PATCH v2 12/14] can: kvaser_usb: " Vincent Mailhol
                     ` (2 subsequent siblings)
  13 siblings, 0 replies; 92+ messages in thread
From: Vincent Mailhol @ 2022-07-25 15:53 UTC (permalink / raw)
  To: linux-can, Marc Kleine-Budde
  Cc: Stephane Grosjean, Jimmy Assarsson, Oliver Hartkopp,
	Dario Binacchi, Max Staudt, Vincent Mailhol

Currently, userland has no method to query which timestamping features
are supported by the kvaser_pciefd driver (aside maybe of getting RX
messages and obseverse whever or not hardware timestamps stay at
zero).

The canonical way for a network driver to advertise what kind of
timestamping it supports is to implement
ethtool_ops::get_ts_info(). Here, we use the CAN specific
can_ethtool_op_get_ts_info_hwts() function to achieve this.

In addition, the driver currently does not support the hardware
timestamps ioctls. According to [1], SIOCSHWTSTAMP is "must" and
SIOCGHWTSTAMP is "should". This patch fills up that gap by
implementing net_device_ops::ndo_eth_ioctl() using the CAN specific
function can_eth_ioctl_hwts().

[1] kernel doc Timestamping, section 3.1: "Hardware Timestamping
Implementation: Device Drivers"
Link: https://docs.kernel.org/networking/timestamping.html#hardware-timestamping-implementation-device-drivers

CC: Jimmy Assarsson <extja@kvaser.com>
Signed-off-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
---
 drivers/net/can/kvaser_pciefd.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/drivers/net/can/kvaser_pciefd.c b/drivers/net/can/kvaser_pciefd.c
index dcd2c9d50d5e..ed54c0b3c7d4 100644
--- a/drivers/net/can/kvaser_pciefd.c
+++ b/drivers/net/can/kvaser_pciefd.c
@@ -9,6 +9,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/device.h>
+#include <linux/ethtool.h>
 #include <linux/pci.h>
 #include <linux/can/dev.h>
 #include <linux/timer.h>
@@ -919,10 +920,15 @@ static void kvaser_pciefd_bec_poll_timer(struct timer_list *data)
 static const struct net_device_ops kvaser_pciefd_netdev_ops = {
 	.ndo_open = kvaser_pciefd_open,
 	.ndo_stop = kvaser_pciefd_stop,
+	.ndo_eth_ioctl = can_eth_ioctl_hwts,
 	.ndo_start_xmit = kvaser_pciefd_start_xmit,
 	.ndo_change_mtu = can_change_mtu,
 };
 
+static const struct ethtool_ops kvaser_pciefd_ethtool_ops = {
+	.get_ts_info = can_ethtool_op_get_ts_info_hwts,
+};
+
 static int kvaser_pciefd_setup_can_ctrls(struct kvaser_pciefd *pcie)
 {
 	int i;
@@ -939,6 +945,7 @@ static int kvaser_pciefd_setup_can_ctrls(struct kvaser_pciefd *pcie)
 
 		can = netdev_priv(netdev);
 		netdev->netdev_ops = &kvaser_pciefd_netdev_ops;
+		netdev->ethtool_ops = &kvaser_pciefd_ethtool_ops;
 		can->reg_base = pcie->reg_base + KVASER_PCIEFD_KCAN0_BASE +
 				i * KVASER_PCIEFD_KCAN_BASE_OFFSET;
 
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 92+ messages in thread

* [PATCH v2 12/14] can: kvaser_usb: advertise timestamping capabilities and add ioctl support
  2022-07-25 15:53 ` [PATCH v2 00/14] " Vincent Mailhol
                     ` (10 preceding siblings ...)
  2022-07-25 15:53   ` [PATCH v2 11/14] can: kvaser_pciefd: " Vincent Mailhol
@ 2022-07-25 15:53   ` Vincent Mailhol
  2022-07-25 15:53   ` [PATCH v2 13/14] can: peak_canfd: " Vincent Mailhol
  2022-07-25 15:53   ` [PATCH v2 14/14] can: peak_usb: " Vincent Mailhol
  13 siblings, 0 replies; 92+ messages in thread
From: Vincent Mailhol @ 2022-07-25 15:53 UTC (permalink / raw)
  To: linux-can, Marc Kleine-Budde
  Cc: Stephane Grosjean, Jimmy Assarsson, Oliver Hartkopp,
	Dario Binacchi, Max Staudt, Vincent Mailhol

Currently, userland has no method to query which timestamping features
are supported by the kvaser_usb driver (aside maybe of getting RX
messages and obseverse whever or not hardware timestamps stay at
zero).

The canonical way for a network driver to advertise what kind of
timestamping it supports is to implement
ethtool_ops::get_ts_info(). Here, we use the CAN specific
can_ethtool_op_get_ts_info_hwts() function to achieve this.

In addition, the driver currently does not support the hardware
timestamps ioctls. According to [1], SIOCSHWTSTAMP is "must" and
SIOCGHWTSTAMP is "should". This patch fills up that gap by
implementing net_device_ops::ndo_eth_ioctl() using the CAN specific
function can_eth_ioctl_hwts().

[1] kernel doc Timestamping, section 3.1: "Hardware Timestamping
Implementation: Device Drivers"
Link: https://docs.kernel.org/networking/timestamping.html#hardware-timestamping-implementation-device-drivers

CC: Jimmy Assarsson <extja@kvaser.com>
Signed-off-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
---

Hi Jimmy, as far as I understand, only the hydra has the hardware
timestamping. If not the case, let me know.

This is not tested. If you find any issue or if you want to modify,
feel free to pick up that patch and resend it.
---
 drivers/net/can/usb/kvaser_usb/kvaser_usb.h   |  1 +
 .../net/can/usb/kvaser_usb/kvaser_usb_core.c  | 27 +++++++++++++++++--
 2 files changed, 26 insertions(+), 2 deletions(-)

diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb.h b/drivers/net/can/usb/kvaser_usb/kvaser_usb.h
index eefcbe3aadce..841da29cef93 100644
--- a/drivers/net/can/usb/kvaser_usb/kvaser_usb.h
+++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb.h
@@ -39,6 +39,7 @@
 #define KVASER_USB_QUIRK_HAS_SILENT_MODE	BIT(0)
 #define KVASER_USB_QUIRK_HAS_TXRX_ERRORS	BIT(1)
 #define KVASER_USB_QUIRK_IGNORE_CLK_FREQ	BIT(2)
+#define KVASER_USB_QUIRK_HAS_HARDWARE_TIMESTAMP	BIT(3)
 
 /* Device capabilities */
 #define KVASER_USB_CAP_BERR_CAP			0x01
diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c b/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c
index f211bfcb1d97..5e357f5d3116 100644
--- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c
+++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c
@@ -13,6 +13,7 @@
 
 #include <linux/completion.h>
 #include <linux/device.h>
+#include <linux/ethtool.h>
 #include <linux/gfp.h>
 #include <linux/if.h>
 #include <linux/kernel.h>
@@ -89,7 +90,7 @@
 #define USB_HYBRID_PRO_CANLIN_PRODUCT_ID	278
 
 static const struct kvaser_usb_driver_info kvaser_usb_driver_info_hydra = {
-	.quirks = 0,
+	.quirks = KVASER_USB_QUIRK_HAS_HARDWARE_TIMESTAMP,
 	.ops = &kvaser_usb_hydra_dev_ops,
 };
 
@@ -665,6 +666,22 @@ static const struct net_device_ops kvaser_usb_netdev_ops = {
 	.ndo_change_mtu = can_change_mtu,
 };
 
+static const struct net_device_ops kvaser_usb_netdev_ops_hwts = {
+	.ndo_open = kvaser_usb_open,
+	.ndo_stop = kvaser_usb_close,
+	.ndo_eth_ioctl = can_eth_ioctl_hwts,
+	.ndo_start_xmit = kvaser_usb_start_xmit,
+	.ndo_change_mtu = can_change_mtu,
+};
+
+static const struct ethtool_ops kvaser_usb_ethtool_ops = {
+	.get_ts_info = ethtool_op_get_ts_info,
+};
+
+static const struct ethtool_ops kvaser_usb_ethtool_ops_hwts = {
+	.get_ts_info = can_ethtool_op_get_ts_info_hwts,
+};
+
 static void kvaser_usb_remove_interfaces(struct kvaser_usb *dev)
 {
 	int i;
@@ -742,7 +759,13 @@ static int kvaser_usb_init_one(struct kvaser_usb *dev, int channel)
 	netdev->flags |= IFF_ECHO;
 
 	netdev->netdev_ops = &kvaser_usb_netdev_ops;
-
+	if (driver_info->quirks & KVASER_USB_QUIRK_HAS_HARDWARE_TIMESTAMP) {
+		netdev->netdev_ops = &kvaser_usb_netdev_ops_hwts;
+		netdev->ethtool_ops = &kvaser_usb_ethtool_ops_hwts;
+	} else {
+		netdev->netdev_ops = &kvaser_usb_netdev_ops;
+		netdev->ethtool_ops = &kvaser_usb_ethtool_ops;
+	}
 	SET_NETDEV_DEV(netdev, &dev->intf->dev);
 	netdev->dev_id = channel;
 
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 92+ messages in thread

* [PATCH v2 13/14] can: peak_canfd: advertise timestamping capabilities and add ioctl support
  2022-07-25 15:53 ` [PATCH v2 00/14] " Vincent Mailhol
                     ` (11 preceding siblings ...)
  2022-07-25 15:53   ` [PATCH v2 12/14] can: kvaser_usb: " Vincent Mailhol
@ 2022-07-25 15:53   ` Vincent Mailhol
  2022-07-25 15:53   ` [PATCH v2 14/14] can: peak_usb: " Vincent Mailhol
  13 siblings, 0 replies; 92+ messages in thread
From: Vincent Mailhol @ 2022-07-25 15:53 UTC (permalink / raw)
  To: linux-can, Marc Kleine-Budde
  Cc: Stephane Grosjean, Jimmy Assarsson, Oliver Hartkopp,
	Dario Binacchi, Max Staudt, Vincent Mailhol

Currently, userland has no method to query which timestamping features
are supported by the peak_canfd driver (aside maybe of getting RX
messages and obseverse whever or not hardware timestamps stay at
zero).

The canonical way for a network driver to advertise what kind of
timestamping it supports is to implement
ethtool_ops::get_ts_info(). Here, we use the CAN specific
can_ethtool_op_get_ts_info_hwts() function to achieve this.

In addition, the driver currently does not support the hardware
timestamps ioctls. According to [1], SIOCSHWTSTAMP is "must" and
SIOCGHWTSTAMP is "should". This patch fills up that gap by
implementing net_device_ops::ndo_eth_ioctl() using the CAN specific
function can_eth_ioctl_hwts().

[1] kernel doc Timestamping, section 3.1: "Hardware Timestamping
Implementation: Device Drivers"
Link: https://docs.kernel.org/networking/timestamping.html#hardware-timestamping-implementation-device-drivers

CC: Stephane Grosjean <s.grosjean@peak-system.com>
Signed-off-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
---
 drivers/net/can/peak_canfd/peak_canfd.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/drivers/net/can/peak_canfd/peak_canfd.c b/drivers/net/can/peak_canfd/peak_canfd.c
index afb9adb3d5c2..634e24d99ac6 100644
--- a/drivers/net/can/peak_canfd/peak_canfd.c
+++ b/drivers/net/can/peak_canfd/peak_canfd.c
@@ -7,6 +7,7 @@
 
 #include <linux/can.h>
 #include <linux/can/dev.h>
+#include <linux/ethtool.h>
 
 #include "peak_canfd_user.h"
 
@@ -745,10 +746,15 @@ static netdev_tx_t peak_canfd_start_xmit(struct sk_buff *skb,
 static const struct net_device_ops peak_canfd_netdev_ops = {
 	.ndo_open = peak_canfd_open,
 	.ndo_stop = peak_canfd_close,
+	.ndo_eth_ioctl = can_eth_ioctl_hwts,
 	.ndo_start_xmit = peak_canfd_start_xmit,
 	.ndo_change_mtu = can_change_mtu,
 };
 
+static const struct ethtool_ops peak_canfd_ethtool_ops = {
+	.get_ts_info = can_ethtool_op_get_ts_info_hwts,
+};
+
 struct net_device *alloc_peak_canfd_dev(int sizeof_priv, int index,
 					int echo_skb_max)
 {
@@ -789,6 +795,7 @@ struct net_device *alloc_peak_canfd_dev(int sizeof_priv, int index,
 
 	ndev->flags |= IFF_ECHO;
 	ndev->netdev_ops = &peak_canfd_netdev_ops;
+	ndev->ethtool_ops = &peak_canfd_ethtool_ops;
 	ndev->dev_id = index;
 
 	return ndev;
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 92+ messages in thread

* [PATCH v2 14/14] can: peak_usb: advertise timestamping capabilities and add ioctl support
  2022-07-25 15:53 ` [PATCH v2 00/14] " Vincent Mailhol
                     ` (12 preceding siblings ...)
  2022-07-25 15:53   ` [PATCH v2 13/14] can: peak_canfd: " Vincent Mailhol
@ 2022-07-25 15:53   ` Vincent Mailhol
  13 siblings, 0 replies; 92+ messages in thread
From: Vincent Mailhol @ 2022-07-25 15:53 UTC (permalink / raw)
  To: linux-can, Marc Kleine-Budde
  Cc: Stephane Grosjean, Jimmy Assarsson, Oliver Hartkopp,
	Dario Binacchi, Max Staudt, Vincent Mailhol

Currently, userland has no method to query which timestamping features
are supported by the peak_usb driver (aside maybe of getting RX
messages and obseverse whever or not hardware timestamps stay at
zero).

The canonical way for a network driver to advertise what kind of
timestamping it supports is to implement
ethtool_ops::get_ts_info(). Here, we use the CAN specific
can_ethtool_op_get_ts_info_hwts() function to achieve this.

In addition, the driver currently does not support the hardware
timestamps ioctls. According to [1], SIOCSHWTSTAMP is "must" and
SIOCGHWTSTAMP is "should". This patch fills up that gap by
implementing net_device_ops::ndo_eth_ioctl() using the CAN specific
function can_eth_ioctl_hwts().

[1] kernel doc Timestamping, section 3.1: "Hardware Timestamping
Implementation: Device Drivers"
Link: https://docs.kernel.org/networking/timestamping.html#hardware-timestamping-implementation-device-drivers

CC: Stephane Grosjean <s.grosjean@peak-system.com>
Signed-off-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
---

Hi Stéphane, as far as I understand, the pcan_usb and the pacn_usb_pro
support hardware timestamps but the pcan_usb_fd doesn't. If not the
case, let me know.

This is not tested. If you find any issue or if you want to modify,
feel free to pick up that patch and resend it.
---
 drivers/net/can/usb/peak_usb/pcan_usb.c      |  2 ++
 drivers/net/can/usb/peak_usb/pcan_usb_core.c | 12 ++++++++++--
 drivers/net/can/usb/peak_usb/pcan_usb_core.h |  4 ++++
 drivers/net/can/usb/peak_usb/pcan_usb_fd.c   |  2 ++
 drivers/net/can/usb/peak_usb/pcan_usb_pro.c  |  2 ++
 5 files changed, 20 insertions(+), 2 deletions(-)

diff --git a/drivers/net/can/usb/peak_usb/pcan_usb.c b/drivers/net/can/usb/peak_usb/pcan_usb.c
index d07b7ee79e3e..23966d5d7825 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb.c
+++ b/drivers/net/can/usb/peak_usb/pcan_usb.c
@@ -965,6 +965,7 @@ static int pcan_usb_set_phys_id(struct net_device *netdev,
 
 static const struct ethtool_ops pcan_usb_ethtool_ops = {
 	.set_phys_id = pcan_usb_set_phys_id,
+	.get_ts_info = can_ethtool_op_get_ts_info_hwts,
 };
 
 /*
@@ -996,6 +997,7 @@ const struct peak_usb_adapter pcan_usb = {
 	/* size of device private data */
 	.sizeof_dev_private = sizeof(struct pcan_usb),
 
+	.netdev_ops = &pcan_usb_netdev_ops,
 	.ethtool_ops = &pcan_usb_ethtool_ops,
 
 	/* timestamps usage */
diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_core.c b/drivers/net/can/usb/peak_usb/pcan_usb_core.c
index 27b0a72fd885..88d0505d3f8d 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb_core.c
+++ b/drivers/net/can/usb/peak_usb/pcan_usb_core.c
@@ -775,13 +775,21 @@ static int peak_usb_set_data_bittiming(struct net_device *netdev)
 	return 0;
 }
 
-static const struct net_device_ops peak_usb_netdev_ops = {
+const struct net_device_ops pcan_usb_netdev_ops = {
 	.ndo_open = peak_usb_ndo_open,
 	.ndo_stop = peak_usb_ndo_stop,
 	.ndo_start_xmit = peak_usb_ndo_start_xmit,
 	.ndo_change_mtu = can_change_mtu,
 };
 
+const struct net_device_ops pcan_usb_netdev_ops_hwts = {
+	.ndo_open = peak_usb_ndo_open,
+	.ndo_stop = peak_usb_ndo_stop,
+	.ndo_eth_ioctl = can_eth_ioctl_hwts,
+	.ndo_start_xmit = peak_usb_ndo_start_xmit,
+	.ndo_change_mtu = can_change_mtu,
+};
+
 /*
  * create one device which is attached to CAN controller #ctrl_idx of the
  * usb adapter.
@@ -833,7 +841,7 @@ static int peak_usb_create_dev(const struct peak_usb_adapter *peak_usb_adapter,
 	dev->can.do_get_berr_counter = peak_usb_adapter->do_get_berr_counter;
 	dev->can.ctrlmode_supported = peak_usb_adapter->ctrlmode_supported;
 
-	netdev->netdev_ops = &peak_usb_netdev_ops;
+	netdev->netdev_ops = peak_usb_adapter->netdev_ops;
 
 	netdev->flags |= IFF_ECHO; /* we support local echo */
 
diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_core.h b/drivers/net/can/usb/peak_usb/pcan_usb_core.h
index 9c90487b9c92..a7412235d36f 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb_core.h
+++ b/drivers/net/can/usb/peak_usb/pcan_usb_core.h
@@ -46,6 +46,7 @@ struct peak_usb_adapter {
 	const struct can_bittiming_const * const data_bittiming_const;
 	unsigned int ctrl_count;
 
+	const struct net_device_ops *netdev_ops;
 	const struct ethtool_ops *ethtool_ops;
 
 	int (*intf_probe)(struct usb_interface *intf);
@@ -88,6 +89,9 @@ extern const struct peak_usb_adapter pcan_usb_chip;
 extern const struct peak_usb_adapter pcan_usb_pro_fd;
 extern const struct peak_usb_adapter pcan_usb_x6;
 
+extern const struct net_device_ops pcan_usb_netdev_ops;
+extern const struct net_device_ops pcan_usb_netdev_ops_hwts;
+
 struct peak_time_ref {
 	ktime_t tv_host_0, tv_host;
 	u32 ts_dev_1, ts_dev_2;
diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_fd.c b/drivers/net/can/usb/peak_usb/pcan_usb_fd.c
index 3d7e0e370505..8560f82b0ab2 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb_fd.c
+++ b/drivers/net/can/usb/peak_usb/pcan_usb_fd.c
@@ -1080,6 +1080,7 @@ static int pcan_usb_fd_set_phys_id(struct net_device *netdev,
 
 static const struct ethtool_ops pcan_usb_fd_ethtool_ops = {
 	.set_phys_id = pcan_usb_fd_set_phys_id,
+	.get_ts_info = ethtool_op_get_ts_info,
 };
 
 /* describes the PCAN-USB FD adapter */
@@ -1123,6 +1124,7 @@ const struct peak_usb_adapter pcan_usb_fd = {
 	/* size of device private data */
 	.sizeof_dev_private = sizeof(struct pcan_usb_fd_device),
 
+	.netdev_ops = &pcan_usb_netdev_ops_hwts,
 	.ethtool_ops = &pcan_usb_fd_ethtool_ops,
 
 	/* timestamps usage */
diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_pro.c b/drivers/net/can/usb/peak_usb/pcan_usb_pro.c
index 457887113e75..13b2d82047c7 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb_pro.c
+++ b/drivers/net/can/usb/peak_usb/pcan_usb_pro.c
@@ -1022,6 +1022,7 @@ static int pcan_usb_pro_set_phys_id(struct net_device *netdev,
 
 static const struct ethtool_ops pcan_usb_pro_ethtool_ops = {
 	.set_phys_id = pcan_usb_pro_set_phys_id,
+	.get_ts_info = can_ethtool_op_get_ts_info_hwts,
 };
 
 /*
@@ -1053,6 +1054,7 @@ const struct peak_usb_adapter pcan_usb_pro = {
 	/* size of device private data */
 	.sizeof_dev_private = sizeof(struct pcan_usb_pro_device),
 
+	.netdev_ops = &pcan_usb_netdev_ops_hwts,
 	.ethtool_ops = &pcan_usb_pro_ethtool_ops,
 
 	/* timestamps usage */
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 92+ messages in thread

* Re: [PATCH v1 18/24] can: dev: add generic function can_eth_ioctl_hwts()
  2022-07-25 14:41     ` Vincent MAILHOL
@ 2022-07-25 16:19       ` Marc Kleine-Budde
  0 siblings, 0 replies; 92+ messages in thread
From: Marc Kleine-Budde @ 2022-07-25 16:19 UTC (permalink / raw)
  To: Vincent MAILHOL
  Cc: linux-can, Stephane Grosjean, Jimmy Assarsson, Oliver Hartkopp,
	Dario Binacchi, Max Staudt

[-- Attachment #1: Type: text/plain, Size: 4066 bytes --]

On 25.07.2022 23:41:17, Vincent MAILHOL wrote:
> On Mon. 25 juil. 2022 at 23:31, Marc Kleine-Budde <mkl@pengutronix.de> wrote:
> > On 25.07.2022 22:32:02, Vincent Mailhol wrote:
> > > Tools based on libpcap (such as tcpdump) expect the SIOCSHWTSTAMP
> > > ioctl call to be supported. This is also specified in the kernel doc
> > > [1]. The purpose of this ioctl is to toggle the hardware timestamps.
> > >
> > > Currently, CAN devices which support hardware timestamping have those
> > > always activated. can_eth_ioctl_hwts() is a dumb function that will
> > > always succeed when requested to set tx_type to HWTSTAMP_TX_ON or
> > > rx_filter to HWTSTAMP_FILTER_ALL.
> > >
> > > [1] Kernel doc: Timestamping, section 3.1 "Hardware Timestamping
> > > Implementation: Device Drivers"
> > > Link: https://docs.kernel.org/networking/timestamping.html#hardware-timestamping-implementation-device-drivers
> > >
> > > Signed-off-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
> > > ---
> > >  drivers/net/can/dev/dev.c | 29 +++++++++++++++++++++++++++++
> > >  include/linux/can/dev.h   |  1 +
> > >  2 files changed, 30 insertions(+)
> > >
> > > diff --git a/drivers/net/can/dev/dev.c b/drivers/net/can/dev/dev.c
> > > index 7ad56d31cec9..750dc7cae9d4 100644
> > > --- a/drivers/net/can/dev/dev.c
> > > +++ b/drivers/net/can/dev/dev.c
> > > @@ -322,6 +322,35 @@ int can_change_mtu(struct net_device *dev, int new_mtu)
> > >  }
> > >  EXPORT_SYMBOL_GPL(can_change_mtu);
> > >
> > > +/* generic implementation of netdev_ops::ndo_eth_ioctl for CAN devices
> > > + * supporting hardware RX timestamps
> > > + */
> > > +int can_eth_ioctl_hwts(struct net_device *netdev, struct ifreq *ifr, int cmd)
> > > +{
> > > +     struct hwtstamp_config hwts_cfg = { 0 };
> > > +
> > > +     switch (cmd) {
> > > +     case SIOCSHWTSTAMP: /* set */
> > > +             if (copy_from_user(&hwts_cfg, ifr->ifr_data, sizeof(hwts_cfg)))
> > > +                     return -EFAULT;
> > > +             if (hwts_cfg.tx_type == HWTSTAMP_TX_ON &&
> > > +                 hwts_cfg.rx_filter == HWTSTAMP_FILTER_ALL)
> > > +                     return 0;
> >
> > I have a WIP hwts patch series for the mcp251xfd. IIRC the driver is
> > allowed to add RX timestamps to more packages than requested without
> > failing, so the relevant code my WIP patches looks like this:
> >
> > +       switch (config.tx_type) {
> > +       case HWTSTAMP_TX_OFF:
> > +               break;
> > +       default:
> > +               return -ERANGE;
> > +       }
> > +
> > +       switch (config.rx_filter) {
> > +       case HWTSTAMP_FILTER_NONE:
> > +               clear_bit(MCP251XFD_FLAGS_TIMESTAMP_RX, priv->flags);
> > +               break;
> > +       default:
> > +               set_bit(MCP251XFD_FLAGS_TIMESTAMP_RX, priv->flags);
> > +               config.rx_filter = HWTSTAMP_FILTER_ALL;
> > +       }
> 
> What is the default value for rx_filter?

Currently switched off.

> Currently, candump -H
> implicitly expects rx_filter to be HWTSTAMP_FILTER_ALL. Defaulting to
> HWTSTAMP_FILTER_NONE would break the current versions of candump.

My series is still WIP, haven't thought that far. I was falling down the
rabbit hole due 2 mcp251xfd "specialties" with regards to reading the
time stamp counter register.

> so I
> was wondering if it would be better for CAN to start with hardware
> timestamps as active (in my series, I assume that HWTSTAMP_FILTER_NONE
> is not supported and thus avoid this problem).

There's hwstamp_ctl to configure time stamping, but that's part of
linuxptp.

> Moving forward, should I keep mcp251xfd in this series or should I
> remove it and let you take care of it?

Keep the patch, I'll adopt mine.

Marc

-- 
Pengutronix e.K.                 | Marc Kleine-Budde           |
Embedded Linux                   | https://www.pengutronix.de  |
Vertretung West/Dortmund         | Phone: +49-231-2826-924     |
Amtsgericht Hildesheim, HRA 2686 | Fax:   +49-5121-206917-5555 |

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 92+ messages in thread

* Re: [PATCH v1 10/24] can: tree-wide: implement ethtool_ops::get_drvinfo()
  2022-07-25 13:31 ` [PATCH v1 10/24] can: tree-wide: implement ethtool_ops::get_drvinfo() Vincent Mailhol
  2022-07-25 14:09   ` Marc Kleine-Budde
@ 2022-07-26  7:29   ` Dario Binacchi
  2022-07-26  8:42     ` Vincent MAILHOL
  1 sibling, 1 reply; 92+ messages in thread
From: Dario Binacchi @ 2022-07-26  7:29 UTC (permalink / raw)
  To: Vincent Mailhol
  Cc: linux-can, Marc Kleine-Budde, Stephane Grosjean, Jimmy Assarsson,
	Oliver Hartkopp, Max Staudt

Hi Vincent,

On Mon, Jul 25, 2022 at 3:32 PM Vincent Mailhol
<mailhol.vincent@wanadoo.fr> wrote:
>
> For all CAN drivers, implement the get_drvinfo() function.
>
> After this patch, it is now possible to retrieve basic information by
> doing:
>
> | $ ethtool -i canX
>
> Signed-off-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
> ---
>  drivers/net/can/at91_can.c                       | 12 ++++++++++++
>  drivers/net/can/c_can/c_can_main.c               | 12 ++++++++++++
>  drivers/net/can/can327.c                         | 11 +++++++++++
>  drivers/net/can/cc770/cc770.c                    | 12 ++++++++++++
>  drivers/net/can/ctucanfd/ctucanfd_base.c         | 12 ++++++++++++
>  drivers/net/can/flexcan/flexcan-core.c           | 12 ++++++++++++
>  drivers/net/can/grcan.c                          | 12 ++++++++++++
>  drivers/net/can/ifi_canfd/ifi_canfd.c            | 12 ++++++++++++
>  drivers/net/can/janz-ican3.c                     | 12 ++++++++++++
>  drivers/net/can/kvaser_pciefd.c                  | 12 ++++++++++++
>  drivers/net/can/m_can/m_can.c                    | 12 ++++++++++++
>  drivers/net/can/mscan/mscan.c                    |  1 +
>  drivers/net/can/pch_can.c                        | 12 ++++++++++++
>  drivers/net/can/peak_canfd/peak_canfd.c          | 12 ++++++++++++
>  drivers/net/can/rcar/rcar_can.c                  | 12 ++++++++++++
>  drivers/net/can/rcar/rcar_canfd.c                | 12 ++++++++++++
>  drivers/net/can/sja1000/sja1000.c                | 12 ++++++++++++
>  drivers/net/can/slcan/slcan-core.c               | 12 ++++++++++++
>  drivers/net/can/softing/softing_main.c           | 12 ++++++++++++
>  drivers/net/can/spi/hi311x.c                     | 12 ++++++++++++
>  drivers/net/can/spi/mcp251x.c                    | 12 ++++++++++++
>  drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c   | 12 ++++++++++++
>  drivers/net/can/sun4i_can.c                      | 12 ++++++++++++
>  drivers/net/can/ti_hecc.c                        | 12 ++++++++++++
>  drivers/net/can/usb/ems_usb.c                    | 12 ++++++++++++
>  drivers/net/can/usb/esd_usb.c                    | 12 ++++++++++++
>  drivers/net/can/usb/etas_es58x/es58x_core.c      | 12 ++++++++++++
>  drivers/net/can/usb/gs_usb.c                     |  8 ++++++++
>  drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c | 12 ++++++++++++
>  drivers/net/can/usb/mcba_usb.c                   | 12 ++++++++++++
>  drivers/net/can/usb/peak_usb/pcan_usb_core.c     |  6 ++++++
>  drivers/net/can/usb/peak_usb/pcan_usb_core.h     |  2 ++
>  drivers/net/can/usb/peak_usb/pcan_usb_fd.c       |  1 +
>  drivers/net/can/usb/peak_usb/pcan_usb_pro.c      |  1 +
>  drivers/net/can/usb/ucan.c                       | 12 ++++++++++++
>  drivers/net/can/usb/usb_8dev.c                   | 12 ++++++++++++
>  drivers/net/can/vcan.c                           | 12 ++++++++++++
>  drivers/net/can/vxcan.c                          | 12 ++++++++++++
>  drivers/net/can/xilinx_can.c                     | 12 ++++++++++++
>  39 files changed, 414 insertions(+)
>
> diff --git a/drivers/net/can/at91_can.c b/drivers/net/can/at91_can.c
> index 29ed0d3cd171..637d2ca34d08 100644
> --- a/drivers/net/can/at91_can.c
> +++ b/drivers/net/can/at91_can.c
> @@ -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>
> @@ -1152,6 +1153,16 @@ static const struct net_device_ops at91_netdev_ops = {
>         .ndo_change_mtu = can_change_mtu,
>  };
>
> +static void at91_get_drvinfo(struct net_device *netdev,
> +                            struct ethtool_drvinfo *drvinfo)
> +{
> +       strscpy(drvinfo->driver, KBUILD_MODNAME, sizeof(drvinfo->driver));
> +}
> +
> +static const struct ethtool_ops at91_ethtool_ops = {
> +       .get_drvinfo = at91_get_drvinfo,
> +};
> +
>  static ssize_t mb0_id_show(struct device *dev,
>                            struct device_attribute *attr, char *buf)
>  {
> @@ -1293,6 +1304,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;
>
> diff --git a/drivers/net/can/c_can/c_can_main.c b/drivers/net/can/c_can/c_can_main.c
> index de38d8f7b5f7..fa541a7cb9c1 100644
> --- a/drivers/net/can/c_can/c_can_main.c
> +++ b/drivers/net/can/c_can/c_can_main.c
> @@ -29,6 +29,7 @@
>  #include <linux/module.h>
>  #include <linux/interrupt.h>
>  #include <linux/delay.h>
> +#include <linux/ethtool.h>
>  #include <linux/netdevice.h>
>  #include <linux/if_arp.h>
>  #include <linux/if_ether.h>
> @@ -1353,6 +1354,16 @@ static const struct net_device_ops c_can_netdev_ops = {
>         .ndo_change_mtu = can_change_mtu,
>  };
>
> +static void c_can_get_drvinfo(struct net_device *netdev,
> +                             struct ethtool_drvinfo *drvinfo)
> +{
> +       strscpy(drvinfo->driver, KBUILD_MODNAME, sizeof(drvinfo->driver));
> +}
> +
> +static const struct ethtool_ops c_can_ethtool_ops = {
> +       .get_drvinfo = c_can_get_drvinfo,
> +};
> +
>  int register_c_can_dev(struct net_device *dev)
>  {
>         /* Deactivate pins to prevent DRA7 DCAN IP from being
> @@ -1364,6 +1375,7 @@ int register_c_can_dev(struct net_device *dev)
>
>         dev->flags |= IFF_ECHO; /* we support local echo */
>         dev->netdev_ops = &c_can_netdev_ops;
> +       dev->ethtool_ops = &c_can_ethtool_ops;
>         c_can_set_ethtool_ops(dev);
>
>         return register_candev(dev);
> diff --git a/drivers/net/can/can327.c b/drivers/net/can/can327.c
> index bf0cce2dbb40..03c9e8c6990d 100644
> --- a/drivers/net/can/can327.c
> +++ b/drivers/net/can/can327.c
> @@ -848,6 +848,16 @@ static const struct net_device_ops can327_netdev_ops = {
>         .ndo_change_mtu = can_change_mtu,
>  };
>
> +static void can327_get_drvinfo(struct net_device *netdev,
> +                              struct ethtool_drvinfo *drvinfo)
> +{
> +       strscpy(drvinfo->driver, KBUILD_MODNAME, sizeof(drvinfo->driver));
> +}
> +
> +static const struct ethtool_ops can327_ethtool_ops = {
> +       .get_drvinfo = can327_get_drvinfo,
> +};
> +
>  static bool can327_is_valid_rx_char(u8 c)
>  {
>         static const bool lut_char_is_valid['z'] = {
> @@ -1032,6 +1042,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;
> diff --git a/drivers/net/can/cc770/cc770.c b/drivers/net/can/cc770/cc770.c
> index 797a954bb1a0..1bb30e69cb24 100644
> --- a/drivers/net/can/cc770/cc770.c
> +++ b/drivers/net/can/cc770/cc770.c
> @@ -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>
> @@ -836,6 +837,16 @@ static const struct net_device_ops cc770_netdev_ops = {
>         .ndo_change_mtu = can_change_mtu,
>  };
>
> +static void cc770_get_drvinfo(struct net_device *netdev,
> +                             struct ethtool_drvinfo *drvinfo)
> +{
> +       strscpy(drvinfo->driver, KBUILD_MODNAME, sizeof(drvinfo->driver));
> +}
> +
> +static const struct ethtool_ops cc770_ethtool_ops = {
> +       .get_drvinfo = cc770_get_drvinfo,
> +};
> +
>  int register_cc770dev(struct net_device *dev)
>  {
>         struct cc770_priv *priv = netdev_priv(dev);
> @@ -846,6 +857,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 */
>
> diff --git a/drivers/net/can/ctucanfd/ctucanfd_base.c b/drivers/net/can/ctucanfd/ctucanfd_base.c
> index 6b281f6eb9b4..fd5fd17c16f2 100644
> --- a/drivers/net/can/ctucanfd/ctucanfd_base.c
> +++ b/drivers/net/can/ctucanfd/ctucanfd_base.c
> @@ -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>
> @@ -1301,6 +1302,16 @@ static const struct net_device_ops ctucan_netdev_ops = {
>         .ndo_change_mtu = can_change_mtu,
>  };
>
> +static void ctucan_get_drvinfo(struct net_device *netdev,
> +                              struct ethtool_drvinfo *drvinfo)
> +{
> +       strscpy(drvinfo->driver, KBUILD_MODNAME, sizeof(drvinfo->driver));
> +}
> +
> +static const struct ethtool_ops ctucan_ethtool_ops = {
> +       .get_drvinfo = ctucan_get_drvinfo,
> +};
> +
>  int ctucan_suspend(struct device *dev)
>  {
>         struct net_device *ndev = dev_get_drvdata(dev);
> @@ -1377,6 +1388,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) {
> diff --git a/drivers/net/can/flexcan/flexcan-core.c b/drivers/net/can/flexcan/flexcan-core.c
> index d060088047f1..61e3483802c6 100644
> --- a/drivers/net/can/flexcan/flexcan-core.c
> +++ b/drivers/net/can/flexcan/flexcan-core.c
> @@ -16,6 +16,7 @@
>  #include <linux/can/error.h>
>  #include <linux/clk.h>
>  #include <linux/delay.h>
> +#include <linux/ethtool.h>
>  #include <linux/firmware/imx/sci.h>
>  #include <linux/interrupt.h>
>  #include <linux/io.h>
> @@ -1813,6 +1814,16 @@ static const struct net_device_ops flexcan_netdev_ops = {
>         .ndo_change_mtu = can_change_mtu,
>  };
>
> +static void flexcan_get_drvinfo(struct net_device *netdev,
> +                               struct ethtool_drvinfo *drvinfo)
> +{
> +       strscpy(drvinfo->driver, DRV_NAME, sizeof(drvinfo->driver));
> +}
> +
> +static const struct ethtool_ops flexcan_ethtool_ops = {
> +       .get_drvinfo = flexcan_get_drvinfo,
> +};
> +
>  static int register_flexcandev(struct net_device *dev)
>  {
>         struct flexcan_priv *priv = netdev_priv(dev);
> @@ -2113,6 +2124,7 @@ static int flexcan_probe(struct platform_device *pdev)
>         SET_NETDEV_DEV(dev, &pdev->dev);
>
>         dev->netdev_ops = &flexcan_netdev_ops;
> +       dev->ethtool_ops = &flexcan_ethtool_ops;
>         flexcan_set_ethtool_ops(dev);
>         dev->irq = irq;
>         dev->flags |= IFF_ECHO;
> diff --git a/drivers/net/can/grcan.c b/drivers/net/can/grcan.c
> index 24035a6187c9..ce64f2cbe9c6 100644
> --- a/drivers/net/can/grcan.c
> +++ b/drivers/net/can/grcan.c
> @@ -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>
> @@ -1561,6 +1562,16 @@ static const struct net_device_ops grcan_netdev_ops = {
>         .ndo_change_mtu = can_change_mtu,
>  };
>
> +static void grcan_get_drvinfo(struct net_device *netdev,
> +                             struct ethtool_drvinfo *drvinfo)
> +{
> +       strscpy(drvinfo->driver, DRV_NAME, sizeof(drvinfo->driver));
> +}
> +
> +static const struct ethtool_ops grcan_ethtool_ops = {
> +       .get_drvinfo = grcan_get_drvinfo,
> +};
> +
>  static int grcan_setup_netdev(struct platform_device *ofdev,
>                               void __iomem *base,
>                               int irq, u32 ambafreq, bool txbug)
> @@ -1577,6 +1588,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);
> diff --git a/drivers/net/can/ifi_canfd/ifi_canfd.c b/drivers/net/can/ifi_canfd/ifi_canfd.c
> index 64e3be8b73af..c682401eea3d 100644
> --- a/drivers/net/can/ifi_canfd/ifi_canfd.c
> +++ b/drivers/net/can/ifi_canfd/ifi_canfd.c
> @@ -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>
> @@ -925,6 +926,16 @@ static const struct net_device_ops ifi_canfd_netdev_ops = {
>         .ndo_change_mtu = can_change_mtu,
>  };
>
> +static void ifi_canfd_get_drvinfo(struct net_device *netdev,
> +                                 struct ethtool_drvinfo *drvinfo)
> +{
> +       strscpy(drvinfo->driver, KBUILD_MODNAME, sizeof(drvinfo->driver));
> +}
> +
> +static const struct ethtool_ops ifi_canfd_ethtool_ops = {
> +       .get_drvinfo = ifi_canfd_get_drvinfo,
> +};
> +
>  static int ifi_canfd_plat_probe(struct platform_device *pdev)
>  {
>         struct device *dev = &pdev->dev;
> @@ -962,6 +973,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;
> diff --git a/drivers/net/can/janz-ican3.c b/drivers/net/can/janz-ican3.c
> index ccb5c5405224..2534364e8be3 100644
> --- a/drivers/net/can/janz-ican3.c
> +++ b/drivers/net/can/janz-ican3.c
> @@ -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>
> @@ -1752,6 +1753,16 @@ static const struct net_device_ops ican3_netdev_ops = {
>         .ndo_change_mtu = can_change_mtu,
>  };
>
> +static void ican3_get_drvinfo(struct net_device *netdev,
> +                             struct ethtool_drvinfo *drvinfo)
> +{
> +       strscpy(drvinfo->driver, DRV_NAME, sizeof(drvinfo->driver));
> +}
> +
> +static const struct ethtool_ops ican3_ethtool_ops = {
> +       .get_drvinfo = ican3_get_drvinfo,
> +};
> +
>  /*
>   * Low-level CAN Device
>   */
> @@ -1923,6 +1934,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);
>
> diff --git a/drivers/net/can/kvaser_pciefd.c b/drivers/net/can/kvaser_pciefd.c
> index dcd2c9d50d5e..f7f7a0287a8d 100644
> --- a/drivers/net/can/kvaser_pciefd.c
> +++ b/drivers/net/can/kvaser_pciefd.c
> @@ -9,6 +9,7 @@
>  #include <linux/kernel.h>
>  #include <linux/module.h>
>  #include <linux/device.h>
> +#include <linux/ethtool.h>
>  #include <linux/pci.h>
>  #include <linux/can/dev.h>
>  #include <linux/timer.h>
> @@ -923,6 +924,16 @@ static const struct net_device_ops kvaser_pciefd_netdev_ops = {
>         .ndo_change_mtu = can_change_mtu,
>  };
>
> +static void kvaser_pciefd_get_drvinfo(struct net_device *netdev,
> +                                     struct ethtool_drvinfo *drvinfo)
> +{
> +       strscpy(drvinfo->driver, KVASER_PCIEFD_DRV_NAME, sizeof(drvinfo->driver));
> +}
> +
> +static const struct ethtool_ops kvaser_pciefd_ethtool_ops = {
> +       .get_drvinfo = kvaser_pciefd_get_drvinfo,
> +};
> +
>  static int kvaser_pciefd_setup_can_ctrls(struct kvaser_pciefd *pcie)
>  {
>         int i;
> @@ -939,6 +950,7 @@ static int kvaser_pciefd_setup_can_ctrls(struct kvaser_pciefd *pcie)
>
>                 can = netdev_priv(netdev);
>                 netdev->netdev_ops = &kvaser_pciefd_netdev_ops;
> +               netdev->ethtool_ops = &kvaser_pciefd_ethtool_ops;
>                 can->reg_base = pcie->reg_base + KVASER_PCIEFD_KCAN0_BASE +
>                                 i * KVASER_PCIEFD_KCAN_BASE_OFFSET;
>
> diff --git a/drivers/net/can/m_can/m_can.c b/drivers/net/can/m_can/m_can.c
> index 713a4b0edf86..dc55bfd260c9 100644
> --- a/drivers/net/can/m_can/m_can.c
> +++ b/drivers/net/can/m_can/m_can.c
> @@ -9,6 +9,7 @@
>   */
>
>  #include <linux/bitfield.h>
> +#include <linux/ethtool.h>
>  #include <linux/interrupt.h>
>  #include <linux/io.h>
>  #include <linux/kernel.h>
> @@ -1829,10 +1830,21 @@ static const struct net_device_ops m_can_netdev_ops = {
>         .ndo_change_mtu = can_change_mtu,
>  };
>
> +static void m_can_get_drvinfo(struct net_device *netdev,
> +                             struct ethtool_drvinfo *drvinfo)
> +{
> +       strscpy(drvinfo->driver, KBUILD_MODNAME, sizeof(drvinfo->driver));
> +}
> +
> +static const struct ethtool_ops m_can_ethtool_ops = {
> +       .get_drvinfo = m_can_get_drvinfo,
> +};
> +
>  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);
>  }
> diff --git a/drivers/net/can/mscan/mscan.c b/drivers/net/can/mscan/mscan.c
> index 78a21ab63601..b1677588a4c8 100644
> --- a/drivers/net/can/mscan/mscan.c
> +++ b/drivers/net/can/mscan/mscan.c
> @@ -676,6 +676,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 */
>
> diff --git a/drivers/net/can/pch_can.c b/drivers/net/can/pch_can.c
> index 32804fed116c..c51354b4cf0c 100644
> --- a/drivers/net/can/pch_can.c
> +++ b/drivers/net/can/pch_can.c
> @@ -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>
> @@ -938,6 +939,16 @@ static const struct net_device_ops pch_can_netdev_ops = {
>         .ndo_change_mtu         = can_change_mtu,
>  };
>
> +static void pch_can_get_drvinfo(struct net_device *netdev,
> +                               struct ethtool_drvinfo *drvinfo)
> +{
> +       strscpy(drvinfo->driver, KBUILD_MODNAME, sizeof(drvinfo->driver));
> +}
> +
> +static const struct ethtool_ops pch_can_ethtool_ops = {
> +       .get_drvinfo = pch_can_get_drvinfo,
> +};
> +
>  static void pch_can_remove(struct pci_dev *pdev)
>  {
>         struct net_device *ndev = pci_get_drvdata(pdev);
> @@ -1188,6 +1199,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);
> diff --git a/drivers/net/can/peak_canfd/peak_canfd.c b/drivers/net/can/peak_canfd/peak_canfd.c
> index afb9adb3d5c2..9b94d5b4be2d 100644
> --- a/drivers/net/can/peak_canfd/peak_canfd.c
> +++ b/drivers/net/can/peak_canfd/peak_canfd.c
> @@ -7,6 +7,7 @@
>
>  #include <linux/can.h>
>  #include <linux/can/dev.h>
> +#include <linux/ethtool.h>
>
>  #include "peak_canfd_user.h"
>
> @@ -749,6 +750,16 @@ static const struct net_device_ops peak_canfd_netdev_ops = {
>         .ndo_change_mtu = can_change_mtu,
>  };
>
> +static void peak_canfd_get_drvinfo(struct net_device *netdev,
> +                                  struct ethtool_drvinfo *drvinfo)
> +{
> +       strscpy(drvinfo->driver, KBUILD_MODNAME, sizeof(drvinfo->driver));
> +}
> +
> +static const struct ethtool_ops peak_canfd_ethtool_ops = {
> +       .get_drvinfo = peak_canfd_get_drvinfo,
> +};
> +
>  struct net_device *alloc_peak_canfd_dev(int sizeof_priv, int index,
>                                         int echo_skb_max)
>  {
> @@ -789,6 +800,7 @@ struct net_device *alloc_peak_canfd_dev(int sizeof_priv, int index,
>
>         ndev->flags |= IFF_ECHO;
>         ndev->netdev_ops = &peak_canfd_netdev_ops;
> +       ndev->ethtool_ops = &peak_canfd_ethtool_ops;
>         ndev->dev_id = index;
>
>         return ndev;
> diff --git a/drivers/net/can/rcar/rcar_can.c b/drivers/net/can/rcar/rcar_can.c
> index d11db2112a4a..aa644bb79da6 100644
> --- a/drivers/net/can/rcar/rcar_can.c
> +++ b/drivers/net/can/rcar/rcar_can.c
> @@ -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>
> @@ -630,6 +631,16 @@ static const struct net_device_ops rcar_can_netdev_ops = {
>         .ndo_change_mtu = can_change_mtu,
>  };
>
> +static void rcar_can_get_drvinfo(struct net_device *netdev,
> +                                struct ethtool_drvinfo *drvinfo)
> +{
> +       strscpy(drvinfo->driver, RCAR_CAN_DRV_NAME, sizeof(drvinfo->driver));
> +}
> +
> +static const struct ethtool_ops rcar_can_ethtool_ops = {
> +       .get_drvinfo = rcar_can_get_drvinfo,
> +};
> +
>  static void rcar_can_rx_pkt(struct rcar_can_priv *priv)
>  {
>         struct net_device_stats *stats = &priv->ndev->stats;
> @@ -785,6 +796,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;
> diff --git a/drivers/net/can/rcar/rcar_canfd.c b/drivers/net/can/rcar/rcar_canfd.c
> index d3e569a02b4d..89cc28985b81 100644
> --- a/drivers/net/can/rcar/rcar_canfd.c
> +++ b/drivers/net/can/rcar/rcar_canfd.c
> @@ -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>
> @@ -1695,6 +1696,16 @@ static const struct net_device_ops rcar_canfd_netdev_ops = {
>         .ndo_change_mtu = can_change_mtu,
>  };
>
> +static void rcar_canfd_get_drvinfo(struct net_device *netdev,
> +                                  struct ethtool_drvinfo *drvinfo)
> +{
> +       strscpy(drvinfo->driver, RCANFD_DRV_NAME, sizeof(drvinfo->driver));
> +}
> +
> +static const struct ethtool_ops rcar_canfd_ethtool_ops = {
> +       .get_drvinfo = rcar_canfd_get_drvinfo,
> +};
> +
>  static int rcar_canfd_channel_probe(struct rcar_canfd_global *gpriv, u32 ch,
>                                     u32 fcan_freq)
>  {
> @@ -1711,6 +1722,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;
> diff --git a/drivers/net/can/sja1000/sja1000.c b/drivers/net/can/sja1000/sja1000.c
> index 75a2f9bf8c16..43967790f4c1 100644
> --- a/drivers/net/can/sja1000/sja1000.c
> +++ b/drivers/net/can/sja1000/sja1000.c
> @@ -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>
> @@ -654,6 +655,16 @@ static const struct net_device_ops sja1000_netdev_ops = {
>         .ndo_change_mtu = can_change_mtu,
>  };
>
> +static void sja1000_get_drvinfo(struct net_device *netdev,
> +                               struct ethtool_drvinfo *drvinfo)
> +{
> +       strscpy(drvinfo->driver, DRV_NAME, sizeof(drvinfo->driver));
> +}
> +
> +static const struct ethtool_ops sja1000_ethtool_ops = {
> +       .get_drvinfo = sja1000_get_drvinfo,
> +};
> +
>  int register_sja1000dev(struct net_device *dev)
>  {
>         int ret;
> @@ -663,6 +674,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);
> diff --git a/drivers/net/can/slcan/slcan-core.c b/drivers/net/can/slcan/slcan-core.c
> index d1562f9474c9..1b86001c85f8 100644
> --- a/drivers/net/can/slcan/slcan-core.c
> +++ b/drivers/net/can/slcan/slcan-core.c
> @@ -46,6 +46,7 @@
>  #include <linux/string.h>
>  #include <linux/tty.h>
>  #include <linux/errno.h>
> +#include <linux/ethtool.h>
>  #include <linux/netdevice.h>
>  #include <linux/skbuff.h>
>  #include <linux/rtnetlink.h>
> @@ -790,6 +791,16 @@ static const struct net_device_ops slc_netdev_ops = {
>         .ndo_change_mtu         = slcan_change_mtu,
>  };
>
> +static void slcan_get_drvinfo(struct net_device *netdev,
> +                             struct ethtool_drvinfo *drvinfo)
> +{
> +       strscpy(drvinfo->driver, DRV_NAME, sizeof(drvinfo->driver));
> +}
> +

Please put the function inside the slcan-ethtool.c.

> +static const struct ethtool_ops slcan_ethtool_ops = {
> +       .get_drvinfo = slcan_get_drvinfo,
> +};
> +

slcan_ethtool_ops is is already defined in slcan-ethtool.c

>  /******************************************
>   *  Routines looking at TTY side.
>   ******************************************/
> @@ -869,6 +880,7 @@ static struct slcan *slc_alloc(void)
>
>         snprintf(dev->name, sizeof(dev->name), DRV_NAME "%d", i);
>         dev->netdev_ops = &slc_netdev_ops;
> +       dev->ethtool_ops = &slcan_ethtool_ops;
>         dev->base_addr  = i;
>         slcan_set_ethtool_ops(dev);

It already sets dev->ethtool_ops.

Thanks and regards,
Dario

>         sl = netdev_priv(dev);
> diff --git a/drivers/net/can/softing/softing_main.c b/drivers/net/can/softing/softing_main.c
> index d810fe6915a4..d2ce61562ccc 100644
> --- a/drivers/net/can/softing/softing_main.c
> +++ b/drivers/net/can/softing/softing_main.c
> @@ -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>
> @@ -612,6 +613,16 @@ static const struct net_device_ops softing_netdev_ops = {
>         .ndo_change_mtu = can_change_mtu,
>  };
>
> +static void softing_get_drvinfo(struct net_device *netdev,
> +                               struct ethtool_drvinfo *drvinfo)
> +{
> +       strscpy(drvinfo->driver, DRV_NAME, sizeof(drvinfo->driver));
> +}
> +
> +static const struct ethtool_ops softing_ethtool_ops = {
> +       .get_drvinfo = softing_get_drvinfo,
> +};
> +
>  static const struct can_bittiming_const softing_btr_const = {
>         .name = DRV_NAME,
>         .tseg1_min = 1,
> @@ -650,6 +661,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;
>
> diff --git a/drivers/net/can/spi/hi311x.c b/drivers/net/can/spi/hi311x.c
> index 167114aae6dd..5e0c0d21aee2 100644
> --- a/drivers/net/can/spi/hi311x.c
> +++ b/drivers/net/can/spi/hi311x.c
> @@ -20,6 +20,7 @@
>  #include <linux/completion.h>
>  #include <linux/delay.h>
>  #include <linux/device.h>
> +#include <linux/ethtool.h>
>  #include <linux/freezer.h>
>  #include <linux/interrupt.h>
>  #include <linux/io.h>
> @@ -802,6 +803,16 @@ static const struct net_device_ops hi3110_netdev_ops = {
>         .ndo_start_xmit = hi3110_hard_start_xmit,
>  };
>
> +static void hi3110_get_drvinfo(struct net_device *netdev,
> +                              struct ethtool_drvinfo *drvinfo)
> +{
> +       strscpy(drvinfo->driver, DEVICE_NAME, sizeof(drvinfo->driver));
> +}
> +
> +static const struct ethtool_ops hi3110_ethtool_ops = {
> +       .get_drvinfo = hi3110_get_drvinfo,
> +};
> +
>  static const struct of_device_id hi3110_of_match[] = {
>         {
>                 .compatible     = "holt,hi3110",
> @@ -856,6 +867,7 @@ static int hi3110_can_probe(struct spi_device *spi)
>                 goto out_free;
>
>         net->netdev_ops = &hi3110_netdev_ops;
> +       net->ethtool_ops = &hi3110_ethtool_ops;
>         net->flags |= IFF_ECHO;
>
>         priv = netdev_priv(net);
> diff --git a/drivers/net/can/spi/mcp251x.c b/drivers/net/can/spi/mcp251x.c
> index 666a4505a55a..2e4c03c61b15 100644
> --- a/drivers/net/can/spi/mcp251x.c
> +++ b/drivers/net/can/spi/mcp251x.c
> @@ -26,6 +26,7 @@
>  #include <linux/completion.h>
>  #include <linux/delay.h>
>  #include <linux/device.h>
> +#include <linux/ethtool.h>
>  #include <linux/freezer.h>
>  #include <linux/gpio.h>
>  #include <linux/gpio/driver.h>
> @@ -1248,6 +1249,16 @@ static const struct net_device_ops mcp251x_netdev_ops = {
>         .ndo_change_mtu = can_change_mtu,
>  };
>
> +static void mcp251x_get_drvinfo(struct net_device *netdev,
> +                               struct ethtool_drvinfo *drvinfo)
> +{
> +       strscpy(drvinfo->driver, DEVICE_NAME, sizeof(drvinfo->driver));
> +}
> +
> +static const struct ethtool_ops mcp251x_ethtool_ops = {
> +       .get_drvinfo = mcp251x_get_drvinfo,
> +};
> +
>  static const struct of_device_id mcp251x_of_match[] = {
>         {
>                 .compatible     = "microchip,mcp2510",
> @@ -1313,6 +1324,7 @@ static int mcp251x_can_probe(struct spi_device *spi)
>                 goto out_free;
>
>         net->netdev_ops = &mcp251x_netdev_ops;
> +       net->ethtool_ops = &mcp251x_ethtool_ops;
>         net->flags |= IFF_ECHO;
>
>         priv = netdev_priv(net);
> diff --git a/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c b/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c
> index 7fc86ed405c6..d9a7de1927d6 100644
> --- a/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c
> +++ b/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c
> @@ -16,6 +16,7 @@
>  #include <linux/bitfield.h>
>  #include <linux/clk.h>
>  #include <linux/device.h>
> +#include <linux/ethtool.h>
>  #include <linux/mod_devicetable.h>
>  #include <linux/module.h>
>  #include <linux/pm_runtime.h>
> @@ -1674,6 +1675,16 @@ static const struct net_device_ops mcp251xfd_netdev_ops = {
>         .ndo_change_mtu = can_change_mtu,
>  };
>
> +static void mcp251xfd_get_drvinfo(struct net_device *netdev,
> +                                 struct ethtool_drvinfo *drvinfo)
> +{
> +       strscpy(drvinfo->driver, DEVICE_NAME, sizeof(drvinfo->driver));
> +}
> +
> +static const struct ethtool_ops mcp251xfd_ethtool_ops = {
> +       .get_drvinfo = mcp251xfd_get_drvinfo,
> +};
> +
>  static void
>  mcp251xfd_register_quirks(struct mcp251xfd_priv *priv)
>  {
> @@ -2050,6 +2061,7 @@ static int mcp251xfd_probe(struct spi_device *spi)
>         SET_NETDEV_DEV(ndev, &spi->dev);
>
>         ndev->netdev_ops = &mcp251xfd_netdev_ops;
> +       ndev->ethtool_ops = &mcp251xfd_ethtool_ops;
>         ndev->irq = spi->irq;
>         ndev->flags |= IFF_ECHO;
>
> diff --git a/drivers/net/can/sun4i_can.c b/drivers/net/can/sun4i_can.c
> index b90dfb429ccd..27ea4e68b516 100644
> --- a/drivers/net/can/sun4i_can.c
> +++ b/drivers/net/can/sun4i_can.c
> @@ -53,6 +53,7 @@
>  #include <linux/can/error.h>
>  #include <linux/clk.h>
>  #include <linux/delay.h>
> +#include <linux/ethtool.h>
>  #include <linux/interrupt.h>
>  #include <linux/init.h>
>  #include <linux/io.h>
> @@ -761,6 +762,16 @@ static const struct net_device_ops sun4ican_netdev_ops = {
>         .ndo_start_xmit = sun4ican_start_xmit,
>  };
>
> +static void sun4ican_get_drvinfo(struct net_device *netdev,
> +                                struct ethtool_drvinfo *drvinfo)
> +{
> +       strscpy(drvinfo->driver, DRV_NAME, sizeof(drvinfo->driver));
> +}
> +
> +static const struct ethtool_ops sun4ican_ethtool_ops = {
> +       .get_drvinfo = sun4ican_get_drvinfo,
> +};
> +
>  static const struct sun4ican_quirks sun4ican_quirks_a10 = {
>         .has_reset = false,
>  };
> @@ -851,6 +862,7 @@ static int sun4ican_probe(struct platform_device *pdev)
>         }
>
>         dev->netdev_ops = &sun4ican_netdev_ops;
> +       dev->ethtool_ops = &sun4ican_ethtool_ops;
>         dev->irq = irq;
>         dev->flags |= IFF_ECHO;
>
> diff --git a/drivers/net/can/ti_hecc.c b/drivers/net/can/ti_hecc.c
> index afa38771520e..965376453050 100644
> --- a/drivers/net/can/ti_hecc.c
> +++ b/drivers/net/can/ti_hecc.c
> @@ -23,6 +23,7 @@
>  #include <linux/types.h>
>  #include <linux/interrupt.h>
>  #include <linux/errno.h>
> +#include <linux/ethtool.h>
>  #include <linux/netdevice.h>
>  #include <linux/skbuff.h>
>  #include <linux/platform_device.h>
> @@ -841,6 +842,16 @@ static const struct net_device_ops ti_hecc_netdev_ops = {
>         .ndo_change_mtu         = can_change_mtu,
>  };
>
> +static void ti_hecc_get_drvinfo(struct net_device *netdev,
> +                               struct ethtool_drvinfo *drvinfo)
> +{
> +       strscpy(drvinfo->driver, DRV_NAME, sizeof(drvinfo->driver));
> +}
> +
> +static const struct ethtool_ops ti_hecc_ethtool_ops = {
> +       .get_drvinfo = ti_hecc_get_drvinfo,
> +};
> +
>  static const struct of_device_id ti_hecc_dt_ids[] = {
>         {
>                 .compatible = "ti,am3517-hecc",
> @@ -918,6 +929,7 @@ static int ti_hecc_probe(struct platform_device *pdev)
>         platform_set_drvdata(pdev, ndev);
>         SET_NETDEV_DEV(ndev, &pdev->dev);
>         ndev->netdev_ops = &ti_hecc_netdev_ops;
> +       ndev->ethtool_ops = &ti_hecc_ethtool_ops;
>
>         priv->clk = clk_get(&pdev->dev, "hecc_ck");
>         if (IS_ERR(priv->clk)) {
> diff --git a/drivers/net/can/usb/ems_usb.c b/drivers/net/can/usb/ems_usb.c
> index e86a2033db60..ac155f73bedd 100644
> --- a/drivers/net/can/usb/ems_usb.c
> +++ b/drivers/net/can/usb/ems_usb.c
> @@ -4,6 +4,7 @@
>   *
>   * Copyright (C) 2004-2009 EMS Dr. Thomas Wuensche
>   */
> +#include <linux/ethtool.h>
>  #include <linux/signal.h>
>  #include <linux/slab.h>
>  #include <linux/module.h>
> @@ -879,6 +880,16 @@ static const struct net_device_ops ems_usb_netdev_ops = {
>         .ndo_change_mtu = can_change_mtu,
>  };
>
> +static void ems_usb_get_drvinfo(struct net_device *netdev,
> +                               struct ethtool_drvinfo *drvinfo)
> +{
> +       strscpy(drvinfo->driver, KBUILD_MODNAME, sizeof(drvinfo->driver));
> +}
> +
> +static const struct ethtool_ops ems_usb_ethtool_ops = {
> +       .get_drvinfo = ems_usb_get_drvinfo,
> +};
> +
>  static const struct can_bittiming_const ems_usb_bittiming_const = {
>         .name = KBUILD_MODNAME,
>         .tseg1_min = 1,
> @@ -990,6 +1001,7 @@ static int ems_usb_probe(struct usb_interface *intf,
>         dev->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES;
>
>         netdev->netdev_ops = &ems_usb_netdev_ops;
> +       netdev->ethtool_ops = &ems_usb_ethtool_ops;
>
>         netdev->flags |= IFF_ECHO; /* we support local echo */
>
> diff --git a/drivers/net/can/usb/esd_usb.c b/drivers/net/can/usb/esd_usb.c
> index 7b849bd3cc9c..2367edd49eb7 100644
> --- a/drivers/net/can/usb/esd_usb.c
> +++ b/drivers/net/can/usb/esd_usb.c
> @@ -5,6 +5,7 @@
>   * 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>
>   */
> +#include <linux/ethtool.h>
>  #include <linux/signal.h>
>  #include <linux/slab.h>
>  #include <linux/module.h>
> @@ -882,6 +883,16 @@ static const struct net_device_ops esd_usb_netdev_ops = {
>         .ndo_change_mtu = can_change_mtu,
>  };
>
> +static void esd_usb_get_drvinfo(struct net_device *netdev,
> +                               struct ethtool_drvinfo *drvinfo)
> +{
> +       strscpy(drvinfo->driver, KBUILD_MODNAME, sizeof(drvinfo->driver));
> +}
> +
> +static const struct ethtool_ops esd_usb_ethtool_ops = {
> +       .get_drvinfo = esd_usb_get_drvinfo,
> +};
> +
>  static const struct can_bittiming_const esd_usb2_bittiming_const = {
>         .name = "esd_usb2",
>         .tseg1_min = ESD_USB2_TSEG1_MIN,
> @@ -1015,6 +1026,7 @@ static int esd_usb_probe_one_net(struct usb_interface *intf, int index)
>         netdev->flags |= IFF_ECHO; /* we support local echo */
>
>         netdev->netdev_ops = &esd_usb_netdev_ops;
> +       netdev->ethtool_ops = &esd_usb_ethtool_ops;
>
>         SET_NETDEV_DEV(netdev, &intf->dev);
>         netdev->dev_id = index;
> diff --git a/drivers/net/can/usb/etas_es58x/es58x_core.c b/drivers/net/can/usb/etas_es58x/es58x_core.c
> index 3f51488bd649..0e692c2dc54d 100644
> --- a/drivers/net/can/usb/etas_es58x/es58x_core.c
> +++ b/drivers/net/can/usb/etas_es58x/es58x_core.c
> @@ -10,6 +10,7 @@
>   * Copyright (c) 2020, 2021 Vincent Mailhol <mailhol.vincent@wanadoo.fr>
>   */
>
> +#include <linux/ethtool.h>
>  #include <linux/kernel.h>
>  #include <linux/module.h>
>  #include <linux/usb.h>
> @@ -1982,6 +1983,16 @@ static const struct net_device_ops es58x_netdev_ops = {
>         .ndo_start_xmit = es58x_start_xmit
>  };
>
> +static void es58x_get_drvinfo(struct net_device *netdev,
> +                             struct ethtool_drvinfo *drvinfo)
> +{
> +       strscpy(drvinfo->driver, ES58X_MODULE_NAME, sizeof(drvinfo->driver));
> +}
> +
> +static const struct ethtool_ops es58x_ethtool_ops = {
> +       .get_drvinfo = es58x_get_drvinfo,
> +};
> +
>  /**
>   * es58x_set_mode() - Change network device mode.
>   * @netdev: CAN network device.
> @@ -2086,6 +2097,7 @@ static int es58x_init_netdev(struct es58x_device *es58x_dev, int channel_idx)
>         es58x_init_priv(es58x_dev, es58x_priv(netdev), channel_idx);
>
>         netdev->netdev_ops = &es58x_netdev_ops;
> +       netdev->ethtool_ops = &es58x_ethtool_ops;
>         netdev->flags |= IFF_ECHO;      /* We support local echo */
>         netdev->dev_port = channel_idx;
>
> diff --git a/drivers/net/can/usb/gs_usb.c b/drivers/net/can/usb/gs_usb.c
> index fd239b523c42..75f5e9c5059a 100644
> --- a/drivers/net/can/usb/gs_usb.c
> +++ b/drivers/net/can/usb/gs_usb.c
> @@ -924,6 +924,12 @@ static int gs_usb_set_identify(struct net_device *netdev, bool do_identify)
>         return (rc > 0) ? 0 : rc;
>  }
>
> +static void gs_usb_get_drvinfo(struct net_device *netdev,
> +                              struct ethtool_drvinfo *drvinfo)
> +{
> +       strscpy(drvinfo->driver, KBUILD_MODNAME, sizeof(drvinfo->driver));
> +}
> +
>  /* blink LED's for finding the this interface */
>  static int gs_usb_set_phys_id(struct net_device *dev,
>                               enum ethtool_phys_id_state state)
> @@ -945,6 +951,7 @@ static int gs_usb_set_phys_id(struct net_device *dev,
>  }
>
>  static const struct ethtool_ops gs_usb_ethtool_ops = {
> +       .get_drvinfo = gs_usb_get_drvinfo,
>         .set_phys_id = gs_usb_set_phys_id,
>  };
>
> @@ -989,6 +996,7 @@ static struct gs_can *gs_make_candev(unsigned int channel,
>         dev = netdev_priv(netdev);
>
>         netdev->netdev_ops = &gs_usb_netdev_ops;
> +       netdev->ethtool_ops = &gs_usb_ethtool_ops;
>
>         netdev->flags |= IFF_ECHO; /* we support full roundtrip echo */
>
> diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c b/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c
> index a6cff8da5a41..964c0026383e 100644
> --- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c
> +++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c
> @@ -13,6 +13,7 @@
>
>  #include <linux/completion.h>
>  #include <linux/device.h>
> +#include <linux/ethtool.h>
>  #include <linux/gfp.h>
>  #include <linux/if.h>
>  #include <linux/kernel.h>
> @@ -667,6 +668,16 @@ static const struct net_device_ops kvaser_usb_netdev_ops = {
>         .ndo_change_mtu = can_change_mtu,
>  };
>
> +static void kvaser_usb_get_drvinfo(struct net_device *netdev,
> +                                  struct ethtool_drvinfo *drvinfo)
> +{
> +       strscpy(drvinfo->driver, DRV_NAME, sizeof(drvinfo->driver));
> +}
> +
> +static const struct ethtool_ops kvaser_usb_ethtool_ops = {
> +       .get_drvinfo = kvaser_usb_get_drvinfo,
> +};
> +
>  static void kvaser_usb_remove_interfaces(struct kvaser_usb *dev)
>  {
>         int i;
> @@ -744,6 +755,7 @@ static int kvaser_usb_init_one(struct kvaser_usb *dev, int channel)
>         netdev->flags |= IFF_ECHO;
>
>         netdev->netdev_ops = &kvaser_usb_netdev_ops;
> +       netdev->ethtool_ops = &kvaser_usb_ethtool_ops;
>
>         SET_NETDEV_DEV(netdev, &dev->intf->dev);
>         netdev->dev_id = channel;
> diff --git a/drivers/net/can/usb/mcba_usb.c b/drivers/net/can/usb/mcba_usb.c
> index 792ab9da317d..485ec697fc08 100644
> --- a/drivers/net/can/usb/mcba_usb.c
> +++ b/drivers/net/can/usb/mcba_usb.c
> @@ -10,6 +10,7 @@
>  #include <linux/can.h>
>  #include <linux/can/dev.h>
>  #include <linux/can/error.h>
> +#include <linux/ethtool.h>
>  #include <linux/module.h>
>  #include <linux/netdevice.h>
>  #include <linux/signal.h>
> @@ -758,6 +759,16 @@ static const struct net_device_ops mcba_netdev_ops = {
>         .ndo_start_xmit = mcba_usb_start_xmit,
>  };
>
> +static void mcba_get_drvinfo(struct net_device *netdev,
> +                            struct ethtool_drvinfo *drvinfo)
> +{
> +       strscpy(drvinfo->driver, MCBA_MODULE_NAME, sizeof(drvinfo->driver));
> +}
> +
> +static const struct ethtool_ops mcba_ethtool_ops = {
> +       .get_drvinfo = mcba_get_drvinfo,
> +};
> +
>  /* Microchip CANBUS has hardcoded bittiming values by default.
>   * This function sends request via USB to change the speed and align bittiming
>   * values for presentation purposes only
> @@ -836,6 +847,7 @@ static int mcba_usb_probe(struct usb_interface *intf,
>         priv->can.do_set_bittiming = mcba_net_set_bittiming;
>
>         netdev->netdev_ops = &mcba_netdev_ops;
> +       netdev->ethtool_ops = &mcba_ethtool_ops;
>
>         netdev->flags |= IFF_ECHO; /* we support local echo */
>
> diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_core.c b/drivers/net/can/usb/peak_usb/pcan_usb_core.c
> index 27b0a72fd885..959448bae3ca 100644
> --- a/drivers/net/can/usb/peak_usb/pcan_usb_core.c
> +++ b/drivers/net/can/usb/peak_usb/pcan_usb_core.c
> @@ -782,6 +782,12 @@ static const struct net_device_ops peak_usb_netdev_ops = {
>         .ndo_change_mtu = can_change_mtu,
>  };
>
> +void peak_usb_get_drvinfo(struct net_device *netdev,
> +                         struct ethtool_drvinfo *drvinfo)
> +{
> +       strscpy(drvinfo->driver, PCAN_USB_DRIVER_NAME, sizeof(drvinfo->driver));
> +}
> +
>  /*
>   * create one device which is attached to CAN controller #ctrl_idx of the
>   * usb adapter.
> diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_core.h b/drivers/net/can/usb/peak_usb/pcan_usb_core.h
> index 9c90487b9c92..da1205575379 100644
> --- a/drivers/net/can/usb/peak_usb/pcan_usb_core.h
> +++ b/drivers/net/can/usb/peak_usb/pcan_usb_core.h
> @@ -145,5 +145,7 @@ int peak_usb_netif_rx(struct sk_buff *skb,
>  int peak_usb_netif_rx_64(struct sk_buff *skb, u32 ts_low, u32 ts_high);
>  void peak_usb_async_complete(struct urb *urb);
>  void peak_usb_restart_complete(struct peak_usb_device *dev);
> +void peak_usb_get_drvinfo(struct net_device *netdev,
> +                         struct ethtool_drvinfo *drvinfo);
>
>  #endif
> diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_fd.c b/drivers/net/can/usb/peak_usb/pcan_usb_fd.c
> index 3d7e0e370505..63122f567380 100644
> --- a/drivers/net/can/usb/peak_usb/pcan_usb_fd.c
> +++ b/drivers/net/can/usb/peak_usb/pcan_usb_fd.c
> @@ -1079,6 +1079,7 @@ static int pcan_usb_fd_set_phys_id(struct net_device *netdev,
>  }
>
>  static const struct ethtool_ops pcan_usb_fd_ethtool_ops = {
> +       .get_drvinfo = peak_usb_get_drvinfo,
>         .set_phys_id = pcan_usb_fd_set_phys_id,
>  };
>
> diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_pro.c b/drivers/net/can/usb/peak_usb/pcan_usb_pro.c
> index 457887113e75..ea2d4fbceaa4 100644
> --- a/drivers/net/can/usb/peak_usb/pcan_usb_pro.c
> +++ b/drivers/net/can/usb/peak_usb/pcan_usb_pro.c
> @@ -1021,6 +1021,7 @@ static int pcan_usb_pro_set_phys_id(struct net_device *netdev,
>  }
>
>  static const struct ethtool_ops pcan_usb_pro_ethtool_ops = {
> +       .get_drvinfo = peak_usb_get_drvinfo,
>         .set_phys_id = pcan_usb_pro_set_phys_id,
>  };
>
> diff --git a/drivers/net/can/usb/ucan.c b/drivers/net/can/usb/ucan.c
> index 5ae0d7c017cc..52263fa286f3 100644
> --- a/drivers/net/can/usb/ucan.c
> +++ b/drivers/net/can/usb/ucan.c
> @@ -28,6 +28,7 @@
>  #include <linux/can.h>
>  #include <linux/can/dev.h>
>  #include <linux/can/error.h>
> +#include <linux/ethtool.h>
>  #include <linux/module.h>
>  #include <linux/netdevice.h>
>  #include <linux/signal.h>
> @@ -1233,6 +1234,16 @@ static const struct net_device_ops ucan_netdev_ops = {
>         .ndo_change_mtu = can_change_mtu,
>  };
>
> +static void ucan_get_drvinfo(struct net_device *netdev,
> +                            struct ethtool_drvinfo *drvinfo)
> +{
> +       strscpy(drvinfo->driver, UCAN_DRIVER_NAME, sizeof(drvinfo->driver));
> +}
> +
> +static const struct ethtool_ops ucan_ethtool_ops = {
> +       .get_drvinfo = ucan_get_drvinfo,
> +};
> +
>  /* Request to set bittiming
>   *
>   * This function generates an USB set bittiming message and transmits
> @@ -1512,6 +1523,7 @@ static int ucan_probe(struct usb_interface *intf,
>         spin_lock_init(&up->context_lock);
>         spin_lock_init(&up->echo_skb_lock);
>         netdev->netdev_ops = &ucan_netdev_ops;
> +       netdev->ethtool_ops = &ucan_ethtool_ops;
>
>         usb_set_intfdata(intf, up);
>         SET_NETDEV_DEV(netdev, &intf->dev);
> diff --git a/drivers/net/can/usb/usb_8dev.c b/drivers/net/can/usb/usb_8dev.c
> index 6665a66745a7..2a56d7c2fdb6 100644
> --- a/drivers/net/can/usb/usb_8dev.c
> +++ b/drivers/net/can/usb/usb_8dev.c
> @@ -12,6 +12,7 @@
>   * who were very cooperative and answered my questions.
>   */
>
> +#include <linux/ethtool.h>
>  #include <linux/signal.h>
>  #include <linux/slab.h>
>  #include <linux/module.h>
> @@ -870,6 +871,16 @@ static const struct net_device_ops usb_8dev_netdev_ops = {
>         .ndo_change_mtu = can_change_mtu,
>  };
>
> +static void usb_8dev_get_drvinfo(struct net_device *netdev,
> +                                struct ethtool_drvinfo *drvinfo)
> +{
> +       strscpy(drvinfo->driver, KBUILD_MODNAME, sizeof(drvinfo->driver));
> +}
> +
> +static const struct ethtool_ops usb_8dev_ethtool_ops = {
> +       .get_drvinfo = usb_8dev_get_drvinfo,
> +};
> +
>  static const struct can_bittiming_const usb_8dev_bittiming_const = {
>         .name = KBUILD_MODNAME,
>         .tseg1_min = 1,
> @@ -927,6 +938,7 @@ static int usb_8dev_probe(struct usb_interface *intf,
>                                       CAN_CTRLMODE_CC_LEN8_DLC;
>
>         netdev->netdev_ops = &usb_8dev_netdev_ops;
> +       netdev->ethtool_ops = &usb_8dev_ethtool_ops;
>
>         netdev->flags |= IFF_ECHO; /* we support local echo */
>
> diff --git a/drivers/net/can/vcan.c b/drivers/net/can/vcan.c
> index a15619d883ec..6827c717af44 100644
> --- a/drivers/net/can/vcan.c
> +++ b/drivers/net/can/vcan.c
> @@ -40,6 +40,7 @@
>
>  #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
>
> +#include <linux/ethtool.h>
>  #include <linux/module.h>
>  #include <linux/init.h>
>  #include <linux/netdevice.h>
> @@ -146,6 +147,16 @@ static const struct net_device_ops vcan_netdev_ops = {
>         .ndo_change_mtu = vcan_change_mtu,
>  };
>
> +static void vcan_get_drvinfo(struct net_device *netdev,
> +                            struct ethtool_drvinfo *drvinfo)
> +{
> +       strscpy(drvinfo->driver, KBUILD_MODNAME, sizeof(drvinfo->driver));
> +}
> +
> +static const struct ethtool_ops vcan_ethtool_ops = {
> +       .get_drvinfo = vcan_get_drvinfo,
> +};
> +
>  static void vcan_setup(struct net_device *dev)
>  {
>         dev->type               = ARPHRD_CAN;
> @@ -161,6 +172,7 @@ static void vcan_setup(struct net_device *dev)
>                 dev->flags |= IFF_ECHO;
>
>         dev->netdev_ops         = &vcan_netdev_ops;
> +       dev->ethtool_ops        = &vcan_ethtool_ops;
>         dev->needs_free_netdev  = true;
>  }
>
> diff --git a/drivers/net/can/vxcan.c b/drivers/net/can/vxcan.c
> index 577a80300514..a221c00fe660 100644
> --- a/drivers/net/can/vxcan.c
> +++ b/drivers/net/can/vxcan.c
> @@ -9,6 +9,7 @@
>   * Copyright (c) 2017 Oliver Hartkopp <socketcan@hartkopp.net>
>   */
>
> +#include <linux/ethtool.h>
>  #include <linux/module.h>
>  #include <linux/init.h>
>  #include <linux/netdevice.h>
> @@ -144,6 +145,16 @@ static const struct net_device_ops vxcan_netdev_ops = {
>         .ndo_change_mtu = vxcan_change_mtu,
>  };
>
> +static void vxcan_get_drvinfo(struct net_device *netdev,
> +                             struct ethtool_drvinfo *drvinfo)
> +{
> +       strscpy(drvinfo->driver, KBUILD_MODNAME, sizeof(drvinfo->driver));
> +}
> +
> +static const struct ethtool_ops vxcan_ethtool_ops = {
> +       .get_drvinfo = vxcan_get_drvinfo,
> +};
> +
>  static void vxcan_setup(struct net_device *dev)
>  {
>         struct can_ml_priv *can_ml;
> @@ -155,6 +166,7 @@ static void vxcan_setup(struct net_device *dev)
>         dev->tx_queue_len       = 0;
>         dev->flags              = IFF_NOARP;
>         dev->netdev_ops         = &vxcan_netdev_ops;
> +       dev->ethtool_ops        = &vxcan_ethtool_ops;
>         dev->needs_free_netdev  = true;
>
>         can_ml = netdev_priv(dev) + ALIGN(sizeof(struct vxcan_priv), NETDEV_ALIGN);
> diff --git a/drivers/net/can/xilinx_can.c b/drivers/net/can/xilinx_can.c
> index caa6b4cee63f..b802ddec1965 100644
> --- a/drivers/net/can/xilinx_can.c
> +++ b/drivers/net/can/xilinx_can.c
> @@ -12,6 +12,7 @@
>  #include <linux/bitfield.h>
>  #include <linux/clk.h>
>  #include <linux/errno.h>
> +#include <linux/ethtool.h>
>  #include <linux/init.h>
>  #include <linux/interrupt.h>
>  #include <linux/io.h>
> @@ -1540,6 +1541,16 @@ static const struct net_device_ops xcan_netdev_ops = {
>         .ndo_change_mtu = can_change_mtu,
>  };
>
> +static void xcan_get_drvinfo(struct net_device *netdev,
> +                            struct ethtool_drvinfo *drvinfo)
> +{
> +       strscpy(drvinfo->driver, DRIVER_NAME, sizeof(drvinfo->driver));
> +}
> +
> +static const struct ethtool_ops xcan_ethtool_ops = {
> +       .get_drvinfo = xcan_get_drvinfo,
> +};
> +
>  /**
>   * xcan_suspend - Suspend method for the driver
>   * @dev:       Address of the device structure
> @@ -1821,6 +1832,7 @@ static int xcan_probe(struct platform_device *pdev)
>         platform_set_drvdata(pdev, ndev);
>         SET_NETDEV_DEV(ndev, &pdev->dev);
>         ndev->netdev_ops = &xcan_netdev_ops;
> +       ndev->ethtool_ops = &xcan_ethtool_ops;
>
>         /* Getting the CAN can_clk info */
>         priv->can_clk = devm_clk_get(&pdev->dev, "can_clk");
> --
> 2.35.1
>


-- 

Dario Binacchi

Embedded Linux Developer

dario.binacchi@amarulasolutions.com

__________________________________


Amarula Solutions SRL

Via Le Canevare 30, 31100 Treviso, Veneto, IT

T. +39 042 243 5310
info@amarulasolutions.com

www.amarulasolutions.com

^ permalink raw reply	[flat|nested] 92+ messages in thread

* Re: [PATCH v1 10/24] can: tree-wide: implement ethtool_ops::get_drvinfo()
  2022-07-26  7:29   ` Dario Binacchi
@ 2022-07-26  8:42     ` Vincent MAILHOL
  2022-07-26  9:21       ` Dario Binacchi
  0 siblings, 1 reply; 92+ messages in thread
From: Vincent MAILHOL @ 2022-07-26  8:42 UTC (permalink / raw)
  To: Dario Binacchi
  Cc: linux-can, Marc Kleine-Budde, Stephane Grosjean, Jimmy Assarsson,
	Oliver Hartkopp, Max Staudt

Hi Dario,

On Tue. 26 Jul. 2022 at 16:41, Dario Binacchi
<dario.binacchi@amarulasolutions.com> wrote:
> Hi Vincent,
>
> On Mon, Jul 25, 2022 at 3:32 PM Vincent Mailhol
> <mailhol.vincent@wanadoo.fr> wrote:
> >
> > For all CAN drivers, implement the get_drvinfo() function.
> >
> > After this patch, it is now possible to retrieve basic information by
> > doing:
> >
> > | $ ethtool -i canX
> >
> > Signed-off-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
> > ---
> >  drivers/net/can/at91_can.c                       | 12 ++++++++++++
> >  drivers/net/can/c_can/c_can_main.c               | 12 ++++++++++++
> >  drivers/net/can/can327.c                         | 11 +++++++++++
> >  drivers/net/can/cc770/cc770.c                    | 12 ++++++++++++
> >  drivers/net/can/ctucanfd/ctucanfd_base.c         | 12 ++++++++++++
> >  drivers/net/can/flexcan/flexcan-core.c           | 12 ++++++++++++
> >  drivers/net/can/grcan.c                          | 12 ++++++++++++
> >  drivers/net/can/ifi_canfd/ifi_canfd.c            | 12 ++++++++++++
> >  drivers/net/can/janz-ican3.c                     | 12 ++++++++++++
> >  drivers/net/can/kvaser_pciefd.c                  | 12 ++++++++++++
> >  drivers/net/can/m_can/m_can.c                    | 12 ++++++++++++
> >  drivers/net/can/mscan/mscan.c                    |  1 +
> >  drivers/net/can/pch_can.c                        | 12 ++++++++++++
> >  drivers/net/can/peak_canfd/peak_canfd.c          | 12 ++++++++++++
> >  drivers/net/can/rcar/rcar_can.c                  | 12 ++++++++++++
> >  drivers/net/can/rcar/rcar_canfd.c                | 12 ++++++++++++
> >  drivers/net/can/sja1000/sja1000.c                | 12 ++++++++++++
> >  drivers/net/can/slcan/slcan-core.c               | 12 ++++++++++++
> >  drivers/net/can/softing/softing_main.c           | 12 ++++++++++++
> >  drivers/net/can/spi/hi311x.c                     | 12 ++++++++++++
> >  drivers/net/can/spi/mcp251x.c                    | 12 ++++++++++++
> >  drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c   | 12 ++++++++++++
> >  drivers/net/can/sun4i_can.c                      | 12 ++++++++++++
> >  drivers/net/can/ti_hecc.c                        | 12 ++++++++++++
> >  drivers/net/can/usb/ems_usb.c                    | 12 ++++++++++++
> >  drivers/net/can/usb/esd_usb.c                    | 12 ++++++++++++
> >  drivers/net/can/usb/etas_es58x/es58x_core.c      | 12 ++++++++++++
> >  drivers/net/can/usb/gs_usb.c                     |  8 ++++++++
> >  drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c | 12 ++++++++++++
> >  drivers/net/can/usb/mcba_usb.c                   | 12 ++++++++++++
> >  drivers/net/can/usb/peak_usb/pcan_usb_core.c     |  6 ++++++
> >  drivers/net/can/usb/peak_usb/pcan_usb_core.h     |  2 ++
> >  drivers/net/can/usb/peak_usb/pcan_usb_fd.c       |  1 +
> >  drivers/net/can/usb/peak_usb/pcan_usb_pro.c      |  1 +
> >  drivers/net/can/usb/ucan.c                       | 12 ++++++++++++
> >  drivers/net/can/usb/usb_8dev.c                   | 12 ++++++++++++
> >  drivers/net/can/vcan.c                           | 12 ++++++++++++
> >  drivers/net/can/vxcan.c                          | 12 ++++++++++++
> >  drivers/net/can/xilinx_can.c                     | 12 ++++++++++++
> >  39 files changed, 414 insertions(+)

(...)

> > diff --git a/drivers/net/can/slcan/slcan-core.c b/drivers/net/can/slcan/slcan-core.c
> > index d1562f9474c9..1b86001c85f8 100644
> > --- a/drivers/net/can/slcan/slcan-core.c
> > +++ b/drivers/net/can/slcan/slcan-core.c
> > @@ -46,6 +46,7 @@
> >  #include <linux/string.h>
> >  #include <linux/tty.h>
> >  #include <linux/errno.h>
> > +#include <linux/ethtool.h>
> >  #include <linux/netdevice.h>
> >  #include <linux/skbuff.h>
> >  #include <linux/rtnetlink.h>
> > @@ -790,6 +791,16 @@ static const struct net_device_ops slc_netdev_ops = {
> >         .ndo_change_mtu         = slcan_change_mtu,
> >  };
> >
> > +static void slcan_get_drvinfo(struct net_device *netdev,
> > +                             struct ethtool_drvinfo *drvinfo)
> > +{
> > +       strscpy(drvinfo->driver, DRV_NAME, sizeof(drvinfo->driver));
> > +}
> > +
>
> Please put the function inside the slcan-ethtool.c.
>
> > +static const struct ethtool_ops slcan_ethtool_ops = {
> > +       .get_drvinfo = slcan_get_drvinfo,
> > +};
> > +
>
> slcan_ethtool_ops is is already defined in slcan-ethtool.c
>
> >  /******************************************
> >   *  Routines looking at TTY side.
> >   ******************************************/
> > @@ -869,6 +880,7 @@ static struct slcan *slc_alloc(void)
> >
> >         snprintf(dev->name, sizeof(dev->name), DRV_NAME "%d", i);
> >         dev->netdev_ops = &slc_netdev_ops;
> > +       dev->ethtool_ops = &slcan_ethtool_ops;
> >         dev->base_addr  = i;
> >         slcan_set_ethtool_ops(dev);
>
> It already sets dev->ethtool_ops.

Indeed. I did not realise this. I was looking for an assignment on
dev->ethtool_ops and missed the call to slcan_set_ethtool_ops().

I am not convinced by the slcan_set_ethtool_ops(). It introduces a
function call for no specific reasons. Instead, I am thinking to just
export slcan_ethtool_ops like that:


diff --git a/drivers/net/can/slcan/slcan-core.c
b/drivers/net/can/slcan/slcan-core.c
index d4dbeb849432..c98567c711ae 100644
--- a/drivers/net/can/slcan/slcan-core.c
+++ b/drivers/net/can/slcan/slcan-core.c
@@ -868,8 +868,8 @@ static struct slcan *slc_alloc(void)

        snprintf(dev->name, sizeof(dev->name), "slcan%d", i);
        dev->netdev_ops = &slc_netdev_ops;
+       dev->ethtool_ops = &slcan_ethtool_ops;
        dev->base_addr  = i;
-       slcan_set_ethtool_ops(dev);
        sl = netdev_priv(dev);

        /* Initialize channel control data */
diff --git a/drivers/net/can/slcan/slcan-ethtool.c
b/drivers/net/can/slcan/slcan-ethtool.c
index bf0afdc4e49d..328ae1fb065b 100644
--- a/drivers/net/can/slcan/slcan-ethtool.c
+++ b/drivers/net/can/slcan/slcan-ethtool.c
@@ -52,14 +52,9 @@ static int slcan_get_sset_count(struct net_device
*netdev, int sset)
        }
 }

-static const struct ethtool_ops slcan_ethtool_ops = {
+const struct ethtool_ops slcan_ethtool_ops = {
        .get_strings = slcan_get_strings,
        .get_priv_flags = slcan_get_priv_flags,
        .set_priv_flags = slcan_set_priv_flags,
        .get_sset_count = slcan_get_sset_count,
 };
-
-void slcan_set_ethtool_ops(struct net_device *netdev)
-{
-       netdev->ethtool_ops = &slcan_ethtool_ops;
-}
diff --git a/drivers/net/can/slcan/slcan.h b/drivers/net/can/slcan/slcan.h
index d463c8d99e22..85cedf856db3 100644
--- a/drivers/net/can/slcan/slcan.h
+++ b/drivers/net/can/slcan/slcan.h
@@ -13,6 +13,7 @@

 bool slcan_err_rst_on_open(struct net_device *ndev);
 int slcan_enable_err_rst_on_open(struct net_device *ndev, bool on);
-void slcan_set_ethtool_ops(struct net_device *ndev);
+
+extern const struct ethtool_ops slcan_ethtool_ops;

 #endif /* _SLCAN_H */



Does it make sense?


Yours sincerely,
Vincent Mailhol

^ permalink raw reply related	[flat|nested] 92+ messages in thread

* Re: [PATCH v1 10/24] can: tree-wide: implement ethtool_ops::get_drvinfo()
  2022-07-26  8:42     ` Vincent MAILHOL
@ 2022-07-26  9:21       ` Dario Binacchi
  2022-07-26  9:59         ` Vincent MAILHOL
  0 siblings, 1 reply; 92+ messages in thread
From: Dario Binacchi @ 2022-07-26  9:21 UTC (permalink / raw)
  To: Vincent MAILHOL
  Cc: linux-can, Marc Kleine-Budde, Stephane Grosjean, Jimmy Assarsson,
	Oliver Hartkopp, Max Staudt

Hi Vincent,

On Tue, Jul 26, 2022 at 10:42 AM Vincent MAILHOL
<mailhol.vincent@wanadoo.fr> wrote:
>
> Hi Dario,
>
> On Tue. 26 Jul. 2022 at 16:41, Dario Binacchi
> <dario.binacchi@amarulasolutions.com> wrote:
> > Hi Vincent,
> >
> > On Mon, Jul 25, 2022 at 3:32 PM Vincent Mailhol
> > <mailhol.vincent@wanadoo.fr> wrote:
> > >
> > > For all CAN drivers, implement the get_drvinfo() function.
> > >
> > > After this patch, it is now possible to retrieve basic information by
> > > doing:
> > >
> > > | $ ethtool -i canX
> > >
> > > Signed-off-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
> > > ---
> > >  drivers/net/can/at91_can.c                       | 12 ++++++++++++
> > >  drivers/net/can/c_can/c_can_main.c               | 12 ++++++++++++
> > >  drivers/net/can/can327.c                         | 11 +++++++++++
> > >  drivers/net/can/cc770/cc770.c                    | 12 ++++++++++++
> > >  drivers/net/can/ctucanfd/ctucanfd_base.c         | 12 ++++++++++++
> > >  drivers/net/can/flexcan/flexcan-core.c           | 12 ++++++++++++
> > >  drivers/net/can/grcan.c                          | 12 ++++++++++++
> > >  drivers/net/can/ifi_canfd/ifi_canfd.c            | 12 ++++++++++++
> > >  drivers/net/can/janz-ican3.c                     | 12 ++++++++++++
> > >  drivers/net/can/kvaser_pciefd.c                  | 12 ++++++++++++
> > >  drivers/net/can/m_can/m_can.c                    | 12 ++++++++++++
> > >  drivers/net/can/mscan/mscan.c                    |  1 +
> > >  drivers/net/can/pch_can.c                        | 12 ++++++++++++
> > >  drivers/net/can/peak_canfd/peak_canfd.c          | 12 ++++++++++++
> > >  drivers/net/can/rcar/rcar_can.c                  | 12 ++++++++++++
> > >  drivers/net/can/rcar/rcar_canfd.c                | 12 ++++++++++++
> > >  drivers/net/can/sja1000/sja1000.c                | 12 ++++++++++++
> > >  drivers/net/can/slcan/slcan-core.c               | 12 ++++++++++++
> > >  drivers/net/can/softing/softing_main.c           | 12 ++++++++++++
> > >  drivers/net/can/spi/hi311x.c                     | 12 ++++++++++++
> > >  drivers/net/can/spi/mcp251x.c                    | 12 ++++++++++++
> > >  drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c   | 12 ++++++++++++
> > >  drivers/net/can/sun4i_can.c                      | 12 ++++++++++++
> > >  drivers/net/can/ti_hecc.c                        | 12 ++++++++++++
> > >  drivers/net/can/usb/ems_usb.c                    | 12 ++++++++++++
> > >  drivers/net/can/usb/esd_usb.c                    | 12 ++++++++++++
> > >  drivers/net/can/usb/etas_es58x/es58x_core.c      | 12 ++++++++++++
> > >  drivers/net/can/usb/gs_usb.c                     |  8 ++++++++
> > >  drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c | 12 ++++++++++++
> > >  drivers/net/can/usb/mcba_usb.c                   | 12 ++++++++++++
> > >  drivers/net/can/usb/peak_usb/pcan_usb_core.c     |  6 ++++++
> > >  drivers/net/can/usb/peak_usb/pcan_usb_core.h     |  2 ++
> > >  drivers/net/can/usb/peak_usb/pcan_usb_fd.c       |  1 +
> > >  drivers/net/can/usb/peak_usb/pcan_usb_pro.c      |  1 +
> > >  drivers/net/can/usb/ucan.c                       | 12 ++++++++++++
> > >  drivers/net/can/usb/usb_8dev.c                   | 12 ++++++++++++
> > >  drivers/net/can/vcan.c                           | 12 ++++++++++++
> > >  drivers/net/can/vxcan.c                          | 12 ++++++++++++
> > >  drivers/net/can/xilinx_can.c                     | 12 ++++++++++++
> > >  39 files changed, 414 insertions(+)
>
> (...)
>
> > > diff --git a/drivers/net/can/slcan/slcan-core.c b/drivers/net/can/slcan/slcan-core.c
> > > index d1562f9474c9..1b86001c85f8 100644
> > > --- a/drivers/net/can/slcan/slcan-core.c
> > > +++ b/drivers/net/can/slcan/slcan-core.c
> > > @@ -46,6 +46,7 @@
> > >  #include <linux/string.h>
> > >  #include <linux/tty.h>
> > >  #include <linux/errno.h>
> > > +#include <linux/ethtool.h>
> > >  #include <linux/netdevice.h>
> > >  #include <linux/skbuff.h>
> > >  #include <linux/rtnetlink.h>
> > > @@ -790,6 +791,16 @@ static const struct net_device_ops slc_netdev_ops = {
> > >         .ndo_change_mtu         = slcan_change_mtu,
> > >  };
> > >
> > > +static void slcan_get_drvinfo(struct net_device *netdev,
> > > +                             struct ethtool_drvinfo *drvinfo)
> > > +{
> > > +       strscpy(drvinfo->driver, DRV_NAME, sizeof(drvinfo->driver));
> > > +}
> > > +
> >
> > Please put the function inside the slcan-ethtool.c.
> >
> > > +static const struct ethtool_ops slcan_ethtool_ops = {
> > > +       .get_drvinfo = slcan_get_drvinfo,
> > > +};
> > > +
> >
> > slcan_ethtool_ops is is already defined in slcan-ethtool.c
> >
> > >  /******************************************
> > >   *  Routines looking at TTY side.
> > >   ******************************************/
> > > @@ -869,6 +880,7 @@ static struct slcan *slc_alloc(void)
> > >
> > >         snprintf(dev->name, sizeof(dev->name), DRV_NAME "%d", i);
> > >         dev->netdev_ops = &slc_netdev_ops;
> > > +       dev->ethtool_ops = &slcan_ethtool_ops;
> > >         dev->base_addr  = i;
> > >         slcan_set_ethtool_ops(dev);
> >
> > It already sets dev->ethtool_ops.
>
> Indeed. I did not realise this. I was looking for an assignment on
> dev->ethtool_ops and missed the call to slcan_set_ethtool_ops().
>
> I am not convinced by the slcan_set_ethtool_ops(). It introduces a
> function call for no specific reasons. Instead, I am thinking to just
> export slcan_ethtool_ops like that:
>
>
> diff --git a/drivers/net/can/slcan/slcan-core.c
> b/drivers/net/can/slcan/slcan-core.c
> index d4dbeb849432..c98567c711ae 100644
> --- a/drivers/net/can/slcan/slcan-core.c
> +++ b/drivers/net/can/slcan/slcan-core.c
> @@ -868,8 +868,8 @@ static struct slcan *slc_alloc(void)
>
>         snprintf(dev->name, sizeof(dev->name), "slcan%d", i);
>         dev->netdev_ops = &slc_netdev_ops;
> +       dev->ethtool_ops = &slcan_ethtool_ops;
>         dev->base_addr  = i;
> -       slcan_set_ethtool_ops(dev);
>         sl = netdev_priv(dev);
>
>         /* Initialize channel control data */
> diff --git a/drivers/net/can/slcan/slcan-ethtool.c
> b/drivers/net/can/slcan/slcan-ethtool.c
> index bf0afdc4e49d..328ae1fb065b 100644
> --- a/drivers/net/can/slcan/slcan-ethtool.c
> +++ b/drivers/net/can/slcan/slcan-ethtool.c
> @@ -52,14 +52,9 @@ static int slcan_get_sset_count(struct net_device
> *netdev, int sset)
>         }
>  }
>
> -static const struct ethtool_ops slcan_ethtool_ops = {
> +const struct ethtool_ops slcan_ethtool_ops = {
>         .get_strings = slcan_get_strings,
>         .get_priv_flags = slcan_get_priv_flags,
>         .set_priv_flags = slcan_set_priv_flags,
>         .get_sset_count = slcan_get_sset_count,
>  };
> -
> -void slcan_set_ethtool_ops(struct net_device *netdev)
> -{
> -       netdev->ethtool_ops = &slcan_ethtool_ops;
> -}
> diff --git a/drivers/net/can/slcan/slcan.h b/drivers/net/can/slcan/slcan.h
> index d463c8d99e22..85cedf856db3 100644
> --- a/drivers/net/can/slcan/slcan.h
> +++ b/drivers/net/can/slcan/slcan.h
> @@ -13,6 +13,7 @@
>
>  bool slcan_err_rst_on_open(struct net_device *ndev);
>  int slcan_enable_err_rst_on_open(struct net_device *ndev, bool on);
> -void slcan_set_ethtool_ops(struct net_device *ndev);
> +
> +extern const struct ethtool_ops slcan_ethtool_ops;
>
>  #endif /* _SLCAN_H */
>
>
>
> Does it make sense?
>
>

I have already used this scheme in the c_can driver. I used this
scheme because I saw that it was used a lot
(git grep set_ethtool_ops) in the kernel. By doing so you can define
slcan_ethtool_ops as a static variable
and if possible I prefer to export functions rather than data. But it
can be a matter of taste.

Thanks and regards,
Dario

> Yours sincerely,
> Vincent Mailhol



-- 

Dario Binacchi

Embedded Linux Developer

dario.binacchi@amarulasolutions.com

__________________________________


Amarula Solutions SRL

Via Le Canevare 30, 31100 Treviso, Veneto, IT

T. +39 042 243 5310
info@amarulasolutions.com

www.amarulasolutions.com

^ permalink raw reply	[flat|nested] 92+ messages in thread

* Re: [PATCH v1 10/24] can: tree-wide: implement ethtool_ops::get_drvinfo()
  2022-07-26  9:21       ` Dario Binacchi
@ 2022-07-26  9:59         ` Vincent MAILHOL
  2022-07-27  8:19           ` Marc Kleine-Budde
  0 siblings, 1 reply; 92+ messages in thread
From: Vincent MAILHOL @ 2022-07-26  9:59 UTC (permalink / raw)
  To: Dario Binacchi
  Cc: linux-can, Marc Kleine-Budde, Stephane Grosjean, Jimmy Assarsson,
	Oliver Hartkopp, Max Staudt

On Tue. 26 Jul. 2022 at 18:26, Dario Binacchi
<dario.binacchi@amarulasolutions.com> wrote:
> Hi Vincent,
>
> On Tue, Jul 26, 2022 at 10:42 AM Vincent MAILHOL
> <mailhol.vincent@wanadoo.fr> wrote:
> >
> > Hi Dario,
> >
> > On Tue. 26 Jul. 2022 at 16:41, Dario Binacchi
> > <dario.binacchi@amarulasolutions.com> wrote:
> > > Hi Vincent,
> > >
> > > On Mon, Jul 25, 2022 at 3:32 PM Vincent Mailhol
> > > <mailhol.vincent@wanadoo.fr> wrote:
> > > >
> > > > For all CAN drivers, implement the get_drvinfo() function.
> > > >
> > > > After this patch, it is now possible to retrieve basic information by
> > > > doing:
> > > >
> > > > | $ ethtool -i canX
> > > >
> > > > Signed-off-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
> > > > ---
> > > >  drivers/net/can/at91_can.c                       | 12 ++++++++++++
> > > >  drivers/net/can/c_can/c_can_main.c               | 12 ++++++++++++
> > > >  drivers/net/can/can327.c                         | 11 +++++++++++
> > > >  drivers/net/can/cc770/cc770.c                    | 12 ++++++++++++
> > > >  drivers/net/can/ctucanfd/ctucanfd_base.c         | 12 ++++++++++++
> > > >  drivers/net/can/flexcan/flexcan-core.c           | 12 ++++++++++++
> > > >  drivers/net/can/grcan.c                          | 12 ++++++++++++
> > > >  drivers/net/can/ifi_canfd/ifi_canfd.c            | 12 ++++++++++++
> > > >  drivers/net/can/janz-ican3.c                     | 12 ++++++++++++
> > > >  drivers/net/can/kvaser_pciefd.c                  | 12 ++++++++++++
> > > >  drivers/net/can/m_can/m_can.c                    | 12 ++++++++++++
> > > >  drivers/net/can/mscan/mscan.c                    |  1 +
> > > >  drivers/net/can/pch_can.c                        | 12 ++++++++++++
> > > >  drivers/net/can/peak_canfd/peak_canfd.c          | 12 ++++++++++++
> > > >  drivers/net/can/rcar/rcar_can.c                  | 12 ++++++++++++
> > > >  drivers/net/can/rcar/rcar_canfd.c                | 12 ++++++++++++
> > > >  drivers/net/can/sja1000/sja1000.c                | 12 ++++++++++++
> > > >  drivers/net/can/slcan/slcan-core.c               | 12 ++++++++++++
> > > >  drivers/net/can/softing/softing_main.c           | 12 ++++++++++++
> > > >  drivers/net/can/spi/hi311x.c                     | 12 ++++++++++++
> > > >  drivers/net/can/spi/mcp251x.c                    | 12 ++++++++++++
> > > >  drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c   | 12 ++++++++++++
> > > >  drivers/net/can/sun4i_can.c                      | 12 ++++++++++++
> > > >  drivers/net/can/ti_hecc.c                        | 12 ++++++++++++
> > > >  drivers/net/can/usb/ems_usb.c                    | 12 ++++++++++++
> > > >  drivers/net/can/usb/esd_usb.c                    | 12 ++++++++++++
> > > >  drivers/net/can/usb/etas_es58x/es58x_core.c      | 12 ++++++++++++
> > > >  drivers/net/can/usb/gs_usb.c                     |  8 ++++++++
> > > >  drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c | 12 ++++++++++++
> > > >  drivers/net/can/usb/mcba_usb.c                   | 12 ++++++++++++
> > > >  drivers/net/can/usb/peak_usb/pcan_usb_core.c     |  6 ++++++
> > > >  drivers/net/can/usb/peak_usb/pcan_usb_core.h     |  2 ++
> > > >  drivers/net/can/usb/peak_usb/pcan_usb_fd.c       |  1 +
> > > >  drivers/net/can/usb/peak_usb/pcan_usb_pro.c      |  1 +
> > > >  drivers/net/can/usb/ucan.c                       | 12 ++++++++++++
> > > >  drivers/net/can/usb/usb_8dev.c                   | 12 ++++++++++++
> > > >  drivers/net/can/vcan.c                           | 12 ++++++++++++
> > > >  drivers/net/can/vxcan.c                          | 12 ++++++++++++
> > > >  drivers/net/can/xilinx_can.c                     | 12 ++++++++++++
> > > >  39 files changed, 414 insertions(+)
> >
> > (...)
> >
> > > > diff --git a/drivers/net/can/slcan/slcan-core.c b/drivers/net/can/slcan/slcan-core.c
> > > > index d1562f9474c9..1b86001c85f8 100644
> > > > --- a/drivers/net/can/slcan/slcan-core.c
> > > > +++ b/drivers/net/can/slcan/slcan-core.c
> > > > @@ -46,6 +46,7 @@
> > > >  #include <linux/string.h>
> > > >  #include <linux/tty.h>
> > > >  #include <linux/errno.h>
> > > > +#include <linux/ethtool.h>
> > > >  #include <linux/netdevice.h>
> > > >  #include <linux/skbuff.h>
> > > >  #include <linux/rtnetlink.h>
> > > > @@ -790,6 +791,16 @@ static const struct net_device_ops slc_netdev_ops = {
> > > >         .ndo_change_mtu         = slcan_change_mtu,
> > > >  };
> > > >
> > > > +static void slcan_get_drvinfo(struct net_device *netdev,
> > > > +                             struct ethtool_drvinfo *drvinfo)
> > > > +{
> > > > +       strscpy(drvinfo->driver, DRV_NAME, sizeof(drvinfo->driver));
> > > > +}
> > > > +
> > >
> > > Please put the function inside the slcan-ethtool.c.
> > >
> > > > +static const struct ethtool_ops slcan_ethtool_ops = {
> > > > +       .get_drvinfo = slcan_get_drvinfo,
> > > > +};
> > > > +
> > >
> > > slcan_ethtool_ops is is already defined in slcan-ethtool.c
> > >
> > > >  /******************************************
> > > >   *  Routines looking at TTY side.
> > > >   ******************************************/
> > > > @@ -869,6 +880,7 @@ static struct slcan *slc_alloc(void)
> > > >
> > > >         snprintf(dev->name, sizeof(dev->name), DRV_NAME "%d", i);
> > > >         dev->netdev_ops = &slc_netdev_ops;
> > > > +       dev->ethtool_ops = &slcan_ethtool_ops;
> > > >         dev->base_addr  = i;
> > > >         slcan_set_ethtool_ops(dev);
> > >
> > > It already sets dev->ethtool_ops.
> >
> > Indeed. I did not realise this. I was looking for an assignment on
> > dev->ethtool_ops and missed the call to slcan_set_ethtool_ops().
> >
> > I am not convinced by the slcan_set_ethtool_ops(). It introduces a
> > function call for no specific reasons. Instead, I am thinking to just
> > export slcan_ethtool_ops like that:
> >
> >
> > diff --git a/drivers/net/can/slcan/slcan-core.c
> > b/drivers/net/can/slcan/slcan-core.c
> > index d4dbeb849432..c98567c711ae 100644
> > --- a/drivers/net/can/slcan/slcan-core.c
> > +++ b/drivers/net/can/slcan/slcan-core.c
> > @@ -868,8 +868,8 @@ static struct slcan *slc_alloc(void)
> >
> >         snprintf(dev->name, sizeof(dev->name), "slcan%d", i);
> >         dev->netdev_ops = &slc_netdev_ops;
> > +       dev->ethtool_ops = &slcan_ethtool_ops;
> >         dev->base_addr  = i;
> > -       slcan_set_ethtool_ops(dev);
> >         sl = netdev_priv(dev);
> >
> >         /* Initialize channel control data */
> > diff --git a/drivers/net/can/slcan/slcan-ethtool.c
> > b/drivers/net/can/slcan/slcan-ethtool.c
> > index bf0afdc4e49d..328ae1fb065b 100644
> > --- a/drivers/net/can/slcan/slcan-ethtool.c
> > +++ b/drivers/net/can/slcan/slcan-ethtool.c
> > @@ -52,14 +52,9 @@ static int slcan_get_sset_count(struct net_device
> > *netdev, int sset)
> >         }
> >  }
> >
> > -static const struct ethtool_ops slcan_ethtool_ops = {
> > +const struct ethtool_ops slcan_ethtool_ops = {
> >         .get_strings = slcan_get_strings,
> >         .get_priv_flags = slcan_get_priv_flags,
> >         .set_priv_flags = slcan_set_priv_flags,
> >         .get_sset_count = slcan_get_sset_count,
> >  };
> > -
> > -void slcan_set_ethtool_ops(struct net_device *netdev)
> > -{
> > -       netdev->ethtool_ops = &slcan_ethtool_ops;
> > -}
> > diff --git a/drivers/net/can/slcan/slcan.h b/drivers/net/can/slcan/slcan.h
> > index d463c8d99e22..85cedf856db3 100644
> > --- a/drivers/net/can/slcan/slcan.h
> > +++ b/drivers/net/can/slcan/slcan.h
> > @@ -13,6 +13,7 @@
> >
> >  bool slcan_err_rst_on_open(struct net_device *ndev);
> >  int slcan_enable_err_rst_on_open(struct net_device *ndev, bool on);
> > -void slcan_set_ethtool_ops(struct net_device *ndev);
> > +
> > +extern const struct ethtool_ops slcan_ethtool_ops;
> >
> >  #endif /* _SLCAN_H */
> >
> >
> >
> > Does it make sense?
> >
> >
>
> I have already used this scheme in the c_can driver. I used this
> scheme because I saw that it was used a lot
> (git grep set_ethtool_ops) in the kernel.

| $ git grep "void .*_set_ethtool_ops.*;" | wc -l
| 46
| $ git grep "extern const struct ethtool_ops" | wc -l
| 43

I did not know it was a good practice, but you are right, both schemes
are roughly as popular (with yours slightly more popular by a small
margin).

> By doing so you can define
> slcan_ethtool_ops as a static variable
> and if possible I prefer to export functions rather than data. But it
> can be a matter of taste.

My taste is to export the data (to remove a function call), but as the
maintainer, your opinion should prevail here.

And thanks for the explanation.


I will also fix those two drivers:

| $ git grep "void .*_set_ethtool_ops.*;" drivers/net/can/
| drivers/net/can/c_can/c_can.h:void c_can_set_ethtool_ops(struct
net_device *dev);
| drivers/net/can/flexcan/flexcan.h:void
flexcan_set_ethtool_ops(struct net_device *dev);


Yours sincerely,
Vincent Mailhol

^ permalink raw reply	[flat|nested] 92+ messages in thread

* [PATCH v3 00/14]
  2022-07-25 13:31 [PATCH v1 00/24] can: add ethtool support and reporting of timestamping capabilities Vincent Mailhol
                   ` (25 preceding siblings ...)
  2022-07-25 15:53 ` [PATCH v2 00/14] " Vincent Mailhol
@ 2022-07-26 10:24 ` Vincent Mailhol
  2022-07-26 10:24   ` [PATCH v3 01/14] can: can327: add software tx timestamps Vincent Mailhol
                     ` (13 more replies)
  2022-07-27 10:16 ` [PATCH v4 00/14] can: add ethtool support and reporting of timestamping capabilities Vincent Mailhol
  27 siblings, 14 replies; 92+ messages in thread
From: Vincent Mailhol @ 2022-07-26 10:24 UTC (permalink / raw)
  To: linux-can, Marc Kleine-Budde
  Cc: Stephane Grosjean, Jimmy Assarsson, Oliver Hartkopp,
	Dario Binacchi, Max Staudt, Vincent Mailhol

This series revolves around ethtool and timestamping. Its ultimate
goal is that the timestamping implementation within socketCAN meets
the specification of other network drivers in the kernel. This way,
tcpdump or other tools derived from libpcap can be used to do
timestamping on CAN devices.

* Example on a device with hardware timestamp support *

Before this series:
| # tcpdump -j adapter_unsynced -i can0
| tcpdump: WARNING: When trying to set timestamp type
| 'adapter_unsynced' on can0: That type of time stamp is not supported
| by that device

After applying this series, the warning disappears and tcpdump can be
used to get RX hardware timestamps.


This series is articulated in three major parts.

* Part 1: Add TX software timestamps and report the software
  timestamping capabilities through ethtool.

All the drivers using can_put_echo_skb() already support TX software
timestamps. However, the five drivers not using this function (namely
can327, janz-ican3, slcan, vcan and vxcan) lack such support. Patch 1
to 4 adds this support.  Finally, patch 5 advertises the timesamping
capabilities of all drivers which do not support hardware timestamps.


* Part 2: add TX hardware timestapms

This part is a single patch. In SocetCAN TX hardware is equal to the
RX hardware timestamps of the corresponding loopback frame. Reuse the
TX hardware timestamp to populate the RX hardware timestamp. While the
need of this feature can be debatable, we implement it here so that
generic timestamping tools which are agnostic of the specificity of
SocketCAN can still obtain the value. For example, tcpdump expects for
both TX and RX hardware timestamps to be supported in order to do:
| # tcpdump -j adapter_unsynced -i canX


* Part 3: report the hardware timestamping capabilities and implement
  the hardware timestamps ioctls.

The kernel documentation specifies in [1] that, for the drivers which
support hardware timestamping, SIOCSHWTSTAMP ioctl must be supported
and that SIOCGHWTSTAMP ioctl should be supported. Currently, none of
the CAN drivers do so. This is a gap.

Furthermore, even if not specified, the tools based on libpcap
(e.g. tcpdump) also expect ethtool_ops::get_ts_info to be implemented.

This last part first adds some generic implementation of
net_device_ops::ndo_eth_ioctl and ethtool_ops::get_ts_info which can
be used by the drivers with hardware timestamping capabilities.

It then uses those generic functions to add ioctl and reporting
functionalities to the drivers with hardware timestamping support
(namely: mcp251xfd, etas_es58x, kvaser_{pciefd,usb}, peak_{canfd,usb})


[1] Kernel doc: Timestamping, section 3.1 "Hardware Timestamping
Implementation: Device Drivers"
Link: https://docs.kernel.org/networking/timestamping.html#hardware-timestamping-implementation-device-drivers


* Testing *

I also developed a tool to test all the different timestamps. For
those who would also like to test it, please have a look at:
https://lore.kernel.org/linux-can/20220725134345.432367-1-mailhol.vincent@wanadoo.fr/T/


* Changelog *

v2 -> v3:

  * The c_can, flexcan, mcp251xfd and the slcan drivers already
    declared a struct ethtool_ops. Do not declare again the same
    structure and instead populate the .get_ts_info() field of the
    existing structures.

v1 -> v2:

  * First series had a patch to implement
    ethtool_ops::get_drvinfo. This proved to be useless. This patch
    was removed and all the clean-up patches made in preparation of
    that one were moved to a separate series:

    https://lore.kernel.org/linux-can/20220725153124.467061-1-mailhol.vincent@wanadoo.fr/T/#u

Vincent Mailhol (14):
  can: can327: add software tx timestamps
  can: janz-ican3: add software tx timestamp
  can: slcan: add software tx timestamps
  can: v(x)can: add software tx timestamps
  can: tree-wide: advertise software timestamping capabilities
  can: dev: add hardware TX timestamp
  can: dev: add generic function can_ethtool_op_get_ts_info_hwts()
  can: dev: add generic function can_eth_ioctl_hwts()
  can: mcp251xfd: advertise timestamping capabilities and add ioctl
    support
  can: etas_es58x: advertise timestamping capabilities and add ioctl
    support
  can: kvaser_pciefd: advertise timestamping capabilities and add ioctl
    support
  can: kvaser_usb: advertise timestamping capabilities and add ioctl
    support
  can: peak_canfd: advertise timestamping capabilities and add ioctl
    support
  can: peak_usb: advertise timestamping capabilities and add ioctl
    support

 drivers/net/can/at91_can.c                    |  6 +++
 drivers/net/can/c_can/c_can_ethtool.c         |  1 +
 drivers/net/can/can327.c                      |  7 +++
 drivers/net/can/cc770/cc770.c                 |  6 +++
 drivers/net/can/ctucanfd/ctucanfd_base.c      |  6 +++
 drivers/net/can/dev/dev.c                     | 50 +++++++++++++++++++
 drivers/net/can/dev/skb.c                     |  6 +++
 drivers/net/can/flexcan/flexcan-ethtool.c     |  1 +
 drivers/net/can/grcan.c                       |  6 +++
 drivers/net/can/ifi_canfd/ifi_canfd.c         |  6 +++
 drivers/net/can/janz-ican3.c                  |  8 +++
 drivers/net/can/kvaser_pciefd.c               |  7 +++
 drivers/net/can/m_can/m_can.c                 |  6 +++
 drivers/net/can/mscan/mscan.c                 |  1 +
 drivers/net/can/pch_can.c                     |  6 +++
 drivers/net/can/peak_canfd/peak_canfd.c       |  7 +++
 drivers/net/can/rcar/rcar_can.c               |  6 +++
 drivers/net/can/rcar/rcar_canfd.c             |  6 +++
 drivers/net/can/sja1000/sja1000.c             |  6 +++
 drivers/net/can/slcan/slcan-core.c            |  2 +
 drivers/net/can/slcan/slcan-ethtool.c         |  1 +
 drivers/net/can/softing/softing_main.c        |  6 +++
 drivers/net/can/spi/hi311x.c                  |  6 +++
 drivers/net/can/spi/mcp251x.c                 |  6 +++
 .../net/can/spi/mcp251xfd/mcp251xfd-core.c    |  1 +
 .../net/can/spi/mcp251xfd/mcp251xfd-ethtool.c |  1 +
 drivers/net/can/sun4i_can.c                   |  6 +++
 drivers/net/can/ti_hecc.c                     |  6 +++
 drivers/net/can/usb/ems_usb.c                 |  6 +++
 drivers/net/can/usb/esd_usb.c                 |  6 +++
 drivers/net/can/usb/etas_es58x/es58x_core.c   |  9 +++-
 drivers/net/can/usb/gs_usb.c                  |  2 +
 drivers/net/can/usb/kvaser_usb/kvaser_usb.h   |  1 +
 .../net/can/usb/kvaser_usb/kvaser_usb_core.c  | 27 +++++++++-
 drivers/net/can/usb/mcba_usb.c                |  6 +++
 drivers/net/can/usb/peak_usb/pcan_usb.c       |  2 +
 drivers/net/can/usb/peak_usb/pcan_usb_core.c  | 12 ++++-
 drivers/net/can/usb/peak_usb/pcan_usb_core.h  |  4 ++
 drivers/net/can/usb/peak_usb/pcan_usb_fd.c    |  2 +
 drivers/net/can/usb/peak_usb/pcan_usb_pro.c   |  2 +
 drivers/net/can/usb/ucan.c                    |  6 +++
 drivers/net/can/usb/usb_8dev.c                |  6 +++
 drivers/net/can/vcan.c                        |  8 +++
 drivers/net/can/vxcan.c                       |  8 +++
 drivers/net/can/xilinx_can.c                  |  6 +++
 include/linux/can/dev.h                       |  4 ++
 46 files changed, 295 insertions(+), 5 deletions(-)

-- 
2.35.1


^ permalink raw reply	[flat|nested] 92+ messages in thread

* [PATCH v3 01/14] can: can327: add software tx timestamps
  2022-07-26 10:24 ` [PATCH v3 00/14] Vincent Mailhol
@ 2022-07-26 10:24   ` Vincent Mailhol
  2022-07-26 10:24   ` [PATCH v3 02/14] can: janz-ican3: add software tx timestamp Vincent Mailhol
                     ` (12 subsequent siblings)
  13 siblings, 0 replies; 92+ messages in thread
From: Vincent Mailhol @ 2022-07-26 10:24 UTC (permalink / raw)
  To: linux-can, Marc Kleine-Budde
  Cc: Stephane Grosjean, Jimmy Assarsson, Oliver Hartkopp,
	Dario Binacchi, Max Staudt, Vincent Mailhol

TX timestamps were added to the can_put_echo_skb() function of can_dev
modules in [1]. However, can327 does not rely on that function and as
such does not offer TX timestamping.

Add a call to skb_tx_timestamp() in the can327_netdev_start_xmit()
function so that the module now supports TX software timestamps.

[1] commit 741b91f1b0ea ("can: dev: can_put_echo_skb(): add software
tx timestamps")
Link: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=741b91f1b0ea34f00f6a7d4539b767c409291fcf

Signed-off-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
---
 drivers/net/can/can327.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/net/can/can327.c b/drivers/net/can/can327.c
index 5da7778d92dc..88718d0cc569 100644
--- a/drivers/net/can/can327.c
+++ b/drivers/net/can/can327.c
@@ -836,6 +836,8 @@ static netdev_tx_t can327_netdev_start_xmit(struct sk_buff *skb,
 	dev->stats.tx_packets++;
 	dev->stats.tx_bytes += frame->can_id & CAN_RTR_FLAG ? 0 : frame->len;
 
+	skb_tx_timestamp(skb);
+
 out:
 	kfree_skb(skb);
 	return NETDEV_TX_OK;
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 92+ messages in thread

* [PATCH v3 02/14] can: janz-ican3: add software tx timestamp
  2022-07-26 10:24 ` [PATCH v3 00/14] Vincent Mailhol
  2022-07-26 10:24   ` [PATCH v3 01/14] can: can327: add software tx timestamps Vincent Mailhol
@ 2022-07-26 10:24   ` Vincent Mailhol
  2022-07-26 10:24   ` [PATCH v3 03/14] can: slcan: add software tx timestamps Vincent Mailhol
                     ` (11 subsequent siblings)
  13 siblings, 0 replies; 92+ messages in thread
From: Vincent Mailhol @ 2022-07-26 10:24 UTC (permalink / raw)
  To: linux-can, Marc Kleine-Budde
  Cc: Stephane Grosjean, Jimmy Assarsson, Oliver Hartkopp,
	Dario Binacchi, Max Staudt, Vincent Mailhol

TX timestamps were added to the can_put_echo_skb() function of can_dev
modules in [1]. However, janz-ican3 does not rely on that function but
instead implements its own echo_skb logic. As such it does not offer
TX timestamping.

Add a call to skb_tx_timestamp() in the ican3_put_echo_skb() function
so that the module now supports TX software timestamps.

[1] commit 741b91f1b0ea ("can: dev: can_put_echo_skb(): add software
tx timestamps")
Link: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=741b91f1b0ea34f00f6a7d4539b767c409291fcf

Signed-off-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
---
 drivers/net/can/janz-ican3.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/net/can/janz-ican3.c b/drivers/net/can/janz-ican3.c
index ccb5c5405224..78d9190a4220 100644
--- a/drivers/net/can/janz-ican3.c
+++ b/drivers/net/can/janz-ican3.c
@@ -1277,6 +1277,8 @@ static void ican3_put_echo_skb(struct ican3_dev *mod, struct sk_buff *skb)
 	if (!skb)
 		return;
 
+	skb_tx_timestamp(skb);
+
 	/* save this skb for tx interrupt echo handling */
 	skb_queue_tail(&mod->echoq, skb);
 }
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 92+ messages in thread

* [PATCH v3 03/14] can: slcan: add software tx timestamps
  2022-07-26 10:24 ` [PATCH v3 00/14] Vincent Mailhol
  2022-07-26 10:24   ` [PATCH v3 01/14] can: can327: add software tx timestamps Vincent Mailhol
  2022-07-26 10:24   ` [PATCH v3 02/14] can: janz-ican3: add software tx timestamp Vincent Mailhol
@ 2022-07-26 10:24   ` Vincent Mailhol
  2022-07-26 10:24   ` [PATCH v3 04/14] can: v(x)can: " Vincent Mailhol
                     ` (10 subsequent siblings)
  13 siblings, 0 replies; 92+ messages in thread
From: Vincent Mailhol @ 2022-07-26 10:24 UTC (permalink / raw)
  To: linux-can, Marc Kleine-Budde
  Cc: Stephane Grosjean, Jimmy Assarsson, Oliver Hartkopp,
	Dario Binacchi, Max Staudt, Vincent Mailhol

TX timestamps were added to the can_put_echo_skb() function of can_dev
modules in [1]. However, slcan does not rely on that function and as
such does not offer TX timestamping.

Add a call to skb_tx_timestamp() in the slc_xmit() function so that
the module now supports TX software timestamps.

[1] commit 741b91f1b0ea ("can: dev: can_put_echo_skb(): add software
tx timestamps")
Link: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=741b91f1b0ea34f00f6a7d4539b767c409291fcf

CC: Dario Binacchi <dario.binacchi@amarulasolutions.com>
Signed-off-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
---
 drivers/net/can/slcan/slcan-core.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/net/can/slcan/slcan-core.c b/drivers/net/can/slcan/slcan-core.c
index dc28e715bbe1..d4dbeb849432 100644
--- a/drivers/net/can/slcan/slcan-core.c
+++ b/drivers/net/can/slcan/slcan-core.c
@@ -626,6 +626,8 @@ static netdev_tx_t slc_xmit(struct sk_buff *skb, struct net_device *dev)
 	slc_encaps(sl, (struct can_frame *)skb->data); /* encaps & send */
 	spin_unlock(&sl->lock);
 
+	skb_tx_timestamp(skb);
+
 out:
 	kfree_skb(skb);
 	return NETDEV_TX_OK;
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 92+ messages in thread

* [PATCH v3 04/14] can: v(x)can: add software tx timestamps
  2022-07-26 10:24 ` [PATCH v3 00/14] Vincent Mailhol
                     ` (2 preceding siblings ...)
  2022-07-26 10:24   ` [PATCH v3 03/14] can: slcan: add software tx timestamps Vincent Mailhol
@ 2022-07-26 10:24   ` Vincent Mailhol
  2022-07-26 10:24   ` [PATCH v3 05/14] can: tree-wide: advertise software timestamping capabilities Vincent Mailhol
                     ` (9 subsequent siblings)
  13 siblings, 0 replies; 92+ messages in thread
From: Vincent Mailhol @ 2022-07-26 10:24 UTC (permalink / raw)
  To: linux-can, Marc Kleine-Budde
  Cc: Stephane Grosjean, Jimmy Assarsson, Oliver Hartkopp,
	Dario Binacchi, Max Staudt, Vincent Mailhol

TX timestamps were added to the can_put_echo_skb() function of can_dev
modules in [1]. However, vcan and vxcan do not rely on that function
and as such do not offer TX timestamping.

While it could be arguable whether TX timestamps are really needed for
virtual interfaces, we prefer to still add it so that all CAN dirvers,
without exception supports the TX software timestamps.

Add a call to skb_tx_timestamp() in the vcan_tx() and vxcan_xmit()
functions so that the modules now support TX software timestamps.

[1] commit 741b91f1b0ea ("can: dev: can_put_echo_skb(): add software
tx timestamps")
Link: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=741b91f1b0ea34f00f6a7d4539b767c409291fcf

Signed-off-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
---
 drivers/net/can/vcan.c  | 2 ++
 drivers/net/can/vxcan.c | 2 ++
 2 files changed, 4 insertions(+)

diff --git a/drivers/net/can/vcan.c b/drivers/net/can/vcan.c
index a15619d883ec..4a363cfcf97c 100644
--- a/drivers/net/can/vcan.c
+++ b/drivers/net/can/vcan.c
@@ -99,6 +99,8 @@ static netdev_tx_t vcan_tx(struct sk_buff *skb, struct net_device *dev)
 	/* set flag whether this packet has to be looped back */
 	loop = skb->pkt_type == PACKET_LOOPBACK;
 
+	skb_tx_timestamp(skb);
+
 	if (!echo) {
 		/* no echo handling available inside this driver */
 		if (loop) {
diff --git a/drivers/net/can/vxcan.c b/drivers/net/can/vxcan.c
index 577a80300514..61b6eca383f8 100644
--- a/drivers/net/can/vxcan.c
+++ b/drivers/net/can/vxcan.c
@@ -53,6 +53,8 @@ static netdev_tx_t vxcan_xmit(struct sk_buff *oskb, struct net_device *dev)
 		goto out_unlock;
 	}
 
+	skb_tx_timestamp(oskb);
+
 	skb = skb_clone(oskb, GFP_ATOMIC);
 	if (skb) {
 		consume_skb(oskb);
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 92+ messages in thread

* [PATCH v3 05/14] can: tree-wide: advertise software timestamping capabilities
  2022-07-26 10:24 ` [PATCH v3 00/14] Vincent Mailhol
                     ` (3 preceding siblings ...)
  2022-07-26 10:24   ` [PATCH v3 04/14] can: v(x)can: " Vincent Mailhol
@ 2022-07-26 10:24   ` Vincent Mailhol
  2022-07-26 10:24   ` [PATCH v3 06/14] can: dev: add hardware TX timestamp Vincent Mailhol
                     ` (8 subsequent siblings)
  13 siblings, 0 replies; 92+ messages in thread
From: Vincent Mailhol @ 2022-07-26 10:24 UTC (permalink / raw)
  To: linux-can, Marc Kleine-Budde
  Cc: Stephane Grosjean, Jimmy Assarsson, Oliver Hartkopp,
	Dario Binacchi, Max Staudt, Vincent Mailhol

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 timespamping will be migrated
in separate patches.

Signed-off-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
---
 drivers/net/can/at91_can.c                | 6 ++++++
 drivers/net/can/c_can/c_can_ethtool.c     | 1 +
 drivers/net/can/can327.c                  | 5 +++++
 drivers/net/can/cc770/cc770.c             | 6 ++++++
 drivers/net/can/ctucanfd/ctucanfd_base.c  | 6 ++++++
 drivers/net/can/flexcan/flexcan-ethtool.c | 1 +
 drivers/net/can/grcan.c                   | 6 ++++++
 drivers/net/can/ifi_canfd/ifi_canfd.c     | 6 ++++++
 drivers/net/can/janz-ican3.c              | 6 ++++++
 drivers/net/can/m_can/m_can.c             | 6 ++++++
 drivers/net/can/mscan/mscan.c             | 1 +
 drivers/net/can/pch_can.c                 | 6 ++++++
 drivers/net/can/rcar/rcar_can.c           | 6 ++++++
 drivers/net/can/rcar/rcar_canfd.c         | 6 ++++++
 drivers/net/can/sja1000/sja1000.c         | 6 ++++++
 drivers/net/can/slcan/slcan-ethtool.c     | 1 +
 drivers/net/can/softing/softing_main.c    | 6 ++++++
 drivers/net/can/spi/hi311x.c              | 6 ++++++
 drivers/net/can/spi/mcp251x.c             | 6 ++++++
 drivers/net/can/sun4i_can.c               | 6 ++++++
 drivers/net/can/ti_hecc.c                 | 6 ++++++
 drivers/net/can/usb/ems_usb.c             | 6 ++++++
 drivers/net/can/usb/esd_usb.c             | 6 ++++++
 drivers/net/can/usb/gs_usb.c              | 2 ++
 drivers/net/can/usb/mcba_usb.c            | 6 ++++++
 drivers/net/can/usb/ucan.c                | 6 ++++++
 drivers/net/can/usb/usb_8dev.c            | 6 ++++++
 drivers/net/can/vcan.c                    | 6 ++++++
 drivers/net/can/vxcan.c                   | 6 ++++++
 drivers/net/can/xilinx_can.c              | 6 ++++++
 30 files changed, 155 insertions(+)

diff --git a/drivers/net/can/at91_can.c b/drivers/net/can/at91_can.c
index 29ed0d3cd171..3a2d109a3792 100644
--- a/drivers/net/can/at91_can.c
+++ b/drivers/net/can/at91_can.c
@@ -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>
@@ -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)
 {
@@ -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;
 
diff --git a/drivers/net/can/c_can/c_can_ethtool.c b/drivers/net/can/c_can/c_can_ethtool.c
index 8a826a6813bd..4994afc0826e 100644
--- a/drivers/net/can/c_can/c_can_ethtool.c
+++ b/drivers/net/can/c_can/c_can_ethtool.c
@@ -26,6 +26,7 @@ static void c_can_get_ringparam(struct net_device *netdev,
 
 static const struct ethtool_ops c_can_ethtool_ops = {
 	.get_ringparam = c_can_get_ringparam,
+	.get_ts_info = ethtool_op_get_ts_info,
 };
 
 void c_can_set_ethtool_ops(struct net_device *netdev)
diff --git a/drivers/net/can/can327.c b/drivers/net/can/can327.c
index 88718d0cc569..bfa33f5e7fbe 100644
--- a/drivers/net/can/can327.c
+++ b/drivers/net/can/can327.c
@@ -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'] = {
@@ -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;
diff --git a/drivers/net/can/cc770/cc770.c b/drivers/net/can/cc770/cc770.c
index 797a954bb1a0..0b9dfc76e769 100644
--- a/drivers/net/can/cc770/cc770.c
+++ b/drivers/net/can/cc770/cc770.c
@@ -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>
@@ -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);
@@ -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 */
 
diff --git a/drivers/net/can/ctucanfd/ctucanfd_base.c b/drivers/net/can/ctucanfd/ctucanfd_base.c
index 6b281f6eb9b4..3c18d028bd8c 100644
--- a/drivers/net/can/ctucanfd/ctucanfd_base.c
+++ b/drivers/net/can/ctucanfd/ctucanfd_base.c
@@ -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>
@@ -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);
@@ -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) {
diff --git a/drivers/net/can/flexcan/flexcan-ethtool.c b/drivers/net/can/flexcan/flexcan-ethtool.c
index 3ae535577700..8d9c45323da8 100644
--- a/drivers/net/can/flexcan/flexcan-ethtool.c
+++ b/drivers/net/can/flexcan/flexcan-ethtool.c
@@ -106,6 +106,7 @@ static 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,
 };
 
 void flexcan_set_ethtool_ops(struct net_device *netdev)
diff --git a/drivers/net/can/grcan.c b/drivers/net/can/grcan.c
index 24035a6187c9..6c37aab93eb3 100644
--- a/drivers/net/can/grcan.c
+++ b/drivers/net/can/grcan.c
@@ -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>
@@ -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)
@@ -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);
diff --git a/drivers/net/can/ifi_canfd/ifi_canfd.c b/drivers/net/can/ifi_canfd/ifi_canfd.c
index 64e3be8b73af..ad7a89b95da7 100644
--- a/drivers/net/can/ifi_canfd/ifi_canfd.c
+++ b/drivers/net/can/ifi_canfd/ifi_canfd.c
@@ -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>
@@ -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;
@@ -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;
diff --git a/drivers/net/can/janz-ican3.c b/drivers/net/can/janz-ican3.c
index 78d9190a4220..71a2caae0757 100644
--- a/drivers/net/can/janz-ican3.c
+++ b/drivers/net/can/janz-ican3.c
@@ -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>
@@ -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
  */
@@ -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);
 
diff --git a/drivers/net/can/m_can/m_can.c b/drivers/net/can/m_can/m_can.c
index 713a4b0edf86..4709c012b1dc 100644
--- a/drivers/net/can/m_can/m_can.c
+++ b/drivers/net/can/m_can/m_can.c
@@ -9,6 +9,7 @@
  */
 
 #include <linux/bitfield.h>
+#include <linux/ethtool.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
 #include <linux/kernel.h>
@@ -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);
 }
diff --git a/drivers/net/can/mscan/mscan.c b/drivers/net/can/mscan/mscan.c
index 78a21ab63601..b1677588a4c8 100644
--- a/drivers/net/can/mscan/mscan.c
+++ b/drivers/net/can/mscan/mscan.c
@@ -676,6 +676,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 */
 
diff --git a/drivers/net/can/pch_can.c b/drivers/net/can/pch_can.c
index 32804fed116c..0558ff67ec6a 100644
--- a/drivers/net/can/pch_can.c
+++ b/drivers/net/can/pch_can.c
@@ -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>
@@ -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);
@@ -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);
diff --git a/drivers/net/can/rcar/rcar_can.c b/drivers/net/can/rcar/rcar_can.c
index d11db2112a4a..6ee968c59ac9 100644
--- a/drivers/net/can/rcar/rcar_can.c
+++ b/drivers/net/can/rcar/rcar_can.c
@@ -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>
@@ -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;
@@ -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;
diff --git a/drivers/net/can/rcar/rcar_canfd.c b/drivers/net/can/rcar/rcar_canfd.c
index d3e569a02b4d..27085b796e75 100644
--- a/drivers/net/can/rcar/rcar_canfd.c
+++ b/drivers/net/can/rcar/rcar_canfd.c
@@ -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>
@@ -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)
 {
@@ -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;
diff --git a/drivers/net/can/sja1000/sja1000.c b/drivers/net/can/sja1000/sja1000.c
index 75a2f9bf8c16..98dfd5f295a7 100644
--- a/drivers/net/can/sja1000/sja1000.c
+++ b/drivers/net/can/sja1000/sja1000.c
@@ -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>
@@ -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;
@@ -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);
diff --git a/drivers/net/can/slcan/slcan-ethtool.c b/drivers/net/can/slcan/slcan-ethtool.c
index bf0afdc4e49d..e11d64de78a6 100644
--- a/drivers/net/can/slcan/slcan-ethtool.c
+++ b/drivers/net/can/slcan/slcan-ethtool.c
@@ -57,6 +57,7 @@ static 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,
 };
 
 void slcan_set_ethtool_ops(struct net_device *netdev)
diff --git a/drivers/net/can/softing/softing_main.c b/drivers/net/can/softing/softing_main.c
index 8d27ac66ca7f..27579f99ef74 100644
--- a/drivers/net/can/softing/softing_main.c
+++ b/drivers/net/can/softing/softing_main.c
@@ -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>
@@ -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 = "softing",
 	.tseg1_min = 1,
@@ -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;
 
diff --git a/drivers/net/can/spi/hi311x.c b/drivers/net/can/spi/hi311x.c
index 167114aae6dd..b87dc420428d 100644
--- a/drivers/net/can/spi/hi311x.c
+++ b/drivers/net/can/spi/hi311x.c
@@ -20,6 +20,7 @@
 #include <linux/completion.h>
 #include <linux/delay.h>
 #include <linux/device.h>
+#include <linux/ethtool.h>
 #include <linux/freezer.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
@@ -802,6 +803,10 @@ static const struct net_device_ops hi3110_netdev_ops = {
 	.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[] = {
 	{
 		.compatible	= "holt,hi3110",
@@ -856,6 +861,7 @@ static int hi3110_can_probe(struct spi_device *spi)
 		goto out_free;
 
 	net->netdev_ops = &hi3110_netdev_ops;
+	net->ethtool_ops = &hi3110_ethtool_ops;
 	net->flags |= IFF_ECHO;
 
 	priv = netdev_priv(net);
diff --git a/drivers/net/can/spi/mcp251x.c b/drivers/net/can/spi/mcp251x.c
index 666a4505a55a..e750d13c8841 100644
--- a/drivers/net/can/spi/mcp251x.c
+++ b/drivers/net/can/spi/mcp251x.c
@@ -26,6 +26,7 @@
 #include <linux/completion.h>
 #include <linux/delay.h>
 #include <linux/device.h>
+#include <linux/ethtool.h>
 #include <linux/freezer.h>
 #include <linux/gpio.h>
 #include <linux/gpio/driver.h>
@@ -1248,6 +1249,10 @@ static const struct net_device_ops mcp251x_netdev_ops = {
 	.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[] = {
 	{
 		.compatible	= "microchip,mcp2510",
@@ -1313,6 +1318,7 @@ static int mcp251x_can_probe(struct spi_device *spi)
 		goto out_free;
 
 	net->netdev_ops = &mcp251x_netdev_ops;
+	net->ethtool_ops = &mcp251x_ethtool_ops;
 	net->flags |= IFF_ECHO;
 
 	priv = netdev_priv(net);
diff --git a/drivers/net/can/sun4i_can.c b/drivers/net/can/sun4i_can.c
index b90dfb429ccd..525309da1320 100644
--- a/drivers/net/can/sun4i_can.c
+++ b/drivers/net/can/sun4i_can.c
@@ -53,6 +53,7 @@
 #include <linux/can/error.h>
 #include <linux/clk.h>
 #include <linux/delay.h>
+#include <linux/ethtool.h>
 #include <linux/interrupt.h>
 #include <linux/init.h>
 #include <linux/io.h>
@@ -761,6 +762,10 @@ static const struct net_device_ops sun4ican_netdev_ops = {
 	.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 = {
 	.has_reset = false,
 };
@@ -851,6 +856,7 @@ static int sun4ican_probe(struct platform_device *pdev)
 	}
 
 	dev->netdev_ops = &sun4ican_netdev_ops;
+	dev->ethtool_ops = &sun4ican_ethtool_ops;
 	dev->irq = irq;
 	dev->flags |= IFF_ECHO;
 
diff --git a/drivers/net/can/ti_hecc.c b/drivers/net/can/ti_hecc.c
index afa38771520e..ec0ffeeb2015 100644
--- a/drivers/net/can/ti_hecc.c
+++ b/drivers/net/can/ti_hecc.c
@@ -23,6 +23,7 @@
 #include <linux/types.h>
 #include <linux/interrupt.h>
 #include <linux/errno.h>
+#include <linux/ethtool.h>
 #include <linux/netdevice.h>
 #include <linux/skbuff.h>
 #include <linux/platform_device.h>
@@ -841,6 +842,10 @@ static const struct net_device_ops ti_hecc_netdev_ops = {
 	.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[] = {
 	{
 		.compatible = "ti,am3517-hecc",
@@ -918,6 +923,7 @@ static int ti_hecc_probe(struct platform_device *pdev)
 	platform_set_drvdata(pdev, ndev);
 	SET_NETDEV_DEV(ndev, &pdev->dev);
 	ndev->netdev_ops = &ti_hecc_netdev_ops;
+	ndev->ethtool_ops = &ti_hecc_ethtool_ops;
 
 	priv->clk = clk_get(&pdev->dev, "hecc_ck");
 	if (IS_ERR(priv->clk)) {
diff --git a/drivers/net/can/usb/ems_usb.c b/drivers/net/can/usb/ems_usb.c
index bbec3311d893..429fc53761d1 100644
--- a/drivers/net/can/usb/ems_usb.c
+++ b/drivers/net/can/usb/ems_usb.c
@@ -4,6 +4,7 @@
  *
  * Copyright (C) 2004-2009 EMS Dr. Thomas Wuensche
  */
+#include <linux/ethtool.h>
 #include <linux/signal.h>
 #include <linux/slab.h>
 #include <linux/module.h>
@@ -879,6 +880,10 @@ static const struct net_device_ops ems_usb_netdev_ops = {
 	.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 = {
 	.name = "ems_usb",
 	.tseg1_min = 1,
@@ -990,6 +995,7 @@ static int ems_usb_probe(struct usb_interface *intf,
 	dev->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES;
 
 	netdev->netdev_ops = &ems_usb_netdev_ops;
+	netdev->ethtool_ops = &ems_usb_ethtool_ops;
 
 	netdev->flags |= IFF_ECHO; /* we support local echo */
 
diff --git a/drivers/net/can/usb/esd_usb.c b/drivers/net/can/usb/esd_usb.c
index 177ed33e08d9..646cb85b3108 100644
--- a/drivers/net/can/usb/esd_usb.c
+++ b/drivers/net/can/usb/esd_usb.c
@@ -5,6 +5,7 @@
  * 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>
  */
+#include <linux/ethtool.h>
 #include <linux/signal.h>
 #include <linux/slab.h>
 #include <linux/module.h>
@@ -882,6 +883,10 @@ static const struct net_device_ops esd_usb_netdev_ops = {
 	.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 = {
 	.name = "esd_usb2",
 	.tseg1_min = ESD_USB2_TSEG1_MIN,
@@ -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->netdev_ops = &esd_usb_netdev_ops;
+	netdev->ethtool_ops = &esd_usb_ethtool_ops;
 
 	SET_NETDEV_DEV(netdev, &intf->dev);
 	netdev->dev_id = index;
diff --git a/drivers/net/can/usb/gs_usb.c b/drivers/net/can/usb/gs_usb.c
index d3a658b444b5..0b2172bc57f1 100644
--- a/drivers/net/can/usb/gs_usb.c
+++ b/drivers/net/can/usb/gs_usb.c
@@ -946,6 +946,7 @@ static int gs_usb_set_phys_id(struct net_device *dev,
 
 static const struct ethtool_ops gs_usb_ethtool_ops = {
 	.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,
@@ -989,6 +990,7 @@ static struct gs_can *gs_make_candev(unsigned int channel,
 	dev = netdev_priv(netdev);
 
 	netdev->netdev_ops = &gs_usb_netdev_ops;
+	netdev->ethtool_ops = &gs_usb_ethtool_ops;
 
 	netdev->flags |= IFF_ECHO; /* we support full roundtrip echo */
 
diff --git a/drivers/net/can/usb/mcba_usb.c b/drivers/net/can/usb/mcba_usb.c
index 792ab9da317d..69346c63021f 100644
--- a/drivers/net/can/usb/mcba_usb.c
+++ b/drivers/net/can/usb/mcba_usb.c
@@ -10,6 +10,7 @@
 #include <linux/can.h>
 #include <linux/can/dev.h>
 #include <linux/can/error.h>
+#include <linux/ethtool.h>
 #include <linux/module.h>
 #include <linux/netdevice.h>
 #include <linux/signal.h>
@@ -758,6 +759,10 @@ static const struct net_device_ops mcba_netdev_ops = {
 	.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.
  * This function sends request via USB to change the speed and align bittiming
  * values for presentation purposes only
@@ -836,6 +841,7 @@ static int mcba_usb_probe(struct usb_interface *intf,
 	priv->can.do_set_bittiming = mcba_net_set_bittiming;
 
 	netdev->netdev_ops = &mcba_netdev_ops;
+	netdev->ethtool_ops = &mcba_ethtool_ops;
 
 	netdev->flags |= IFF_ECHO; /* we support local echo */
 
diff --git a/drivers/net/can/usb/ucan.c b/drivers/net/can/usb/ucan.c
index 5ae0d7c017cc..7c35f50fda4e 100644
--- a/drivers/net/can/usb/ucan.c
+++ b/drivers/net/can/usb/ucan.c
@@ -28,6 +28,7 @@
 #include <linux/can.h>
 #include <linux/can/dev.h>
 #include <linux/can/error.h>
+#include <linux/ethtool.h>
 #include <linux/module.h>
 #include <linux/netdevice.h>
 #include <linux/signal.h>
@@ -1233,6 +1234,10 @@ static const struct net_device_ops ucan_netdev_ops = {
 	.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
  *
  * This function generates an USB set bittiming message and transmits
@@ -1512,6 +1517,7 @@ static int ucan_probe(struct usb_interface *intf,
 	spin_lock_init(&up->context_lock);
 	spin_lock_init(&up->echo_skb_lock);
 	netdev->netdev_ops = &ucan_netdev_ops;
+	netdev->ethtool_ops = &ucan_ethtool_ops;
 
 	usb_set_intfdata(intf, up);
 	SET_NETDEV_DEV(netdev, &intf->dev);
diff --git a/drivers/net/can/usb/usb_8dev.c b/drivers/net/can/usb/usb_8dev.c
index 8b7cd69e20b0..9453956303c0 100644
--- a/drivers/net/can/usb/usb_8dev.c
+++ b/drivers/net/can/usb/usb_8dev.c
@@ -12,6 +12,7 @@
  * who were very cooperative and answered my questions.
  */
 
+#include <linux/ethtool.h>
 #include <linux/signal.h>
 #include <linux/slab.h>
 #include <linux/module.h>
@@ -870,6 +871,10 @@ static const struct net_device_ops usb_8dev_netdev_ops = {
 	.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 = {
 	.name = "usb_8dev",
 	.tseg1_min = 1,
@@ -927,6 +932,7 @@ static int usb_8dev_probe(struct usb_interface *intf,
 				      CAN_CTRLMODE_CC_LEN8_DLC;
 
 	netdev->netdev_ops = &usb_8dev_netdev_ops;
+	netdev->ethtool_ops = &usb_8dev_ethtool_ops;
 
 	netdev->flags |= IFF_ECHO; /* we support local echo */
 
diff --git a/drivers/net/can/vcan.c b/drivers/net/can/vcan.c
index 4a363cfcf97c..36b6310a2e5b 100644
--- a/drivers/net/can/vcan.c
+++ b/drivers/net/can/vcan.c
@@ -40,6 +40,7 @@
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
+#include <linux/ethtool.h>
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/netdevice.h>
@@ -148,6 +149,10 @@ static const struct net_device_ops vcan_netdev_ops = {
 	.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)
 {
 	dev->type		= ARPHRD_CAN;
@@ -163,6 +168,7 @@ static void vcan_setup(struct net_device *dev)
 		dev->flags |= IFF_ECHO;
 
 	dev->netdev_ops		= &vcan_netdev_ops;
+	dev->ethtool_ops	= &vcan_ethtool_ops;
 	dev->needs_free_netdev	= true;
 }
 
diff --git a/drivers/net/can/vxcan.c b/drivers/net/can/vxcan.c
index 61b6eca383f8..cffd107d8b28 100644
--- a/drivers/net/can/vxcan.c
+++ b/drivers/net/can/vxcan.c
@@ -9,6 +9,7 @@
  * Copyright (c) 2017 Oliver Hartkopp <socketcan@hartkopp.net>
  */
 
+#include <linux/ethtool.h>
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/netdevice.h>
@@ -146,6 +147,10 @@ static const struct net_device_ops vxcan_netdev_ops = {
 	.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)
 {
 	struct can_ml_priv *can_ml;
@@ -157,6 +162,7 @@ static void vxcan_setup(struct net_device *dev)
 	dev->tx_queue_len	= 0;
 	dev->flags		= IFF_NOARP;
 	dev->netdev_ops		= &vxcan_netdev_ops;
+	dev->ethtool_ops	= &vxcan_ethtool_ops;
 	dev->needs_free_netdev	= true;
 
 	can_ml = netdev_priv(dev) + ALIGN(sizeof(struct vxcan_priv), NETDEV_ALIGN);
diff --git a/drivers/net/can/xilinx_can.c b/drivers/net/can/xilinx_can.c
index caa6b4cee63f..5d3172795ad0 100644
--- a/drivers/net/can/xilinx_can.c
+++ b/drivers/net/can/xilinx_can.c
@@ -12,6 +12,7 @@
 #include <linux/bitfield.h>
 #include <linux/clk.h>
 #include <linux/errno.h>
+#include <linux/ethtool.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
@@ -1540,6 +1541,10 @@ static const struct net_device_ops xcan_netdev_ops = {
 	.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
  * @dev:	Address of the device structure
@@ -1821,6 +1826,7 @@ static int xcan_probe(struct platform_device *pdev)
 	platform_set_drvdata(pdev, ndev);
 	SET_NETDEV_DEV(ndev, &pdev->dev);
 	ndev->netdev_ops = &xcan_netdev_ops;
+	ndev->ethtool_ops = &xcan_ethtool_ops;
 
 	/* Getting the CAN can_clk info */
 	priv->can_clk = devm_clk_get(&pdev->dev, "can_clk");
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 92+ messages in thread

* [PATCH v3 06/14] can: dev: add hardware TX timestamp
  2022-07-26 10:24 ` [PATCH v3 00/14] Vincent Mailhol
                     ` (4 preceding siblings ...)
  2022-07-26 10:24   ` [PATCH v3 05/14] can: tree-wide: advertise software timestamping capabilities Vincent Mailhol
@ 2022-07-26 10:24   ` Vincent Mailhol
  2022-07-26 10:24   ` [PATCH v3 07/14] can: dev: add generic function can_ethtool_op_get_ts_info_hwts() Vincent Mailhol
                     ` (7 subsequent siblings)
  13 siblings, 0 replies; 92+ messages in thread
From: Vincent Mailhol @ 2022-07-26 10:24 UTC (permalink / raw)
  To: linux-can, Marc Kleine-Budde
  Cc: Stephane Grosjean, Jimmy Assarsson, Oliver Hartkopp,
	Dario Binacchi, Max Staudt, Vincent Mailhol

Because of the loopback feature of socket CAN, hardware TX timestamps
are nothing else than the hardware RX timespamp of the corresponding
loopback packet. This patch simply reuses the hardware RX timestamp.

The rationale to clone this timestamp value is that existing tools
which rely of libpcap (such as tcpdump) expect support for both TX and
RX hardware timestamps in order to activate the feature (i.e. no
granular control to activate either of TX or RX hardware timestamps).

Signed-off-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
---
 drivers/net/can/dev/skb.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/net/can/dev/skb.c b/drivers/net/can/dev/skb.c
index 8bb62dd864c8..07e0feac8629 100644
--- a/drivers/net/can/dev/skb.c
+++ b/drivers/net/can/dev/skb.c
@@ -72,6 +72,9 @@ int can_put_echo_skb(struct sk_buff *skb, struct net_device *dev,
 		/* save frame_len to reuse it when transmission is completed */
 		can_skb_prv(skb)->frame_len = frame_len;
 
+		if (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)
+			skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;
+
 		skb_tx_timestamp(skb);
 
 		/* save this skb for tx interrupt echo handling */
@@ -107,6 +110,9 @@ __can_get_echo_skb(struct net_device *dev, unsigned int idx, u8 *len_ptr,
 		struct can_skb_priv *can_skb_priv = can_skb_prv(skb);
 		struct canfd_frame *cf = (struct canfd_frame *)skb->data;
 
+		if (skb_shinfo(skb)->tx_flags & SKBTX_IN_PROGRESS)
+			skb_tstamp_tx(skb, skb_hwtstamps(skb));
+
 		/* get the real payload length for netdev statistics */
 		if (cf->can_id & CAN_RTR_FLAG)
 			*len_ptr = 0;
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 92+ messages in thread

* [PATCH v3 07/14] can: dev: add generic function can_ethtool_op_get_ts_info_hwts()
  2022-07-26 10:24 ` [PATCH v3 00/14] Vincent Mailhol
                     ` (5 preceding siblings ...)
  2022-07-26 10:24   ` [PATCH v3 06/14] can: dev: add hardware TX timestamp Vincent Mailhol
@ 2022-07-26 10:24   ` Vincent Mailhol
  2022-07-26 10:24   ` [PATCH v3 08/14] can: dev: add generic function can_eth_ioctl_hwts() Vincent Mailhol
                     ` (6 subsequent siblings)
  13 siblings, 0 replies; 92+ messages in thread
From: Vincent Mailhol @ 2022-07-26 10:24 UTC (permalink / raw)
  To: linux-can, Marc Kleine-Budde
  Cc: Stephane Grosjean, Jimmy Assarsson, Oliver Hartkopp,
	Dario Binacchi, Max Staudt, Vincent Mailhol

Add function can_ethtool_op_get_ts_info_hwts(). This function will be
used by CAN devices with hardware TX/RX timestamping support to
implement ethtool_ops::get_ts_info. This function does not offer
support to activate/deactivate hardware timestamps at device level nor
support the filter options (which is currently the case for all CAN
devices with hardware timestamping support).

The fact that hardware timestamp can not be deactivated at hardware
level does not impact the userland. As long as the user do not set
SO_TIMESTAMPING using a setsockopt() or ioctl(), the kernel will not
emit TX timestamps (RX timestamps will still be reproted as it is the
case currently).

Drivers which need more fine grained control remains free to implement
their own function, but we foresee that the generic function
introduced here will be sufficient for the majority.

Signed-off-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
---
 drivers/net/can/dev/dev.c | 21 +++++++++++++++++++++
 include/linux/can/dev.h   |  3 +++
 2 files changed, 24 insertions(+)

diff --git a/drivers/net/can/dev/dev.c b/drivers/net/can/dev/dev.c
index 523eaacfe29e..f307034ff4fd 100644
--- a/drivers/net/can/dev/dev.c
+++ b/drivers/net/can/dev/dev.c
@@ -322,6 +322,27 @@ int can_change_mtu(struct net_device *dev, int new_mtu)
 }
 EXPORT_SYMBOL_GPL(can_change_mtu);
 
+/* generic implementation of ethtool_ops::get_ts_info for CAN devices
+ * supporting hardware timestamps
+ */
+int can_ethtool_op_get_ts_info_hwts(struct net_device *dev,
+				    struct ethtool_ts_info *info)
+{
+	info->so_timestamping =
+		SOF_TIMESTAMPING_TX_SOFTWARE |
+		SOF_TIMESTAMPING_RX_SOFTWARE |
+		SOF_TIMESTAMPING_SOFTWARE |
+		SOF_TIMESTAMPING_TX_HARDWARE |
+		SOF_TIMESTAMPING_RX_HARDWARE |
+		SOF_TIMESTAMPING_RAW_HARDWARE;
+	info->phc_index = -1;
+	info->tx_types = BIT(HWTSTAMP_TX_ON);
+	info->rx_filters = BIT(HWTSTAMP_FILTER_ALL);
+
+	return 0;
+}
+EXPORT_SYMBOL(can_ethtool_op_get_ts_info_hwts);
+
 /* Common open function when the device gets opened.
  *
  * This function should be called in the open function of the device
diff --git a/include/linux/can/dev.h b/include/linux/can/dev.h
index e22dc03c850e..752bd45d8ebf 100644
--- a/include/linux/can/dev.h
+++ b/include/linux/can/dev.h
@@ -20,6 +20,7 @@
 #include <linux/can/length.h>
 #include <linux/can/netlink.h>
 #include <linux/can/skb.h>
+#include <linux/ethtool.h>
 #include <linux/netdevice.h>
 
 /*
@@ -162,6 +163,8 @@ struct can_priv *safe_candev_priv(struct net_device *dev);
 int open_candev(struct net_device *dev);
 void close_candev(struct net_device *dev);
 int can_change_mtu(struct net_device *dev, int new_mtu);
+int can_ethtool_op_get_ts_info_hwts(struct net_device *dev,
+				    struct ethtool_ts_info *info);
 
 int register_candev(struct net_device *dev);
 void unregister_candev(struct net_device *dev);
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 92+ messages in thread

* [PATCH v3 08/14] can: dev: add generic function can_eth_ioctl_hwts()
  2022-07-26 10:24 ` [PATCH v3 00/14] Vincent Mailhol
                     ` (6 preceding siblings ...)
  2022-07-26 10:24   ` [PATCH v3 07/14] can: dev: add generic function can_ethtool_op_get_ts_info_hwts() Vincent Mailhol
@ 2022-07-26 10:24   ` Vincent Mailhol
  2022-07-26 10:24   ` [PATCH v3 09/14] can: mcp251xfd: advertise timestamping capabilities and add ioctl support Vincent Mailhol
                     ` (5 subsequent siblings)
  13 siblings, 0 replies; 92+ messages in thread
From: Vincent Mailhol @ 2022-07-26 10:24 UTC (permalink / raw)
  To: linux-can, Marc Kleine-Budde
  Cc: Stephane Grosjean, Jimmy Assarsson, Oliver Hartkopp,
	Dario Binacchi, Max Staudt, Vincent Mailhol

Tools based on libpcap (such as tcpdump) expect the SIOCSHWTSTAMP
ioctl call to be supported. This is also specified in the kernel doc
[1]. The purpose of this ioctl is to toggle the hardware timestamps.

Currently, CAN devices which support hardware timestamping have those
always activated. can_eth_ioctl_hwts() is a dumb function that will
always succeed when requested to set tx_type to HWTSTAMP_TX_ON or
rx_filter to HWTSTAMP_FILTER_ALL.

[1] Kernel doc: Timestamping, section 3.1 "Hardware Timestamping
Implementation: Device Drivers"
Link: https://docs.kernel.org/networking/timestamping.html#hardware-timestamping-implementation-device-drivers

Signed-off-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
---
 drivers/net/can/dev/dev.c | 29 +++++++++++++++++++++++++++++
 include/linux/can/dev.h   |  1 +
 2 files changed, 30 insertions(+)

diff --git a/drivers/net/can/dev/dev.c b/drivers/net/can/dev/dev.c
index f307034ff4fd..c1956b1e9faf 100644
--- a/drivers/net/can/dev/dev.c
+++ b/drivers/net/can/dev/dev.c
@@ -322,6 +322,35 @@ int can_change_mtu(struct net_device *dev, int new_mtu)
 }
 EXPORT_SYMBOL_GPL(can_change_mtu);
 
+/* generic implementation of netdev_ops::ndo_eth_ioctl for CAN devices
+ * supporting hardware timestamps
+ */
+int can_eth_ioctl_hwts(struct net_device *netdev, struct ifreq *ifr, int cmd)
+{
+	struct hwtstamp_config hwts_cfg = { 0 };
+
+	switch (cmd) {
+	case SIOCSHWTSTAMP: /* set */
+		if (copy_from_user(&hwts_cfg, ifr->ifr_data, sizeof(hwts_cfg)))
+			return -EFAULT;
+		if (hwts_cfg.tx_type == HWTSTAMP_TX_ON &&
+		    hwts_cfg.rx_filter == HWTSTAMP_FILTER_ALL)
+			return 0;
+		return -ERANGE;
+
+	case SIOCGHWTSTAMP: /* get */
+		hwts_cfg.tx_type = HWTSTAMP_TX_ON;
+		hwts_cfg.rx_filter = HWTSTAMP_FILTER_ALL;
+		if (copy_to_user(ifr->ifr_data, &hwts_cfg, sizeof(hwts_cfg)))
+			return -EFAULT;
+		return 0;
+
+	default:
+		return -EOPNOTSUPP;
+	}
+}
+EXPORT_SYMBOL(can_eth_ioctl_hwts);
+
 /* generic implementation of ethtool_ops::get_ts_info for CAN devices
  * supporting hardware timestamps
  */
diff --git a/include/linux/can/dev.h b/include/linux/can/dev.h
index 752bd45d8ebf..c3e50e537e39 100644
--- a/include/linux/can/dev.h
+++ b/include/linux/can/dev.h
@@ -163,6 +163,7 @@ struct can_priv *safe_candev_priv(struct net_device *dev);
 int open_candev(struct net_device *dev);
 void close_candev(struct net_device *dev);
 int can_change_mtu(struct net_device *dev, int new_mtu);
+int can_eth_ioctl_hwts(struct net_device *netdev, struct ifreq *ifr, int cmd);
 int can_ethtool_op_get_ts_info_hwts(struct net_device *dev,
 				    struct ethtool_ts_info *info);
 
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 92+ messages in thread

* [PATCH v3 09/14] can: mcp251xfd: advertise timestamping capabilities and add ioctl support
  2022-07-26 10:24 ` [PATCH v3 00/14] Vincent Mailhol
                     ` (7 preceding siblings ...)
  2022-07-26 10:24   ` [PATCH v3 08/14] can: dev: add generic function can_eth_ioctl_hwts() Vincent Mailhol
@ 2022-07-26 10:24   ` Vincent Mailhol
  2022-07-26 10:24   ` [PATCH v3 10/14] can: etas_es58x: " Vincent Mailhol
                     ` (4 subsequent siblings)
  13 siblings, 0 replies; 92+ messages in thread
From: Vincent Mailhol @ 2022-07-26 10:24 UTC (permalink / raw)
  To: linux-can, Marc Kleine-Budde
  Cc: Stephane Grosjean, Jimmy Assarsson, Oliver Hartkopp,
	Dario Binacchi, Max Staudt, Vincent Mailhol

Currently, userland has no methods to query which timestamping
features are supported by the mcp251xfd driver (aside maybe of getting
RX messages and obseverse whether or not hardware timestamps stay at
zero).

The canonical way for a network driver to advertise what kind of
timestamping it supports is to implement
ethtool_ops::get_ts_info(). Here, we use the CAN specific
can_ethtool_op_get_ts_info_hwts() function to achieve this.

In addition, the driver currently does not support the hardware
timestamps ioctls. According to [1], SIOCSHWTSTAMP is "must" and
SIOCGHWTSTAMP is "should". This patch fills up that gap by
implementing net_device_ops::ndo_eth_ioctl() using the CAN specific
function can_eth_ioctl_hwts().

[1] kernel doc Timestamping, section 3.1: "Hardware Timestamping
Implementation: Device Drivers"
Link: https://docs.kernel.org/networking/timestamping.html#hardware-timestamping-implementation-device-drivers

Signed-off-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
---
 drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c    | 1 +
 drivers/net/can/spi/mcp251xfd/mcp251xfd-ethtool.c | 1 +
 2 files changed, 2 insertions(+)

diff --git a/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c b/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c
index 7fc86ed405c6..68df6d4641b5 100644
--- a/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c
+++ b/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c
@@ -1671,6 +1671,7 @@ static const struct net_device_ops mcp251xfd_netdev_ops = {
 	.ndo_open = mcp251xfd_open,
 	.ndo_stop = mcp251xfd_stop,
 	.ndo_start_xmit	= mcp251xfd_start_xmit,
+	.ndo_eth_ioctl = can_eth_ioctl_hwts,
 	.ndo_change_mtu = can_change_mtu,
 };
 
diff --git a/drivers/net/can/spi/mcp251xfd/mcp251xfd-ethtool.c b/drivers/net/can/spi/mcp251xfd/mcp251xfd-ethtool.c
index 6c7a57f16cc6..3585f02575df 100644
--- a/drivers/net/can/spi/mcp251xfd/mcp251xfd-ethtool.c
+++ b/drivers/net/can/spi/mcp251xfd/mcp251xfd-ethtool.c
@@ -124,6 +124,7 @@ static const struct ethtool_ops mcp251xfd_ethtool_ops = {
 	.set_ringparam = mcp251xfd_ring_set_ringparam,
 	.get_coalesce = mcp251xfd_ring_get_coalesce,
 	.set_coalesce = mcp251xfd_ring_set_coalesce,
+	.get_ts_info = can_ethtool_op_get_ts_info_hwts,
 };
 
 void mcp251xfd_ethtool_init(struct mcp251xfd_priv *priv)
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 92+ messages in thread

* [PATCH v3 10/14] can: etas_es58x: advertise timestamping capabilities and add ioctl support
  2022-07-26 10:24 ` [PATCH v3 00/14] Vincent Mailhol
                     ` (8 preceding siblings ...)
  2022-07-26 10:24   ` [PATCH v3 09/14] can: mcp251xfd: advertise timestamping capabilities and add ioctl support Vincent Mailhol
@ 2022-07-26 10:24   ` Vincent Mailhol
  2022-07-26 10:24   ` [PATCH v3 11/14] can: kvaser_pciefd: " Vincent Mailhol
                     ` (3 subsequent siblings)
  13 siblings, 0 replies; 92+ messages in thread
From: Vincent Mailhol @ 2022-07-26 10:24 UTC (permalink / raw)
  To: linux-can, Marc Kleine-Budde
  Cc: Stephane Grosjean, Jimmy Assarsson, Oliver Hartkopp,
	Dario Binacchi, Max Staudt, Vincent Mailhol

Currently, userland has no method to query which timestamping features
are supported by the etas_es58x driver (aside maybe of getting RX
messages and obseverse whever or not hardware timestamps stay at
zero).

The canonical way for a network driver to advertise what kind of
timestamping is supports is to implement
ethtool_ops::get_ts_info(). Here, we use the CAN specific
can_ethtool_op_get_ts_info_hwts() function to achieve this.

In addition, the driver currently does not support the hardware
timestamps ioctls. According to [1], SIOCSHWTSTAMP is "must" and
SIOCGHWTSTAMP is "should". This patch fills up that gap by
implementing net_device_ops::ndo_eth_ioctl() using the CAN specific
function can_eth_ioctl_hwts().

[1] kernel doc Timestamping, section 3.1: "Hardware Timestamping
Implementation: Device Drivers"
Link: https://docs.kernel.org/networking/timestamping.html#hardware-timestamping-implementation-device-drivers

Signed-off-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
---
 drivers/net/can/usb/etas_es58x/es58x_core.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/net/can/usb/etas_es58x/es58x_core.c b/drivers/net/can/usb/etas_es58x/es58x_core.c
index 7353745f92d7..5e2585c85500 100644
--- a/drivers/net/can/usb/etas_es58x/es58x_core.c
+++ b/drivers/net/can/usb/etas_es58x/es58x_core.c
@@ -10,6 +10,7 @@
  * Copyright (c) 2020, 2021 Vincent Mailhol <mailhol.vincent@wanadoo.fr>
  */
 
+#include <linux/ethtool.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/usb.h>
@@ -1981,7 +1982,12 @@ static netdev_tx_t es58x_start_xmit(struct sk_buff *skb,
 static const struct net_device_ops es58x_netdev_ops = {
 	.ndo_open = es58x_open,
 	.ndo_stop = es58x_stop,
-	.ndo_start_xmit = es58x_start_xmit
+	.ndo_start_xmit = es58x_start_xmit,
+	.ndo_eth_ioctl = can_eth_ioctl_hwts,
+};
+
+static const struct ethtool_ops es58x_ethtool_ops = {
+	.get_ts_info = can_ethtool_op_get_ts_info_hwts,
 };
 
 /**
@@ -2088,6 +2094,7 @@ static int es58x_init_netdev(struct es58x_device *es58x_dev, int channel_idx)
 	es58x_init_priv(es58x_dev, es58x_priv(netdev), channel_idx);
 
 	netdev->netdev_ops = &es58x_netdev_ops;
+	netdev->ethtool_ops = &es58x_ethtool_ops;
 	netdev->flags |= IFF_ECHO;	/* We support local echo */
 	netdev->dev_port = channel_idx;
 
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 92+ messages in thread

* [PATCH v3 11/14] can: kvaser_pciefd: advertise timestamping capabilities and add ioctl support
  2022-07-26 10:24 ` [PATCH v3 00/14] Vincent Mailhol
                     ` (9 preceding siblings ...)
  2022-07-26 10:24   ` [PATCH v3 10/14] can: etas_es58x: " Vincent Mailhol
@ 2022-07-26 10:24   ` Vincent Mailhol
  2022-07-26 10:24   ` [PATCH v3 12/14] can: kvaser_usb: " Vincent Mailhol
                     ` (2 subsequent siblings)
  13 siblings, 0 replies; 92+ messages in thread
From: Vincent Mailhol @ 2022-07-26 10:24 UTC (permalink / raw)
  To: linux-can, Marc Kleine-Budde
  Cc: Stephane Grosjean, Jimmy Assarsson, Oliver Hartkopp,
	Dario Binacchi, Max Staudt, Vincent Mailhol

Currently, userland has no method to query which timestamping features
are supported by the kvaser_pciefd driver (aside maybe of getting RX
messages and obseverse whever or not hardware timestamps stay at
zero).

The canonical way for a network driver to advertise what kind of
timestamping it supports is to implement
ethtool_ops::get_ts_info(). Here, we use the CAN specific
can_ethtool_op_get_ts_info_hwts() function to achieve this.

In addition, the driver currently does not support the hardware
timestamps ioctls. According to [1], SIOCSHWTSTAMP is "must" and
SIOCGHWTSTAMP is "should". This patch fills up that gap by
implementing net_device_ops::ndo_eth_ioctl() using the CAN specific
function can_eth_ioctl_hwts().

[1] kernel doc Timestamping, section 3.1: "Hardware Timestamping
Implementation: Device Drivers"
Link: https://docs.kernel.org/networking/timestamping.html#hardware-timestamping-implementation-device-drivers

CC: Jimmy Assarsson <extja@kvaser.com>
Signed-off-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
---
 drivers/net/can/kvaser_pciefd.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/drivers/net/can/kvaser_pciefd.c b/drivers/net/can/kvaser_pciefd.c
index dcd2c9d50d5e..ed54c0b3c7d4 100644
--- a/drivers/net/can/kvaser_pciefd.c
+++ b/drivers/net/can/kvaser_pciefd.c
@@ -9,6 +9,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/device.h>
+#include <linux/ethtool.h>
 #include <linux/pci.h>
 #include <linux/can/dev.h>
 #include <linux/timer.h>
@@ -919,10 +920,15 @@ static void kvaser_pciefd_bec_poll_timer(struct timer_list *data)
 static const struct net_device_ops kvaser_pciefd_netdev_ops = {
 	.ndo_open = kvaser_pciefd_open,
 	.ndo_stop = kvaser_pciefd_stop,
+	.ndo_eth_ioctl = can_eth_ioctl_hwts,
 	.ndo_start_xmit = kvaser_pciefd_start_xmit,
 	.ndo_change_mtu = can_change_mtu,
 };
 
+static const struct ethtool_ops kvaser_pciefd_ethtool_ops = {
+	.get_ts_info = can_ethtool_op_get_ts_info_hwts,
+};
+
 static int kvaser_pciefd_setup_can_ctrls(struct kvaser_pciefd *pcie)
 {
 	int i;
@@ -939,6 +945,7 @@ static int kvaser_pciefd_setup_can_ctrls(struct kvaser_pciefd *pcie)
 
 		can = netdev_priv(netdev);
 		netdev->netdev_ops = &kvaser_pciefd_netdev_ops;
+		netdev->ethtool_ops = &kvaser_pciefd_ethtool_ops;
 		can->reg_base = pcie->reg_base + KVASER_PCIEFD_KCAN0_BASE +
 				i * KVASER_PCIEFD_KCAN_BASE_OFFSET;
 
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 92+ messages in thread

* [PATCH v3 12/14] can: kvaser_usb: advertise timestamping capabilities and add ioctl support
  2022-07-26 10:24 ` [PATCH v3 00/14] Vincent Mailhol
                     ` (10 preceding siblings ...)
  2022-07-26 10:24   ` [PATCH v3 11/14] can: kvaser_pciefd: " Vincent Mailhol
@ 2022-07-26 10:24   ` Vincent Mailhol
  2022-07-26 10:24   ` [PATCH v3 13/14] can: peak_canfd: " Vincent Mailhol
  2022-07-26 10:24   ` [PATCH v3 14/14] can: peak_usb: " Vincent Mailhol
  13 siblings, 0 replies; 92+ messages in thread
From: Vincent Mailhol @ 2022-07-26 10:24 UTC (permalink / raw)
  To: linux-can, Marc Kleine-Budde
  Cc: Stephane Grosjean, Jimmy Assarsson, Oliver Hartkopp,
	Dario Binacchi, Max Staudt, Vincent Mailhol

Currently, userland has no method to query which timestamping features
are supported by the kvaser_usb driver (aside maybe of getting RX
messages and obseverse whever or not hardware timestamps stay at
zero).

The canonical way for a network driver to advertise what kind of
timestamping it supports is to implement
ethtool_ops::get_ts_info(). Here, we use the CAN specific
can_ethtool_op_get_ts_info_hwts() function to achieve this.

In addition, the driver currently does not support the hardware
timestamps ioctls. According to [1], SIOCSHWTSTAMP is "must" and
SIOCGHWTSTAMP is "should". This patch fills up that gap by
implementing net_device_ops::ndo_eth_ioctl() using the CAN specific
function can_eth_ioctl_hwts().

[1] kernel doc Timestamping, section 3.1: "Hardware Timestamping
Implementation: Device Drivers"
Link: https://docs.kernel.org/networking/timestamping.html#hardware-timestamping-implementation-device-drivers

CC: Jimmy Assarsson <extja@kvaser.com>
Signed-off-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
---

Hi Jimmy, as far as I understand, only the hydra has the hardware
timestamping. If not the case, let me know.

This is not tested. If you find any issue or if you want to modify,
feel free to pick up that patch and resend it.
---
 drivers/net/can/usb/kvaser_usb/kvaser_usb.h   |  1 +
 .../net/can/usb/kvaser_usb/kvaser_usb_core.c  | 27 +++++++++++++++++--
 2 files changed, 26 insertions(+), 2 deletions(-)

diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb.h b/drivers/net/can/usb/kvaser_usb/kvaser_usb.h
index eefcbe3aadce..841da29cef93 100644
--- a/drivers/net/can/usb/kvaser_usb/kvaser_usb.h
+++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb.h
@@ -39,6 +39,7 @@
 #define KVASER_USB_QUIRK_HAS_SILENT_MODE	BIT(0)
 #define KVASER_USB_QUIRK_HAS_TXRX_ERRORS	BIT(1)
 #define KVASER_USB_QUIRK_IGNORE_CLK_FREQ	BIT(2)
+#define KVASER_USB_QUIRK_HAS_HARDWARE_TIMESTAMP	BIT(3)
 
 /* Device capabilities */
 #define KVASER_USB_CAP_BERR_CAP			0x01
diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c b/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c
index f211bfcb1d97..5e357f5d3116 100644
--- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c
+++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c
@@ -13,6 +13,7 @@
 
 #include <linux/completion.h>
 #include <linux/device.h>
+#include <linux/ethtool.h>
 #include <linux/gfp.h>
 #include <linux/if.h>
 #include <linux/kernel.h>
@@ -89,7 +90,7 @@
 #define USB_HYBRID_PRO_CANLIN_PRODUCT_ID	278
 
 static const struct kvaser_usb_driver_info kvaser_usb_driver_info_hydra = {
-	.quirks = 0,
+	.quirks = KVASER_USB_QUIRK_HAS_HARDWARE_TIMESTAMP,
 	.ops = &kvaser_usb_hydra_dev_ops,
 };
 
@@ -665,6 +666,22 @@ static const struct net_device_ops kvaser_usb_netdev_ops = {
 	.ndo_change_mtu = can_change_mtu,
 };
 
+static const struct net_device_ops kvaser_usb_netdev_ops_hwts = {
+	.ndo_open = kvaser_usb_open,
+	.ndo_stop = kvaser_usb_close,
+	.ndo_eth_ioctl = can_eth_ioctl_hwts,
+	.ndo_start_xmit = kvaser_usb_start_xmit,
+	.ndo_change_mtu = can_change_mtu,
+};
+
+static const struct ethtool_ops kvaser_usb_ethtool_ops = {
+	.get_ts_info = ethtool_op_get_ts_info,
+};
+
+static const struct ethtool_ops kvaser_usb_ethtool_ops_hwts = {
+	.get_ts_info = can_ethtool_op_get_ts_info_hwts,
+};
+
 static void kvaser_usb_remove_interfaces(struct kvaser_usb *dev)
 {
 	int i;
@@ -742,7 +759,13 @@ static int kvaser_usb_init_one(struct kvaser_usb *dev, int channel)
 	netdev->flags |= IFF_ECHO;
 
 	netdev->netdev_ops = &kvaser_usb_netdev_ops;
-
+	if (driver_info->quirks & KVASER_USB_QUIRK_HAS_HARDWARE_TIMESTAMP) {
+		netdev->netdev_ops = &kvaser_usb_netdev_ops_hwts;
+		netdev->ethtool_ops = &kvaser_usb_ethtool_ops_hwts;
+	} else {
+		netdev->netdev_ops = &kvaser_usb_netdev_ops;
+		netdev->ethtool_ops = &kvaser_usb_ethtool_ops;
+	}
 	SET_NETDEV_DEV(netdev, &dev->intf->dev);
 	netdev->dev_id = channel;
 
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 92+ messages in thread

* [PATCH v3 13/14] can: peak_canfd: advertise timestamping capabilities and add ioctl support
  2022-07-26 10:24 ` [PATCH v3 00/14] Vincent Mailhol
                     ` (11 preceding siblings ...)
  2022-07-26 10:24   ` [PATCH v3 12/14] can: kvaser_usb: " Vincent Mailhol
@ 2022-07-26 10:24   ` Vincent Mailhol
  2022-07-26 10:24   ` [PATCH v3 14/14] can: peak_usb: " Vincent Mailhol
  13 siblings, 0 replies; 92+ messages in thread
From: Vincent Mailhol @ 2022-07-26 10:24 UTC (permalink / raw)
  To: linux-can, Marc Kleine-Budde
  Cc: Stephane Grosjean, Jimmy Assarsson, Oliver Hartkopp,
	Dario Binacchi, Max Staudt, Vincent Mailhol

Currently, userland has no method to query which timestamping features
are supported by the peak_canfd driver (aside maybe of getting RX
messages and obseverse whever or not hardware timestamps stay at
zero).

The canonical way for a network driver to advertise what kind of
timestamping it supports is to implement
ethtool_ops::get_ts_info(). Here, we use the CAN specific
can_ethtool_op_get_ts_info_hwts() function to achieve this.

In addition, the driver currently does not support the hardware
timestamps ioctls. According to [1], SIOCSHWTSTAMP is "must" and
SIOCGHWTSTAMP is "should". This patch fills up that gap by
implementing net_device_ops::ndo_eth_ioctl() using the CAN specific
function can_eth_ioctl_hwts().

[1] kernel doc Timestamping, section 3.1: "Hardware Timestamping
Implementation: Device Drivers"
Link: https://docs.kernel.org/networking/timestamping.html#hardware-timestamping-implementation-device-drivers

CC: Stephane Grosjean <s.grosjean@peak-system.com>
Signed-off-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
---
 drivers/net/can/peak_canfd/peak_canfd.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/drivers/net/can/peak_canfd/peak_canfd.c b/drivers/net/can/peak_canfd/peak_canfd.c
index afb9adb3d5c2..634e24d99ac6 100644
--- a/drivers/net/can/peak_canfd/peak_canfd.c
+++ b/drivers/net/can/peak_canfd/peak_canfd.c
@@ -7,6 +7,7 @@
 
 #include <linux/can.h>
 #include <linux/can/dev.h>
+#include <linux/ethtool.h>
 
 #include "peak_canfd_user.h"
 
@@ -745,10 +746,15 @@ static netdev_tx_t peak_canfd_start_xmit(struct sk_buff *skb,
 static const struct net_device_ops peak_canfd_netdev_ops = {
 	.ndo_open = peak_canfd_open,
 	.ndo_stop = peak_canfd_close,
+	.ndo_eth_ioctl = can_eth_ioctl_hwts,
 	.ndo_start_xmit = peak_canfd_start_xmit,
 	.ndo_change_mtu = can_change_mtu,
 };
 
+static const struct ethtool_ops peak_canfd_ethtool_ops = {
+	.get_ts_info = can_ethtool_op_get_ts_info_hwts,
+};
+
 struct net_device *alloc_peak_canfd_dev(int sizeof_priv, int index,
 					int echo_skb_max)
 {
@@ -789,6 +795,7 @@ struct net_device *alloc_peak_canfd_dev(int sizeof_priv, int index,
 
 	ndev->flags |= IFF_ECHO;
 	ndev->netdev_ops = &peak_canfd_netdev_ops;
+	ndev->ethtool_ops = &peak_canfd_ethtool_ops;
 	ndev->dev_id = index;
 
 	return ndev;
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 92+ messages in thread

* [PATCH v3 14/14] can: peak_usb: advertise timestamping capabilities and add ioctl support
  2022-07-26 10:24 ` [PATCH v3 00/14] Vincent Mailhol
                     ` (12 preceding siblings ...)
  2022-07-26 10:24   ` [PATCH v3 13/14] can: peak_canfd: " Vincent Mailhol
@ 2022-07-26 10:24   ` Vincent Mailhol
  2022-07-27  8:06     ` Marc Kleine-Budde
  13 siblings, 1 reply; 92+ messages in thread
From: Vincent Mailhol @ 2022-07-26 10:24 UTC (permalink / raw)
  To: linux-can, Marc Kleine-Budde
  Cc: Stephane Grosjean, Jimmy Assarsson, Oliver Hartkopp,
	Dario Binacchi, Max Staudt, Vincent Mailhol

Currently, userland has no method to query which timestamping features
are supported by the peak_usb driver (aside maybe of getting RX
messages and obseverse whever or not hardware timestamps stay at
zero).

The canonical way for a network driver to advertise what kind of
timestamping it supports is to implement
ethtool_ops::get_ts_info(). Here, we use the CAN specific
can_ethtool_op_get_ts_info_hwts() function to achieve this.

In addition, the driver currently does not support the hardware
timestamps ioctls. According to [1], SIOCSHWTSTAMP is "must" and
SIOCGHWTSTAMP is "should". This patch fills up that gap by
implementing net_device_ops::ndo_eth_ioctl() using the CAN specific
function can_eth_ioctl_hwts().

[1] kernel doc Timestamping, section 3.1: "Hardware Timestamping
Implementation: Device Drivers"
Link: https://docs.kernel.org/networking/timestamping.html#hardware-timestamping-implementation-device-drivers

CC: Stephane Grosjean <s.grosjean@peak-system.com>
Signed-off-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
---

Hi Stéphane, as far as I understand, the pcan_usb and the pacn_usb_pro
support hardware timestamps but the pcan_usb_fd doesn't. If not the
case, let me know.

This is not tested. If you find any issue or if you want to modify,
feel free to pick up that patch and resend it.
---
 drivers/net/can/usb/peak_usb/pcan_usb.c      |  2 ++
 drivers/net/can/usb/peak_usb/pcan_usb_core.c | 12 ++++++++++--
 drivers/net/can/usb/peak_usb/pcan_usb_core.h |  4 ++++
 drivers/net/can/usb/peak_usb/pcan_usb_fd.c   |  2 ++
 drivers/net/can/usb/peak_usb/pcan_usb_pro.c  |  2 ++
 5 files changed, 20 insertions(+), 2 deletions(-)

diff --git a/drivers/net/can/usb/peak_usb/pcan_usb.c b/drivers/net/can/usb/peak_usb/pcan_usb.c
index d07b7ee79e3e..23966d5d7825 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb.c
+++ b/drivers/net/can/usb/peak_usb/pcan_usb.c
@@ -965,6 +965,7 @@ static int pcan_usb_set_phys_id(struct net_device *netdev,
 
 static const struct ethtool_ops pcan_usb_ethtool_ops = {
 	.set_phys_id = pcan_usb_set_phys_id,
+	.get_ts_info = can_ethtool_op_get_ts_info_hwts,
 };
 
 /*
@@ -996,6 +997,7 @@ const struct peak_usb_adapter pcan_usb = {
 	/* size of device private data */
 	.sizeof_dev_private = sizeof(struct pcan_usb),
 
+	.netdev_ops = &pcan_usb_netdev_ops,
 	.ethtool_ops = &pcan_usb_ethtool_ops,
 
 	/* timestamps usage */
diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_core.c b/drivers/net/can/usb/peak_usb/pcan_usb_core.c
index 27b0a72fd885..88d0505d3f8d 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb_core.c
+++ b/drivers/net/can/usb/peak_usb/pcan_usb_core.c
@@ -775,13 +775,21 @@ static int peak_usb_set_data_bittiming(struct net_device *netdev)
 	return 0;
 }
 
-static const struct net_device_ops peak_usb_netdev_ops = {
+const struct net_device_ops pcan_usb_netdev_ops = {
 	.ndo_open = peak_usb_ndo_open,
 	.ndo_stop = peak_usb_ndo_stop,
 	.ndo_start_xmit = peak_usb_ndo_start_xmit,
 	.ndo_change_mtu = can_change_mtu,
 };
 
+const struct net_device_ops pcan_usb_netdev_ops_hwts = {
+	.ndo_open = peak_usb_ndo_open,
+	.ndo_stop = peak_usb_ndo_stop,
+	.ndo_eth_ioctl = can_eth_ioctl_hwts,
+	.ndo_start_xmit = peak_usb_ndo_start_xmit,
+	.ndo_change_mtu = can_change_mtu,
+};
+
 /*
  * create one device which is attached to CAN controller #ctrl_idx of the
  * usb adapter.
@@ -833,7 +841,7 @@ static int peak_usb_create_dev(const struct peak_usb_adapter *peak_usb_adapter,
 	dev->can.do_get_berr_counter = peak_usb_adapter->do_get_berr_counter;
 	dev->can.ctrlmode_supported = peak_usb_adapter->ctrlmode_supported;
 
-	netdev->netdev_ops = &peak_usb_netdev_ops;
+	netdev->netdev_ops = peak_usb_adapter->netdev_ops;
 
 	netdev->flags |= IFF_ECHO; /* we support local echo */
 
diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_core.h b/drivers/net/can/usb/peak_usb/pcan_usb_core.h
index 9c90487b9c92..a7412235d36f 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb_core.h
+++ b/drivers/net/can/usb/peak_usb/pcan_usb_core.h
@@ -46,6 +46,7 @@ struct peak_usb_adapter {
 	const struct can_bittiming_const * const data_bittiming_const;
 	unsigned int ctrl_count;
 
+	const struct net_device_ops *netdev_ops;
 	const struct ethtool_ops *ethtool_ops;
 
 	int (*intf_probe)(struct usb_interface *intf);
@@ -88,6 +89,9 @@ extern const struct peak_usb_adapter pcan_usb_chip;
 extern const struct peak_usb_adapter pcan_usb_pro_fd;
 extern const struct peak_usb_adapter pcan_usb_x6;
 
+extern const struct net_device_ops pcan_usb_netdev_ops;
+extern const struct net_device_ops pcan_usb_netdev_ops_hwts;
+
 struct peak_time_ref {
 	ktime_t tv_host_0, tv_host;
 	u32 ts_dev_1, ts_dev_2;
diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_fd.c b/drivers/net/can/usb/peak_usb/pcan_usb_fd.c
index 3d7e0e370505..8560f82b0ab2 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb_fd.c
+++ b/drivers/net/can/usb/peak_usb/pcan_usb_fd.c
@@ -1080,6 +1080,7 @@ static int pcan_usb_fd_set_phys_id(struct net_device *netdev,
 
 static const struct ethtool_ops pcan_usb_fd_ethtool_ops = {
 	.set_phys_id = pcan_usb_fd_set_phys_id,
+	.get_ts_info = ethtool_op_get_ts_info,
 };
 
 /* describes the PCAN-USB FD adapter */
@@ -1123,6 +1124,7 @@ const struct peak_usb_adapter pcan_usb_fd = {
 	/* size of device private data */
 	.sizeof_dev_private = sizeof(struct pcan_usb_fd_device),
 
+	.netdev_ops = &pcan_usb_netdev_ops_hwts,
 	.ethtool_ops = &pcan_usb_fd_ethtool_ops,
 
 	/* timestamps usage */
diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_pro.c b/drivers/net/can/usb/peak_usb/pcan_usb_pro.c
index 457887113e75..13b2d82047c7 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb_pro.c
+++ b/drivers/net/can/usb/peak_usb/pcan_usb_pro.c
@@ -1022,6 +1022,7 @@ static int pcan_usb_pro_set_phys_id(struct net_device *netdev,
 
 static const struct ethtool_ops pcan_usb_pro_ethtool_ops = {
 	.set_phys_id = pcan_usb_pro_set_phys_id,
+	.get_ts_info = can_ethtool_op_get_ts_info_hwts,
 };
 
 /*
@@ -1053,6 +1054,7 @@ const struct peak_usb_adapter pcan_usb_pro = {
 	/* size of device private data */
 	.sizeof_dev_private = sizeof(struct pcan_usb_pro_device),
 
+	.netdev_ops = &pcan_usb_netdev_ops_hwts,
 	.ethtool_ops = &pcan_usb_pro_ethtool_ops,
 
 	/* timestamps usage */
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 92+ messages in thread

* Re: [PATCH v3 14/14] can: peak_usb: advertise timestamping capabilities and add ioctl support
  2022-07-26 10:24   ` [PATCH v3 14/14] can: peak_usb: " Vincent Mailhol
@ 2022-07-27  8:06     ` Marc Kleine-Budde
  2022-07-27  8:29       ` Vincent MAILHOL
  0 siblings, 1 reply; 92+ messages in thread
From: Marc Kleine-Budde @ 2022-07-27  8:06 UTC (permalink / raw)
  To: Vincent Mailhol
  Cc: linux-can, Stephane Grosjean, Jimmy Assarsson, Oliver Hartkopp,
	Dario Binacchi, Max Staudt

[-- Attachment #1: Type: text/plain, Size: 2294 bytes --]

On 26.07.2022 19:24:54, Vincent Mailhol wrote:
> Currently, userland has no method to query which timestamping features
> are supported by the peak_usb driver (aside maybe of getting RX
> messages and obseverse whever or not hardware timestamps stay at
> zero).
> 
> The canonical way for a network driver to advertise what kind of
> timestamping it supports is to implement
> ethtool_ops::get_ts_info(). Here, we use the CAN specific
> can_ethtool_op_get_ts_info_hwts() function to achieve this.
> 
> In addition, the driver currently does not support the hardware
> timestamps ioctls. According to [1], SIOCSHWTSTAMP is "must" and
> SIOCGHWTSTAMP is "should". This patch fills up that gap by
> implementing net_device_ops::ndo_eth_ioctl() using the CAN specific
> function can_eth_ioctl_hwts().
> 
> [1] kernel doc Timestamping, section 3.1: "Hardware Timestamping
> Implementation: Device Drivers"
> Link: https://docs.kernel.org/networking/timestamping.html#hardware-timestamping-implementation-device-drivers
> 
> CC: Stephane Grosjean <s.grosjean@peak-system.com>
> Signed-off-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
> ---
> 
> Hi Stéphane, as far as I understand, the pcan_usb and the pacn_usb_pro
                                                            ^^^^
                                                            pcan

> support hardware timestamps but the pcan_usb_fd doesn't. If not the
> case, let me know.
> 
> This is not tested. If you find any issue or if you want to modify,
> feel free to pick up that patch and resend it.

I have a:

| Bus 002 Device 009: ID 0c72:0012 PEAK System PCAN-USB FD

It supports hardware RX timestamps (Debian kernel 5.18.0-2-amd64) only:

|  (1970-01-01 01:00:00.000000)  peakfd0  TX - -  002   [1]  01
|  (1970-01-01 02:17:09.473817)  peakfd0  RX - -  002   [1]  3C
|  (1970-01-01 01:00:00.000000)  peakfd0  TX - -  002   [1]  02
|  (1970-01-01 02:17:09.673980)  peakfd0  RX - -  002   [1]  3D

regards,
Marc

-- 
Pengutronix e.K.                 | Marc Kleine-Budde           |
Embedded Linux                   | https://www.pengutronix.de  |
Vertretung West/Dortmund         | Phone: +49-231-2826-924     |
Amtsgericht Hildesheim, HRA 2686 | Fax:   +49-5121-206917-5555 |

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 92+ messages in thread

* Re: [PATCH v1 10/24] can: tree-wide: implement ethtool_ops::get_drvinfo()
  2022-07-26  9:59         ` Vincent MAILHOL
@ 2022-07-27  8:19           ` Marc Kleine-Budde
  2022-07-27  9:05             ` Vincent MAILHOL
  0 siblings, 1 reply; 92+ messages in thread
From: Marc Kleine-Budde @ 2022-07-27  8:19 UTC (permalink / raw)
  To: Vincent MAILHOL
  Cc: Dario Binacchi, linux-can, Stephane Grosjean, Jimmy Assarsson,
	Oliver Hartkopp, Max Staudt

[-- Attachment #1: Type: text/plain, Size: 2071 bytes --]

On 26.07.2022 18:59:18, Vincent MAILHOL wrote:
> > > Does it make sense?
> >
> > I have already used this scheme in the c_can driver. I used this
> > scheme because I saw that it was used a lot
> > (git grep set_ethtool_ops) in the kernel.
> 
> | $ git grep "void .*_set_ethtool_ops.*;" | wc -l
> | 46
> | $ git grep "extern const struct ethtool_ops" | wc -l
> | 43
> 
> I did not know it was a good practice, but you are right, both schemes
> are roughly as popular (with yours slightly more popular by a small
> margin).
> 
> > By doing so you can define
> > slcan_ethtool_ops as a static variable
> > and if possible I prefer to export functions rather than data. But it
> > can be a matter of taste.
> 
> My taste is to export the data (to remove a function call), but as the
> maintainer, your opinion should prevail here.

I think with exporting the data instead of the function, the resulting
module will be a bit smaller. As we don't use LTO by default there's no
optimization between object files. The size of the resulting modules can
be checked with:

| ./scripts/bloat-o-meter old.o new.o

> And thanks for the explanation.
> 
> I will also fix those two drivers:
> 
> | $ git grep "void .*_set_ethtool_ops.*;" drivers/net/can/
> | drivers/net/can/c_can/c_can.h:void c_can_set_ethtool_ops(struct
> net_device *dev);
> | drivers/net/can/flexcan/flexcan.h:void
> flexcan_set_ethtool_ops(struct net_device *dev);

In the mcp251xfd driver there is mcp251xfd_ethtool_init(). This function
sets the ethtool_ops, but also initializes the parameters that can be
configured by ethtool (ring layout and coalescing) to default values.

Other drivers that have a dedicated function that assigns ethtool_ops
only can be optimized IMHO.

regards,
Marc

-- 
Pengutronix e.K.                 | Marc Kleine-Budde           |
Embedded Linux                   | https://www.pengutronix.de  |
Vertretung West/Dortmund         | Phone: +49-231-2826-924     |
Amtsgericht Hildesheim, HRA 2686 | Fax:   +49-5121-206917-5555 |

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 92+ messages in thread

* Re: [PATCH v3 14/14] can: peak_usb: advertise timestamping capabilities and add ioctl support
  2022-07-27  8:06     ` Marc Kleine-Budde
@ 2022-07-27  8:29       ` Vincent MAILHOL
  2022-07-27  8:42         ` Marc Kleine-Budde
  0 siblings, 1 reply; 92+ messages in thread
From: Vincent MAILHOL @ 2022-07-27  8:29 UTC (permalink / raw)
  To: Marc Kleine-Budde
  Cc: linux-can, Stephane Grosjean, Jimmy Assarsson, Oliver Hartkopp,
	Dario Binacchi, Max Staudt

On Wed. 27 Jul. 2022 at 17:10, Marc Kleine-Budde <mkl@pengutronix.de> wrote:
> On 26.07.2022 19:24:54, Vincent Mailhol wrote:
> > Currently, userland has no method to query which timestamping features
> > are supported by the peak_usb driver (aside maybe of getting RX
> > messages and obseverse whever or not hardware timestamps stay at
> > zero).
> >
> > The canonical way for a network driver to advertise what kind of
> > timestamping it supports is to implement
> > ethtool_ops::get_ts_info(). Here, we use the CAN specific
> > can_ethtool_op_get_ts_info_hwts() function to achieve this.
> >
> > In addition, the driver currently does not support the hardware
> > timestamps ioctls. According to [1], SIOCSHWTSTAMP is "must" and
> > SIOCGHWTSTAMP is "should". This patch fills up that gap by
> > implementing net_device_ops::ndo_eth_ioctl() using the CAN specific
> > function can_eth_ioctl_hwts().
> >
> > [1] kernel doc Timestamping, section 3.1: "Hardware Timestamping
> > Implementation: Device Drivers"
> > Link: https://docs.kernel.org/networking/timestamping.html#hardware-timestamping-implementation-device-drivers
> >
> > CC: Stephane Grosjean <s.grosjean@peak-system.com>
> > Signed-off-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
> > ---
> >
> > Hi Stéphane, as far as I understand, the pcan_usb and the pacn_usb_pro
>                                                             ^^^^
>                                                             pcan
>
> > support hardware timestamps but the pcan_usb_fd doesn't. If not the
> > case, let me know.
> >
> > This is not tested. If you find any issue or if you want to modify,
> > feel free to pick up that patch and resend it.
>
> I have a:
>
> | Bus 002 Device 009: ID 0c72:0012 PEAK System PCAN-USB FD
>
> It supports hardware RX timestamps (Debian kernel 5.18.0-2-amd64) only:
>
> |  (1970-01-01 01:00:00.000000)  peakfd0  TX - -  002   [1]  01
> |  (1970-01-01 02:17:09.473817)  peakfd0  RX - -  002   [1]  3C
> |  (1970-01-01 01:00:00.000000)  peakfd0  TX - -  002   [1]  02
> |  (1970-01-01 02:17:09.673980)  peakfd0  RX - -  002   [1]  3D

Thanks for the confirmation. So this means that all Peak hardware
supports the hardware timestamping. This will greatly simplify the
logic. No need to have two different struct ethtool_ops. I will
prepare a v4.

Yours sincerely,
Vincent Mailhol

^ permalink raw reply	[flat|nested] 92+ messages in thread

* Re: [PATCH v3 14/14] can: peak_usb: advertise timestamping capabilities and add ioctl support
  2022-07-27  8:29       ` Vincent MAILHOL
@ 2022-07-27  8:42         ` Marc Kleine-Budde
  2022-07-27  9:17           ` Vincent MAILHOL
  0 siblings, 1 reply; 92+ messages in thread
From: Marc Kleine-Budde @ 2022-07-27  8:42 UTC (permalink / raw)
  To: Vincent MAILHOL
  Cc: linux-can, Stephane Grosjean, Jimmy Assarsson, Oliver Hartkopp,
	Dario Binacchi, Max Staudt

[-- Attachment #1: Type: text/plain, Size: 3410 bytes --]

On 27.07.2022 17:29:25, Vincent MAILHOL wrote:
> On Wed. 27 Jul. 2022 at 17:10, Marc Kleine-Budde <mkl@pengutronix.de> wrote:
> > On 26.07.2022 19:24:54, Vincent Mailhol wrote:
> > > Currently, userland has no method to query which timestamping features
> > > are supported by the peak_usb driver (aside maybe of getting RX
> > > messages and obseverse whever or not hardware timestamps stay at
> > > zero).
> > >
> > > The canonical way for a network driver to advertise what kind of
> > > timestamping it supports is to implement
> > > ethtool_ops::get_ts_info(). Here, we use the CAN specific
> > > can_ethtool_op_get_ts_info_hwts() function to achieve this.
> > >
> > > In addition, the driver currently does not support the hardware
> > > timestamps ioctls. According to [1], SIOCSHWTSTAMP is "must" and
> > > SIOCGHWTSTAMP is "should". This patch fills up that gap by
> > > implementing net_device_ops::ndo_eth_ioctl() using the CAN specific
> > > function can_eth_ioctl_hwts().
> > >
> > > [1] kernel doc Timestamping, section 3.1: "Hardware Timestamping
> > > Implementation: Device Drivers"
> > > Link: https://docs.kernel.org/networking/timestamping.html#hardware-timestamping-implementation-device-drivers
> > >
> > > CC: Stephane Grosjean <s.grosjean@peak-system.com>
> > > Signed-off-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
> > > ---
> > >
> > > Hi Stéphane, as far as I understand, the pcan_usb and the pacn_usb_pro
> >                                                             ^^^^
> >                                                             pcan
> >
> > > support hardware timestamps but the pcan_usb_fd doesn't. If not the
> > > case, let me know.
> > >
> > > This is not tested. If you find any issue or if you want to modify,
> > > feel free to pick up that patch and resend it.
> >
> > I have a:
> >
> > | Bus 002 Device 009: ID 0c72:0012 PEAK System PCAN-USB FD
> >
> > It supports hardware RX timestamps (Debian kernel 5.18.0-2-amd64) only:
> >
> > |  (1970-01-01 01:00:00.000000)  peakfd0  TX - -  002   [1]  01
> > |  (1970-01-01 02:17:09.473817)  peakfd0  RX - -  002   [1]  3C
> > |  (1970-01-01 01:00:00.000000)  peakfd0  TX - -  002   [1]  02
> > |  (1970-01-01 02:17:09.673980)  peakfd0  RX - -  002   [1]  3D
> 
> Thanks for the confirmation. So this means that all Peak hardware
> supports the hardware timestamping.

The PCAN-USB FD only support RX hardware timestamping, not TX.

> This will greatly simplify the
> logic. No need to have two different struct ethtool_ops. I will
> prepare a v4.

We have a peak_pciefd card:

| 01:00.0 Network controller: PEAK-System Technik GmbH Device 0018 (rev 01)

Only RX HW timestamps (Debian kernel 5.16.0-0.bpo.4-amd64):

|  (1970-01-01 01:00:00.000000)  can0_iobus  TX - -  601   [8]  40 0C 21 01 00 00 00 00
|  (1970-02-16 18:25:06.810100)  can0_iobus  RX - -  581   [8]  53 0C 21 01 00 00 00 00
|  (1970-01-01 01:00:00.000000)  can0_iobus  TX - -  602   [8]  40 0C 21 01 00 00 00 00
|  (1970-02-16 18:25:06.819380)  can0_iobus  RX - -  582   [8]  53 0C 21 01 00 00 00 00

Marc

-- 
Pengutronix e.K.                 | Marc Kleine-Budde           |
Embedded Linux                   | https://www.pengutronix.de  |
Vertretung West/Dortmund         | Phone: +49-231-2826-924     |
Amtsgericht Hildesheim, HRA 2686 | Fax:   +49-5121-206917-5555 |

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 92+ messages in thread

* Re: [PATCH v1 10/24] can: tree-wide: implement ethtool_ops::get_drvinfo()
  2022-07-27  8:19           ` Marc Kleine-Budde
@ 2022-07-27  9:05             ` Vincent MAILHOL
  2022-07-27 11:19               ` Marc Kleine-Budde
  0 siblings, 1 reply; 92+ messages in thread
From: Vincent MAILHOL @ 2022-07-27  9:05 UTC (permalink / raw)
  To: Marc Kleine-Budde
  Cc: Dario Binacchi, linux-can, Stephane Grosjean, Jimmy Assarsson,
	Oliver Hartkopp, Max Staudt

On Wed. 27 Jul. 2022 at 17:20, Marc Kleine-Budde <mkl@pengutronix.de> wrote:
> On 26.07.2022 18:59:18, Vincent MAILHOL wrote:
> > > > Does it make sense?
> > >
> > > I have already used this scheme in the c_can driver. I used this
> > > scheme because I saw that it was used a lot
> > > (git grep set_ethtool_ops) in the kernel.
> >
> > | $ git grep "void .*_set_ethtool_ops.*;" | wc -l
> > | 46
> > | $ git grep "extern const struct ethtool_ops" | wc -l
> > | 43
> >
> > I did not know it was a good practice, but you are right, both schemes
> > are roughly as popular (with yours slightly more popular by a small
> > margin).
> >
> > > By doing so you can define
> > > slcan_ethtool_ops as a static variable
> > > and if possible I prefer to export functions rather than data. But it
> > > can be a matter of taste.
> >
> > My taste is to export the data (to remove a function call), but as the
> > maintainer, your opinion should prevail here.
>
> I think with exporting the data instead of the function, the resulting
> module will be a bit smaller. As we don't use LTO by default there's no
> optimization between object files. The size of the resulting modules can
> be checked with:

Yes, the additional function call goes with additional assembly
instruction. I did not mention it but this goes in pairs.

> | ./scripts/bloat-o-meter old.o new.o

$ ./scripts/bloat-o-meter drivers/net/can/slcan/slcan.old.o
drivers/net/can/slcan/slcan.o
add/remove: 0/1 grow/shrink: 1/0 up/down: 15/-29 (-14)
Function                                     old     new   delta
slcan_open                                  1010    1025     +15
slcan_set_ethtool_ops                         29       -     -29
Total: Before=11115, After=11101, chg -0.13%

slcan.old.o is the current one which uses the set_ethtool_ops()
function, the slcan.o exports the structure instead.

It saves 14 bytes (and a function call).

> > And thanks for the explanation.
> >
> > I will also fix those two drivers:
> >
> > | $ git grep "void .*_set_ethtool_ops.*;" drivers/net/can/
> > | drivers/net/can/c_can/c_can.h:void c_can_set_ethtool_ops(struct
> > net_device *dev);
> > | drivers/net/can/flexcan/flexcan.h:void
> > flexcan_set_ethtool_ops(struct net_device *dev);
>
> In the mcp251xfd driver there is mcp251xfd_ethtool_init(). This function
> sets the ethtool_ops, but also initializes the parameters that can be
> configured by ethtool (ring layout and coalescing) to default values.

Yes, also the mcp251xfd is already fixed in v3.

> Other drivers that have a dedicated function that assigns ethtool_ops
> only can be optimized IMHO.

Yes, but this is not related to the timestamp series. So if I do it, I
will do it separately (and I do not commit that I will do it).


Yours sincerely,
Vincent Mailhol

^ permalink raw reply	[flat|nested] 92+ messages in thread

* Re: [PATCH v3 14/14] can: peak_usb: advertise timestamping capabilities and add ioctl support
  2022-07-27  8:42         ` Marc Kleine-Budde
@ 2022-07-27  9:17           ` Vincent MAILHOL
  0 siblings, 0 replies; 92+ messages in thread
From: Vincent MAILHOL @ 2022-07-27  9:17 UTC (permalink / raw)
  To: Marc Kleine-Budde
  Cc: linux-can, Stephane Grosjean, Jimmy Assarsson, Oliver Hartkopp,
	Dario Binacchi, Max Staudt

On Tue. 27 Jul. 2022 at 17:50, Marc Kleine-Budde <mkl@pengutronix.de> wrote:
> On 27.07.2022 17:29:25, Vincent MAILHOL wrote:
> > On Wed. 27 Jul. 2022 at 17:10, Marc Kleine-Budde <mkl@pengutronix.de> wrote:
> > > On 26.07.2022 19:24:54, Vincent Mailhol wrote:
> > > > Currently, userland has no method to query which timestamping features
> > > > are supported by the peak_usb driver (aside maybe of getting RX
> > > > messages and obseverse whever or not hardware timestamps stay at
> > > > zero).
> > > >
> > > > The canonical way for a network driver to advertise what kind of
> > > > timestamping it supports is to implement
> > > > ethtool_ops::get_ts_info(). Here, we use the CAN specific
> > > > can_ethtool_op_get_ts_info_hwts() function to achieve this.
> > > >
> > > > In addition, the driver currently does not support the hardware
> > > > timestamps ioctls. According to [1], SIOCSHWTSTAMP is "must" and
> > > > SIOCGHWTSTAMP is "should". This patch fills up that gap by
> > > > implementing net_device_ops::ndo_eth_ioctl() using the CAN specific
> > > > function can_eth_ioctl_hwts().
> > > >
> > > > [1] kernel doc Timestamping, section 3.1: "Hardware Timestamping
> > > > Implementation: Device Drivers"
> > > > Link: https://docs.kernel.org/networking/timestamping.html#hardware-timestamping-implementation-device-drivers
> > > >
> > > > CC: Stephane Grosjean <s.grosjean@peak-system.com>
> > > > Signed-off-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
> > > > ---
> > > >
> > > > Hi Stéphane, as far as I understand, the pcan_usb and the pacn_usb_pro
> > >                                                             ^^^^
> > >                                                             pcan
> > >
> > > > support hardware timestamps but the pcan_usb_fd doesn't. If not the
> > > > case, let me know.
> > > >
> > > > This is not tested. If you find any issue or if you want to modify,
> > > > feel free to pick up that patch and resend it.
> > >
> > > I have a:
> > >
> > > | Bus 002 Device 009: ID 0c72:0012 PEAK System PCAN-USB FD
> > >
> > > It supports hardware RX timestamps (Debian kernel 5.18.0-2-amd64) only:
> > >
> > > |  (1970-01-01 01:00:00.000000)  peakfd0  TX - -  002   [1]  01
> > > |  (1970-01-01 02:17:09.473817)  peakfd0  RX - -  002   [1]  3C
> > > |  (1970-01-01 01:00:00.000000)  peakfd0  TX - -  002   [1]  02
> > > |  (1970-01-01 02:17:09.673980)  peakfd0  RX - -  002   [1]  3D
> >
> > Thanks for the confirmation. So this means that all Peak hardware
> > supports the hardware timestamping.
>
> The PCAN-USB FD only support RX hardware timestamping, not TX.

> > This will greatly simplify the
> > logic. No need to have two different struct ethtool_ops. I will
> > prepare a v4.
>
> We have a peak_pciefd card:
>
> | 01:00.0 Network controller: PEAK-System Technik GmbH Device 0018 (rev 01)
>
> Only RX HW timestamps (Debian kernel 5.16.0-0.bpo.4-amd64):
>
> |  (1970-01-01 01:00:00.000000)  can0_iobus  TX - -  601   [8]  40 0C 21 01 00 00 00 00
> |  (1970-02-16 18:25:06.810100)  can0_iobus  RX - -  581   [8]  53 0C 21 01 00 00 00 00
> |  (1970-01-01 01:00:00.000000)  can0_iobus  TX - -  602   [8]  40 0C 21 01 00 00 00 00
> |  (1970-02-16 18:25:06.819380)  can0_iobus  RX - -  582   [8]  53 0C 21 01 00 00 00 00

O_o
This comes as a surprise.

I read your first message too quick and did not get the nuance that
only *RX* hardware timestamp was supported.

After investigation, I found this message from Stéphane:

| Those hw tx timestamps are not supported by the peak_usb
| driver: your socket-can application will receive "local
| software" TX timestamps only, corresponding roughly to the time
| the CAN frame has been given to the USB core of the kernel.
|
| However, this is possible with our pcan driver: you can get
| an "echoed" message with a HW TX timestamp for each message
| your application sends.

Source: https://forum.peak-system.com/viewtopic.php?t=5572#p12913

So the hardware does support it, it is just that the mainstream driver
does not implement it.


Yours sincerely,
Vincent Mailhol

^ permalink raw reply	[flat|nested] 92+ messages in thread

* [PATCH v4 00/14] can: add ethtool support and reporting of timestamping capabilities
  2022-07-25 13:31 [PATCH v1 00/24] can: add ethtool support and reporting of timestamping capabilities Vincent Mailhol
                   ` (26 preceding siblings ...)
  2022-07-26 10:24 ` [PATCH v3 00/14] Vincent Mailhol
@ 2022-07-27 10:16 ` Vincent Mailhol
  2022-07-27 10:16   ` [PATCH v4 01/14] can: can327: add software tx timestamps Vincent Mailhol
                     ` (14 more replies)
  27 siblings, 15 replies; 92+ messages in thread
From: Vincent Mailhol @ 2022-07-27 10:16 UTC (permalink / raw)
  To: linux-can, Marc Kleine-Budde
  Cc: Stephane Grosjean, Jimmy Assarsson, Oliver Hartkopp,
	Dario Binacchi, Max Staudt, Vincent Mailhol

This series revolves around ethtool and timestamping. Its ultimate
goal is that the timestamping implementation within socketCAN meets
the specification of other network drivers in the kernel. This way,
tcpdump or other tools derived from libpcap can be used to do
timestamping on CAN devices.

* Example on a device with hardware timestamp support *

Before this series:
| # tcpdump -j adapter_unsynced -i can0
| tcpdump: WARNING: When trying to set timestamp type
| 'adapter_unsynced' on can0: That type of time stamp is not supported
| by that device

After applying this series, the warning disappears and tcpdump can be
used to get RX hardware timestamps.


This series is articulated in three major parts.

* Part 1: Add TX software timestamps and report the software
  timestamping capabilities through ethtool.

All the drivers using can_put_echo_skb() already support TX software
timestamps. However, the five drivers not using this function (namely
can327, janz-ican3, slcan, vcan and vxcan) lack such support. Patch 1
to 4 adds this support.  Finally, patch 5 advertises the timesamping
capabilities of all drivers which do not support hardware timestamps.


* Part 2: add TX hardware timestapms

This part is a single patch. In SocketCAN TX hardware is equal to the
RX hardware timestamps of the corresponding loopback frame. Reuse the
TX hardware timestamp to populate the RX hardware timestamp. While the
need of this feature can be debatable, we implement it here so that
generic timestamping tools which are agnostic of the specificity of
SocketCAN can still obtain the value. For example, tcpdump expects for
both TX and RX hardware timestamps to be supported in order to do:
| # tcpdump -j adapter_unsynced -i canX


* Part 3: report the hardware timestamping capabilities and implement
  the hardware timestamps ioctls.

The kernel documentation specifies in [1] that, for the drivers which
support hardware timestamping, SIOCSHWTSTAMP ioctl must be supported
and that SIOCGHWTSTAMP ioctl should be supported. Currently, none of
the CAN drivers do so. This is a gap.

Furthermore, even if not specified, the tools based on libpcap
(e.g. tcpdump) also expect ethtool_ops::get_ts_info to be implemented.

This last part first adds some generic implementation of
net_device_ops::ndo_eth_ioctl and ethtool_ops::get_ts_info which can
be used by the drivers with hardware timestamping capabilities.

It then uses those generic functions to add ioctl and reporting
functionalities to the drivers with hardware timestamping support
(namely: mcp251xfd, etas_es58x, kvaser_{pciefd,usb}, peak_{canfd,usb})


[1] Kernel doc: Timestamping, section 3.1 "Hardware Timestamping
Implementation: Device Drivers"
Link: https://docs.kernel.org/networking/timestamping.html#hardware-timestamping-implementation-device-drivers


* Testing *

I also developed a tool to test all the different timestamps. For
those who would also like to test it, please have a look at:
https://lore.kernel.org/linux-can/20220725134345.432367-1-mailhol.vincent@wanadoo.fr/T/


* Changelog *

v3 -> v4:

  * The peak drivers (both PCI and USB) do not support hardware TX
    timestamps (only RX). Implement specific ioctl and ethtool
    callback functions for this device.

v2 -> v3:

  * The c_can, flexcan, mcp251xfd and the slcan drivers already
    declared a struct ethtool_ops. Do not declare again the same
    structure and instead populate the .get_ts_info() field of the
    existing structures.

v1 -> v2:

  * First series had a patch to implement
    ethtool_ops::get_drvinfo. This proved to be useless. This patch
    was removed and all the clean-up patches made in preparation of
    that one were moved to a separate series:

    https://lore.kernel.org/linux-can/20220725153124.467061-1-mailhol.vincent@wanadoo.fr/T/#u

Vincent Mailhol (14):
  can: can327: add software tx timestamps
  can: janz-ican3: add software tx timestamp
  can: slcan: add software tx timestamps
  can: v(x)can: add software tx timestamps
  can: tree-wide: advertise software timestamping capabilities
  can: dev: add hardware TX timestamp
  can: dev: add generic function can_ethtool_op_get_ts_info_hwts()
  can: dev: add generic function can_eth_ioctl_hwts()
  can: mcp251xfd: advertise timestamping capabilities and add ioctl
    support
  can: etas_es58x: advertise timestamping capabilities and add ioctl
    support
  can: kvaser_pciefd: advertise timestamping capabilities and add ioctl
    support
  can: kvaser_usb: advertise timestamping capabilities and add ioctl
    support
  can: peak_canfd: advertise timestamping capabilities and add ioctl
    support
  can: peak_usb: advertise timestamping capabilities and add ioctl
    support

 drivers/net/can/at91_can.c                    |  6 +++
 drivers/net/can/c_can/c_can_ethtool.c         |  1 +
 drivers/net/can/can327.c                      |  7 +++
 drivers/net/can/cc770/cc770.c                 |  6 +++
 drivers/net/can/ctucanfd/ctucanfd_base.c      |  6 +++
 drivers/net/can/dev/dev.c                     | 50 +++++++++++++++++++
 drivers/net/can/dev/skb.c                     |  6 +++
 drivers/net/can/flexcan/flexcan-ethtool.c     |  1 +
 drivers/net/can/grcan.c                       |  6 +++
 drivers/net/can/ifi_canfd/ifi_canfd.c         |  6 +++
 drivers/net/can/janz-ican3.c                  |  8 +++
 drivers/net/can/kvaser_pciefd.c               |  7 +++
 drivers/net/can/m_can/m_can.c                 |  6 +++
 drivers/net/can/mscan/mscan.c                 |  1 +
 drivers/net/can/pch_can.c                     |  6 +++
 drivers/net/can/peak_canfd/peak_canfd.c       | 48 ++++++++++++++++++
 drivers/net/can/rcar/rcar_can.c               |  6 +++
 drivers/net/can/rcar/rcar_canfd.c             |  6 +++
 drivers/net/can/sja1000/sja1000.c             |  6 +++
 drivers/net/can/slcan/slcan-core.c            |  2 +
 drivers/net/can/slcan/slcan-ethtool.c         |  1 +
 drivers/net/can/softing/softing_main.c        |  6 +++
 drivers/net/can/spi/hi311x.c                  |  6 +++
 drivers/net/can/spi/mcp251x.c                 |  6 +++
 .../net/can/spi/mcp251xfd/mcp251xfd-core.c    |  1 +
 .../net/can/spi/mcp251xfd/mcp251xfd-ethtool.c |  1 +
 drivers/net/can/sun4i_can.c                   |  6 +++
 drivers/net/can/ti_hecc.c                     |  6 +++
 drivers/net/can/usb/ems_usb.c                 |  6 +++
 drivers/net/can/usb/esd_usb.c                 |  6 +++
 drivers/net/can/usb/etas_es58x/es58x_core.c   |  9 +++-
 drivers/net/can/usb/gs_usb.c                  |  2 +
 drivers/net/can/usb/kvaser_usb/kvaser_usb.h   |  1 +
 .../net/can/usb/kvaser_usb/kvaser_usb_core.c  | 27 +++++++++-
 drivers/net/can/usb/mcba_usb.c                |  6 +++
 drivers/net/can/usb/peak_usb/pcan_usb.c       |  1 +
 drivers/net/can/usb/peak_usb/pcan_usb_core.c  | 41 +++++++++++++++
 drivers/net/can/usb/peak_usb/pcan_usb_core.h  |  1 +
 drivers/net/can/usb/peak_usb/pcan_usb_fd.c    |  1 +
 drivers/net/can/usb/peak_usb/pcan_usb_pro.c   |  1 +
 drivers/net/can/usb/ucan.c                    |  6 +++
 drivers/net/can/usb/usb_8dev.c                |  6 +++
 drivers/net/can/vcan.c                        |  8 +++
 drivers/net/can/vxcan.c                       |  8 +++
 drivers/net/can/xilinx_can.c                  |  6 +++
 include/linux/can/dev.h                       |  4 ++
 46 files changed, 361 insertions(+), 3 deletions(-)

-- 
2.35.1


^ permalink raw reply	[flat|nested] 92+ messages in thread

* [PATCH v4 01/14] can: can327: add software tx timestamps
  2022-07-27 10:16 ` [PATCH v4 00/14] can: add ethtool support and reporting of timestamping capabilities Vincent Mailhol
@ 2022-07-27 10:16   ` Vincent Mailhol
  2022-07-27 20:24     ` Max Staudt
  2022-07-27 10:16   ` [PATCH v4 02/14] can: janz-ican3: add software tx timestamp Vincent Mailhol
                     ` (13 subsequent siblings)
  14 siblings, 1 reply; 92+ messages in thread
From: Vincent Mailhol @ 2022-07-27 10:16 UTC (permalink / raw)
  To: linux-can, Marc Kleine-Budde
  Cc: Stephane Grosjean, Jimmy Assarsson, Oliver Hartkopp,
	Dario Binacchi, Max Staudt, Vincent Mailhol

TX timestamps were added to the can_put_echo_skb() function of can_dev
modules in [1]. However, can327 does not rely on that function and as
such does not offer TX timestamping.

Add a call to skb_tx_timestamp() in the can327_netdev_start_xmit()
function so that the module now supports TX software timestamps.

[1] commit 741b91f1b0ea ("can: dev: can_put_echo_skb(): add software
tx timestamps")
Link: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=741b91f1b0ea34f00f6a7d4539b767c409291fcf

Signed-off-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
---
 drivers/net/can/can327.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/net/can/can327.c b/drivers/net/can/can327.c
index 5da7778d92dc..88718d0cc569 100644
--- a/drivers/net/can/can327.c
+++ b/drivers/net/can/can327.c
@@ -836,6 +836,8 @@ static netdev_tx_t can327_netdev_start_xmit(struct sk_buff *skb,
 	dev->stats.tx_packets++;
 	dev->stats.tx_bytes += frame->can_id & CAN_RTR_FLAG ? 0 : frame->len;
 
+	skb_tx_timestamp(skb);
+
 out:
 	kfree_skb(skb);
 	return NETDEV_TX_OK;
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 92+ messages in thread

* [PATCH v4 02/14] can: janz-ican3: add software tx timestamp
  2022-07-27 10:16 ` [PATCH v4 00/14] can: add ethtool support and reporting of timestamping capabilities Vincent Mailhol
  2022-07-27 10:16   ` [PATCH v4 01/14] can: can327: add software tx timestamps Vincent Mailhol
@ 2022-07-27 10:16   ` Vincent Mailhol
  2022-07-27 10:16   ` [PATCH v4 03/14] can: slcan: add software tx timestamps Vincent Mailhol
                     ` (12 subsequent siblings)
  14 siblings, 0 replies; 92+ messages in thread
From: Vincent Mailhol @ 2022-07-27 10:16 UTC (permalink / raw)
  To: linux-can, Marc Kleine-Budde
  Cc: Stephane Grosjean, Jimmy Assarsson, Oliver Hartkopp,
	Dario Binacchi, Max Staudt, Vincent Mailhol

TX timestamps were added to the can_put_echo_skb() function of can_dev
modules in [1]. However, janz-ican3 does not rely on that function but
instead implements its own echo_skb logic. As such it does not offer
TX timestamping.

Add a call to skb_tx_timestamp() in the ican3_put_echo_skb() function
so that the module now supports TX software timestamps.

[1] commit 741b91f1b0ea ("can: dev: can_put_echo_skb(): add software
tx timestamps")
Link: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=741b91f1b0ea34f00f6a7d4539b767c409291fcf

Signed-off-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
---
 drivers/net/can/janz-ican3.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/net/can/janz-ican3.c b/drivers/net/can/janz-ican3.c
index ccb5c5405224..78d9190a4220 100644
--- a/drivers/net/can/janz-ican3.c
+++ b/drivers/net/can/janz-ican3.c
@@ -1277,6 +1277,8 @@ static void ican3_put_echo_skb(struct ican3_dev *mod, struct sk_buff *skb)
 	if (!skb)
 		return;
 
+	skb_tx_timestamp(skb);
+
 	/* save this skb for tx interrupt echo handling */
 	skb_queue_tail(&mod->echoq, skb);
 }
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 92+ messages in thread

* [PATCH v4 03/14] can: slcan: add software tx timestamps
  2022-07-27 10:16 ` [PATCH v4 00/14] can: add ethtool support and reporting of timestamping capabilities Vincent Mailhol
  2022-07-27 10:16   ` [PATCH v4 01/14] can: can327: add software tx timestamps Vincent Mailhol
  2022-07-27 10:16   ` [PATCH v4 02/14] can: janz-ican3: add software tx timestamp Vincent Mailhol
@ 2022-07-27 10:16   ` Vincent Mailhol
  2022-07-27 10:16   ` [PATCH v4 04/14] can: v(x)can: " Vincent Mailhol
                     ` (11 subsequent siblings)
  14 siblings, 0 replies; 92+ messages in thread
From: Vincent Mailhol @ 2022-07-27 10:16 UTC (permalink / raw)
  To: linux-can, Marc Kleine-Budde
  Cc: Stephane Grosjean, Jimmy Assarsson, Oliver Hartkopp,
	Dario Binacchi, Max Staudt, Vincent Mailhol

TX timestamps were added to the can_put_echo_skb() function of can_dev
modules in [1]. However, slcan does not rely on that function and as
such does not offer TX timestamping.

Add a call to skb_tx_timestamp() in the slc_xmit() function so that
the module now supports TX software timestamps.

[1] commit 741b91f1b0ea ("can: dev: can_put_echo_skb(): add software
tx timestamps")
Link: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=741b91f1b0ea34f00f6a7d4539b767c409291fcf

CC: Dario Binacchi <dario.binacchi@amarulasolutions.com>
Signed-off-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
---
 drivers/net/can/slcan/slcan-core.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/net/can/slcan/slcan-core.c b/drivers/net/can/slcan/slcan-core.c
index dc28e715bbe1..d4dbeb849432 100644
--- a/drivers/net/can/slcan/slcan-core.c
+++ b/drivers/net/can/slcan/slcan-core.c
@@ -626,6 +626,8 @@ static netdev_tx_t slc_xmit(struct sk_buff *skb, struct net_device *dev)
 	slc_encaps(sl, (struct can_frame *)skb->data); /* encaps & send */
 	spin_unlock(&sl->lock);
 
+	skb_tx_timestamp(skb);
+
 out:
 	kfree_skb(skb);
 	return NETDEV_TX_OK;
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 92+ messages in thread

* [PATCH v4 04/14] can: v(x)can: add software tx timestamps
  2022-07-27 10:16 ` [PATCH v4 00/14] can: add ethtool support and reporting of timestamping capabilities Vincent Mailhol
                     ` (2 preceding siblings ...)
  2022-07-27 10:16   ` [PATCH v4 03/14] can: slcan: add software tx timestamps Vincent Mailhol
@ 2022-07-27 10:16   ` Vincent Mailhol
  2022-07-27 10:16   ` [PATCH v4 05/14] can: tree-wide: advertise software timestamping capabilities Vincent Mailhol
                     ` (10 subsequent siblings)
  14 siblings, 0 replies; 92+ messages in thread
From: Vincent Mailhol @ 2022-07-27 10:16 UTC (permalink / raw)
  To: linux-can, Marc Kleine-Budde
  Cc: Stephane Grosjean, Jimmy Assarsson, Oliver Hartkopp,
	Dario Binacchi, Max Staudt, Vincent Mailhol

TX timestamps were added to the can_put_echo_skb() function of can_dev
modules in [1]. However, vcan and vxcan do not rely on that function
and as such do not offer TX timestamping.

While it could be arguable whether TX timestamps are really needed for
virtual interfaces, we prefer to still add it so that all CAN drivers,
without exception, support the software TX timestamps.

Add a call to skb_tx_timestamp() in the vcan_tx() and vxcan_xmit()
functions so that the modules now support TX software timestamps.

[1] commit 741b91f1b0ea ("can: dev: can_put_echo_skb(): add software
tx timestamps")
Link: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=741b91f1b0ea34f00f6a7d4539b767c409291fcf

Signed-off-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
---
 drivers/net/can/vcan.c  | 2 ++
 drivers/net/can/vxcan.c | 2 ++
 2 files changed, 4 insertions(+)

diff --git a/drivers/net/can/vcan.c b/drivers/net/can/vcan.c
index a15619d883ec..4a363cfcf97c 100644
--- a/drivers/net/can/vcan.c
+++ b/drivers/net/can/vcan.c
@@ -99,6 +99,8 @@ static netdev_tx_t vcan_tx(struct sk_buff *skb, struct net_device *dev)
 	/* set flag whether this packet has to be looped back */
 	loop = skb->pkt_type == PACKET_LOOPBACK;
 
+	skb_tx_timestamp(skb);
+
 	if (!echo) {
 		/* no echo handling available inside this driver */
 		if (loop) {
diff --git a/drivers/net/can/vxcan.c b/drivers/net/can/vxcan.c
index 577a80300514..61b6eca383f8 100644
--- a/drivers/net/can/vxcan.c
+++ b/drivers/net/can/vxcan.c
@@ -53,6 +53,8 @@ static netdev_tx_t vxcan_xmit(struct sk_buff *oskb, struct net_device *dev)
 		goto out_unlock;
 	}
 
+	skb_tx_timestamp(oskb);
+
 	skb = skb_clone(oskb, GFP_ATOMIC);
 	if (skb) {
 		consume_skb(oskb);
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 92+ messages in thread

* [PATCH v4 05/14] can: tree-wide: advertise software timestamping capabilities
  2022-07-27 10:16 ` [PATCH v4 00/14] can: add ethtool support and reporting of timestamping capabilities Vincent Mailhol
                     ` (3 preceding siblings ...)
  2022-07-27 10:16   ` [PATCH v4 04/14] can: v(x)can: " Vincent Mailhol
@ 2022-07-27 10:16   ` Vincent Mailhol
  2022-07-28  9:38     ` Marc Kleine-Budde
  2022-07-27 10:16   ` [PATCH v4 06/14] can: dev: add hardware TX timestamp Vincent Mailhol
                     ` (9 subsequent siblings)
  14 siblings, 1 reply; 92+ messages in thread
From: Vincent Mailhol @ 2022-07-27 10:16 UTC (permalink / raw)
  To: linux-can, Marc Kleine-Budde
  Cc: Stephane Grosjean, Jimmy Assarsson, Oliver Hartkopp,
	Dario Binacchi, Max Staudt, Vincent Mailhol

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>
---
 drivers/net/can/at91_can.c                | 6 ++++++
 drivers/net/can/c_can/c_can_ethtool.c     | 1 +
 drivers/net/can/can327.c                  | 5 +++++
 drivers/net/can/cc770/cc770.c             | 6 ++++++
 drivers/net/can/ctucanfd/ctucanfd_base.c  | 6 ++++++
 drivers/net/can/flexcan/flexcan-ethtool.c | 1 +
 drivers/net/can/grcan.c                   | 6 ++++++
 drivers/net/can/ifi_canfd/ifi_canfd.c     | 6 ++++++
 drivers/net/can/janz-ican3.c              | 6 ++++++
 drivers/net/can/m_can/m_can.c             | 6 ++++++
 drivers/net/can/mscan/mscan.c             | 1 +
 drivers/net/can/pch_can.c                 | 6 ++++++
 drivers/net/can/rcar/rcar_can.c           | 6 ++++++
 drivers/net/can/rcar/rcar_canfd.c         | 6 ++++++
 drivers/net/can/sja1000/sja1000.c         | 6 ++++++
 drivers/net/can/slcan/slcan-ethtool.c     | 1 +
 drivers/net/can/softing/softing_main.c    | 6 ++++++
 drivers/net/can/spi/hi311x.c              | 6 ++++++
 drivers/net/can/spi/mcp251x.c             | 6 ++++++
 drivers/net/can/sun4i_can.c               | 6 ++++++
 drivers/net/can/ti_hecc.c                 | 6 ++++++
 drivers/net/can/usb/ems_usb.c             | 6 ++++++
 drivers/net/can/usb/esd_usb.c             | 6 ++++++
 drivers/net/can/usb/gs_usb.c              | 2 ++
 drivers/net/can/usb/mcba_usb.c            | 6 ++++++
 drivers/net/can/usb/ucan.c                | 6 ++++++
 drivers/net/can/usb/usb_8dev.c            | 6 ++++++
 drivers/net/can/vcan.c                    | 6 ++++++
 drivers/net/can/vxcan.c                   | 6 ++++++
 drivers/net/can/xilinx_can.c              | 6 ++++++
 30 files changed, 155 insertions(+)

diff --git a/drivers/net/can/at91_can.c b/drivers/net/can/at91_can.c
index 29ed0d3cd171..3a2d109a3792 100644
--- a/drivers/net/can/at91_can.c
+++ b/drivers/net/can/at91_can.c
@@ -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>
@@ -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)
 {
@@ -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;
 
diff --git a/drivers/net/can/c_can/c_can_ethtool.c b/drivers/net/can/c_can/c_can_ethtool.c
index 8a826a6813bd..4994afc0826e 100644
--- a/drivers/net/can/c_can/c_can_ethtool.c
+++ b/drivers/net/can/c_can/c_can_ethtool.c
@@ -26,6 +26,7 @@ static void c_can_get_ringparam(struct net_device *netdev,
 
 static const struct ethtool_ops c_can_ethtool_ops = {
 	.get_ringparam = c_can_get_ringparam,
+	.get_ts_info = ethtool_op_get_ts_info,
 };
 
 void c_can_set_ethtool_ops(struct net_device *netdev)
diff --git a/drivers/net/can/can327.c b/drivers/net/can/can327.c
index 88718d0cc569..bfa33f5e7fbe 100644
--- a/drivers/net/can/can327.c
+++ b/drivers/net/can/can327.c
@@ -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'] = {
@@ -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;
diff --git a/drivers/net/can/cc770/cc770.c b/drivers/net/can/cc770/cc770.c
index 797a954bb1a0..0b9dfc76e769 100644
--- a/drivers/net/can/cc770/cc770.c
+++ b/drivers/net/can/cc770/cc770.c
@@ -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>
@@ -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);
@@ -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 */
 
diff --git a/drivers/net/can/ctucanfd/ctucanfd_base.c b/drivers/net/can/ctucanfd/ctucanfd_base.c
index 6b281f6eb9b4..3c18d028bd8c 100644
--- a/drivers/net/can/ctucanfd/ctucanfd_base.c
+++ b/drivers/net/can/ctucanfd/ctucanfd_base.c
@@ -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>
@@ -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);
@@ -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) {
diff --git a/drivers/net/can/flexcan/flexcan-ethtool.c b/drivers/net/can/flexcan/flexcan-ethtool.c
index 3ae535577700..8d9c45323da8 100644
--- a/drivers/net/can/flexcan/flexcan-ethtool.c
+++ b/drivers/net/can/flexcan/flexcan-ethtool.c
@@ -106,6 +106,7 @@ static 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,
 };
 
 void flexcan_set_ethtool_ops(struct net_device *netdev)
diff --git a/drivers/net/can/grcan.c b/drivers/net/can/grcan.c
index 24035a6187c9..6c37aab93eb3 100644
--- a/drivers/net/can/grcan.c
+++ b/drivers/net/can/grcan.c
@@ -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>
@@ -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)
@@ -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);
diff --git a/drivers/net/can/ifi_canfd/ifi_canfd.c b/drivers/net/can/ifi_canfd/ifi_canfd.c
index 64e3be8b73af..ad7a89b95da7 100644
--- a/drivers/net/can/ifi_canfd/ifi_canfd.c
+++ b/drivers/net/can/ifi_canfd/ifi_canfd.c
@@ -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>
@@ -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;
@@ -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;
diff --git a/drivers/net/can/janz-ican3.c b/drivers/net/can/janz-ican3.c
index 78d9190a4220..71a2caae0757 100644
--- a/drivers/net/can/janz-ican3.c
+++ b/drivers/net/can/janz-ican3.c
@@ -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>
@@ -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
  */
@@ -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);
 
diff --git a/drivers/net/can/m_can/m_can.c b/drivers/net/can/m_can/m_can.c
index 713a4b0edf86..4709c012b1dc 100644
--- a/drivers/net/can/m_can/m_can.c
+++ b/drivers/net/can/m_can/m_can.c
@@ -9,6 +9,7 @@
  */
 
 #include <linux/bitfield.h>
+#include <linux/ethtool.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
 #include <linux/kernel.h>
@@ -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);
 }
diff --git a/drivers/net/can/mscan/mscan.c b/drivers/net/can/mscan/mscan.c
index 78a21ab63601..b1677588a4c8 100644
--- a/drivers/net/can/mscan/mscan.c
+++ b/drivers/net/can/mscan/mscan.c
@@ -676,6 +676,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 */
 
diff --git a/drivers/net/can/pch_can.c b/drivers/net/can/pch_can.c
index 32804fed116c..0558ff67ec6a 100644
--- a/drivers/net/can/pch_can.c
+++ b/drivers/net/can/pch_can.c
@@ -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>
@@ -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);
@@ -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);
diff --git a/drivers/net/can/rcar/rcar_can.c b/drivers/net/can/rcar/rcar_can.c
index d11db2112a4a..6ee968c59ac9 100644
--- a/drivers/net/can/rcar/rcar_can.c
+++ b/drivers/net/can/rcar/rcar_can.c
@@ -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>
@@ -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;
@@ -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;
diff --git a/drivers/net/can/rcar/rcar_canfd.c b/drivers/net/can/rcar/rcar_canfd.c
index d3e569a02b4d..27085b796e75 100644
--- a/drivers/net/can/rcar/rcar_canfd.c
+++ b/drivers/net/can/rcar/rcar_canfd.c
@@ -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>
@@ -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)
 {
@@ -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;
diff --git a/drivers/net/can/sja1000/sja1000.c b/drivers/net/can/sja1000/sja1000.c
index 75a2f9bf8c16..98dfd5f295a7 100644
--- a/drivers/net/can/sja1000/sja1000.c
+++ b/drivers/net/can/sja1000/sja1000.c
@@ -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>
@@ -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;
@@ -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);
diff --git a/drivers/net/can/slcan/slcan-ethtool.c b/drivers/net/can/slcan/slcan-ethtool.c
index bf0afdc4e49d..e11d64de78a6 100644
--- a/drivers/net/can/slcan/slcan-ethtool.c
+++ b/drivers/net/can/slcan/slcan-ethtool.c
@@ -57,6 +57,7 @@ static 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,
 };
 
 void slcan_set_ethtool_ops(struct net_device *netdev)
diff --git a/drivers/net/can/softing/softing_main.c b/drivers/net/can/softing/softing_main.c
index 8d27ac66ca7f..27579f99ef74 100644
--- a/drivers/net/can/softing/softing_main.c
+++ b/drivers/net/can/softing/softing_main.c
@@ -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>
@@ -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 = "softing",
 	.tseg1_min = 1,
@@ -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;
 
diff --git a/drivers/net/can/spi/hi311x.c b/drivers/net/can/spi/hi311x.c
index 167114aae6dd..b87dc420428d 100644
--- a/drivers/net/can/spi/hi311x.c
+++ b/drivers/net/can/spi/hi311x.c
@@ -20,6 +20,7 @@
 #include <linux/completion.h>
 #include <linux/delay.h>
 #include <linux/device.h>
+#include <linux/ethtool.h>
 #include <linux/freezer.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
@@ -802,6 +803,10 @@ static const struct net_device_ops hi3110_netdev_ops = {
 	.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[] = {
 	{
 		.compatible	= "holt,hi3110",
@@ -856,6 +861,7 @@ static int hi3110_can_probe(struct spi_device *spi)
 		goto out_free;
 
 	net->netdev_ops = &hi3110_netdev_ops;
+	net->ethtool_ops = &hi3110_ethtool_ops;
 	net->flags |= IFF_ECHO;
 
 	priv = netdev_priv(net);
diff --git a/drivers/net/can/spi/mcp251x.c b/drivers/net/can/spi/mcp251x.c
index 666a4505a55a..e750d13c8841 100644
--- a/drivers/net/can/spi/mcp251x.c
+++ b/drivers/net/can/spi/mcp251x.c
@@ -26,6 +26,7 @@
 #include <linux/completion.h>
 #include <linux/delay.h>
 #include <linux/device.h>
+#include <linux/ethtool.h>
 #include <linux/freezer.h>
 #include <linux/gpio.h>
 #include <linux/gpio/driver.h>
@@ -1248,6 +1249,10 @@ static const struct net_device_ops mcp251x_netdev_ops = {
 	.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[] = {
 	{
 		.compatible	= "microchip,mcp2510",
@@ -1313,6 +1318,7 @@ static int mcp251x_can_probe(struct spi_device *spi)
 		goto out_free;
 
 	net->netdev_ops = &mcp251x_netdev_ops;
+	net->ethtool_ops = &mcp251x_ethtool_ops;
 	net->flags |= IFF_ECHO;
 
 	priv = netdev_priv(net);
diff --git a/drivers/net/can/sun4i_can.c b/drivers/net/can/sun4i_can.c
index b90dfb429ccd..525309da1320 100644
--- a/drivers/net/can/sun4i_can.c
+++ b/drivers/net/can/sun4i_can.c
@@ -53,6 +53,7 @@
 #include <linux/can/error.h>
 #include <linux/clk.h>
 #include <linux/delay.h>
+#include <linux/ethtool.h>
 #include <linux/interrupt.h>
 #include <linux/init.h>
 #include <linux/io.h>
@@ -761,6 +762,10 @@ static const struct net_device_ops sun4ican_netdev_ops = {
 	.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 = {
 	.has_reset = false,
 };
@@ -851,6 +856,7 @@ static int sun4ican_probe(struct platform_device *pdev)
 	}
 
 	dev->netdev_ops = &sun4ican_netdev_ops;
+	dev->ethtool_ops = &sun4ican_ethtool_ops;
 	dev->irq = irq;
 	dev->flags |= IFF_ECHO;
 
diff --git a/drivers/net/can/ti_hecc.c b/drivers/net/can/ti_hecc.c
index afa38771520e..ec0ffeeb2015 100644
--- a/drivers/net/can/ti_hecc.c
+++ b/drivers/net/can/ti_hecc.c
@@ -23,6 +23,7 @@
 #include <linux/types.h>
 #include <linux/interrupt.h>
 #include <linux/errno.h>
+#include <linux/ethtool.h>
 #include <linux/netdevice.h>
 #include <linux/skbuff.h>
 #include <linux/platform_device.h>
@@ -841,6 +842,10 @@ static const struct net_device_ops ti_hecc_netdev_ops = {
 	.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[] = {
 	{
 		.compatible = "ti,am3517-hecc",
@@ -918,6 +923,7 @@ static int ti_hecc_probe(struct platform_device *pdev)
 	platform_set_drvdata(pdev, ndev);
 	SET_NETDEV_DEV(ndev, &pdev->dev);
 	ndev->netdev_ops = &ti_hecc_netdev_ops;
+	ndev->ethtool_ops = &ti_hecc_ethtool_ops;
 
 	priv->clk = clk_get(&pdev->dev, "hecc_ck");
 	if (IS_ERR(priv->clk)) {
diff --git a/drivers/net/can/usb/ems_usb.c b/drivers/net/can/usb/ems_usb.c
index bbec3311d893..429fc53761d1 100644
--- a/drivers/net/can/usb/ems_usb.c
+++ b/drivers/net/can/usb/ems_usb.c
@@ -4,6 +4,7 @@
  *
  * Copyright (C) 2004-2009 EMS Dr. Thomas Wuensche
  */
+#include <linux/ethtool.h>
 #include <linux/signal.h>
 #include <linux/slab.h>
 #include <linux/module.h>
@@ -879,6 +880,10 @@ static const struct net_device_ops ems_usb_netdev_ops = {
 	.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 = {
 	.name = "ems_usb",
 	.tseg1_min = 1,
@@ -990,6 +995,7 @@ static int ems_usb_probe(struct usb_interface *intf,
 	dev->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES;
 
 	netdev->netdev_ops = &ems_usb_netdev_ops;
+	netdev->ethtool_ops = &ems_usb_ethtool_ops;
 
 	netdev->flags |= IFF_ECHO; /* we support local echo */
 
diff --git a/drivers/net/can/usb/esd_usb.c b/drivers/net/can/usb/esd_usb.c
index 177ed33e08d9..646cb85b3108 100644
--- a/drivers/net/can/usb/esd_usb.c
+++ b/drivers/net/can/usb/esd_usb.c
@@ -5,6 +5,7 @@
  * 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>
  */
+#include <linux/ethtool.h>
 #include <linux/signal.h>
 #include <linux/slab.h>
 #include <linux/module.h>
@@ -882,6 +883,10 @@ static const struct net_device_ops esd_usb_netdev_ops = {
 	.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 = {
 	.name = "esd_usb2",
 	.tseg1_min = ESD_USB2_TSEG1_MIN,
@@ -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->netdev_ops = &esd_usb_netdev_ops;
+	netdev->ethtool_ops = &esd_usb_ethtool_ops;
 
 	SET_NETDEV_DEV(netdev, &intf->dev);
 	netdev->dev_id = index;
diff --git a/drivers/net/can/usb/gs_usb.c b/drivers/net/can/usb/gs_usb.c
index d3a658b444b5..0b2172bc57f1 100644
--- a/drivers/net/can/usb/gs_usb.c
+++ b/drivers/net/can/usb/gs_usb.c
@@ -946,6 +946,7 @@ static int gs_usb_set_phys_id(struct net_device *dev,
 
 static const struct ethtool_ops gs_usb_ethtool_ops = {
 	.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,
@@ -989,6 +990,7 @@ static struct gs_can *gs_make_candev(unsigned int channel,
 	dev = netdev_priv(netdev);
 
 	netdev->netdev_ops = &gs_usb_netdev_ops;
+	netdev->ethtool_ops = &gs_usb_ethtool_ops;
 
 	netdev->flags |= IFF_ECHO; /* we support full roundtrip echo */
 
diff --git a/drivers/net/can/usb/mcba_usb.c b/drivers/net/can/usb/mcba_usb.c
index 792ab9da317d..69346c63021f 100644
--- a/drivers/net/can/usb/mcba_usb.c
+++ b/drivers/net/can/usb/mcba_usb.c
@@ -10,6 +10,7 @@
 #include <linux/can.h>
 #include <linux/can/dev.h>
 #include <linux/can/error.h>
+#include <linux/ethtool.h>
 #include <linux/module.h>
 #include <linux/netdevice.h>
 #include <linux/signal.h>
@@ -758,6 +759,10 @@ static const struct net_device_ops mcba_netdev_ops = {
 	.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.
  * This function sends request via USB to change the speed and align bittiming
  * values for presentation purposes only
@@ -836,6 +841,7 @@ static int mcba_usb_probe(struct usb_interface *intf,
 	priv->can.do_set_bittiming = mcba_net_set_bittiming;
 
 	netdev->netdev_ops = &mcba_netdev_ops;
+	netdev->ethtool_ops = &mcba_ethtool_ops;
 
 	netdev->flags |= IFF_ECHO; /* we support local echo */
 
diff --git a/drivers/net/can/usb/ucan.c b/drivers/net/can/usb/ucan.c
index 5ae0d7c017cc..7c35f50fda4e 100644
--- a/drivers/net/can/usb/ucan.c
+++ b/drivers/net/can/usb/ucan.c
@@ -28,6 +28,7 @@
 #include <linux/can.h>
 #include <linux/can/dev.h>
 #include <linux/can/error.h>
+#include <linux/ethtool.h>
 #include <linux/module.h>
 #include <linux/netdevice.h>
 #include <linux/signal.h>
@@ -1233,6 +1234,10 @@ static const struct net_device_ops ucan_netdev_ops = {
 	.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
  *
  * This function generates an USB set bittiming message and transmits
@@ -1512,6 +1517,7 @@ static int ucan_probe(struct usb_interface *intf,
 	spin_lock_init(&up->context_lock);
 	spin_lock_init(&up->echo_skb_lock);
 	netdev->netdev_ops = &ucan_netdev_ops;
+	netdev->ethtool_ops = &ucan_ethtool_ops;
 
 	usb_set_intfdata(intf, up);
 	SET_NETDEV_DEV(netdev, &intf->dev);
diff --git a/drivers/net/can/usb/usb_8dev.c b/drivers/net/can/usb/usb_8dev.c
index 8b7cd69e20b0..9453956303c0 100644
--- a/drivers/net/can/usb/usb_8dev.c
+++ b/drivers/net/can/usb/usb_8dev.c
@@ -12,6 +12,7 @@
  * who were very cooperative and answered my questions.
  */
 
+#include <linux/ethtool.h>
 #include <linux/signal.h>
 #include <linux/slab.h>
 #include <linux/module.h>
@@ -870,6 +871,10 @@ static const struct net_device_ops usb_8dev_netdev_ops = {
 	.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 = {
 	.name = "usb_8dev",
 	.tseg1_min = 1,
@@ -927,6 +932,7 @@ static int usb_8dev_probe(struct usb_interface *intf,
 				      CAN_CTRLMODE_CC_LEN8_DLC;
 
 	netdev->netdev_ops = &usb_8dev_netdev_ops;
+	netdev->ethtool_ops = &usb_8dev_ethtool_ops;
 
 	netdev->flags |= IFF_ECHO; /* we support local echo */
 
diff --git a/drivers/net/can/vcan.c b/drivers/net/can/vcan.c
index 4a363cfcf97c..36b6310a2e5b 100644
--- a/drivers/net/can/vcan.c
+++ b/drivers/net/can/vcan.c
@@ -40,6 +40,7 @@
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
+#include <linux/ethtool.h>
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/netdevice.h>
@@ -148,6 +149,10 @@ static const struct net_device_ops vcan_netdev_ops = {
 	.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)
 {
 	dev->type		= ARPHRD_CAN;
@@ -163,6 +168,7 @@ static void vcan_setup(struct net_device *dev)
 		dev->flags |= IFF_ECHO;
 
 	dev->netdev_ops		= &vcan_netdev_ops;
+	dev->ethtool_ops	= &vcan_ethtool_ops;
 	dev->needs_free_netdev	= true;
 }
 
diff --git a/drivers/net/can/vxcan.c b/drivers/net/can/vxcan.c
index 61b6eca383f8..cffd107d8b28 100644
--- a/drivers/net/can/vxcan.c
+++ b/drivers/net/can/vxcan.c
@@ -9,6 +9,7 @@
  * Copyright (c) 2017 Oliver Hartkopp <socketcan@hartkopp.net>
  */
 
+#include <linux/ethtool.h>
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/netdevice.h>
@@ -146,6 +147,10 @@ static const struct net_device_ops vxcan_netdev_ops = {
 	.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)
 {
 	struct can_ml_priv *can_ml;
@@ -157,6 +162,7 @@ static void vxcan_setup(struct net_device *dev)
 	dev->tx_queue_len	= 0;
 	dev->flags		= IFF_NOARP;
 	dev->netdev_ops		= &vxcan_netdev_ops;
+	dev->ethtool_ops	= &vxcan_ethtool_ops;
 	dev->needs_free_netdev	= true;
 
 	can_ml = netdev_priv(dev) + ALIGN(sizeof(struct vxcan_priv), NETDEV_ALIGN);
diff --git a/drivers/net/can/xilinx_can.c b/drivers/net/can/xilinx_can.c
index caa6b4cee63f..5d3172795ad0 100644
--- a/drivers/net/can/xilinx_can.c
+++ b/drivers/net/can/xilinx_can.c
@@ -12,6 +12,7 @@
 #include <linux/bitfield.h>
 #include <linux/clk.h>
 #include <linux/errno.h>
+#include <linux/ethtool.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
@@ -1540,6 +1541,10 @@ static const struct net_device_ops xcan_netdev_ops = {
 	.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
  * @dev:	Address of the device structure
@@ -1821,6 +1826,7 @@ static int xcan_probe(struct platform_device *pdev)
 	platform_set_drvdata(pdev, ndev);
 	SET_NETDEV_DEV(ndev, &pdev->dev);
 	ndev->netdev_ops = &xcan_netdev_ops;
+	ndev->ethtool_ops = &xcan_ethtool_ops;
 
 	/* Getting the CAN can_clk info */
 	priv->can_clk = devm_clk_get(&pdev->dev, "can_clk");
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 92+ messages in thread

* [PATCH v4 06/14] can: dev: add hardware TX timestamp
  2022-07-27 10:16 ` [PATCH v4 00/14] can: add ethtool support and reporting of timestamping capabilities Vincent Mailhol
                     ` (4 preceding siblings ...)
  2022-07-27 10:16   ` [PATCH v4 05/14] can: tree-wide: advertise software timestamping capabilities Vincent Mailhol
@ 2022-07-27 10:16   ` Vincent Mailhol
  2022-07-27 10:16   ` [PATCH v4 07/14] can: dev: add generic function can_ethtool_op_get_ts_info_hwts() Vincent Mailhol
                     ` (8 subsequent siblings)
  14 siblings, 0 replies; 92+ messages in thread
From: Vincent Mailhol @ 2022-07-27 10:16 UTC (permalink / raw)
  To: linux-can, Marc Kleine-Budde
  Cc: Stephane Grosjean, Jimmy Assarsson, Oliver Hartkopp,
	Dario Binacchi, Max Staudt, Vincent Mailhol

Because of the loopback feature of socket CAN, hardware TX timestamps
are nothing else than the hardware RX timespamp of the corresponding
loopback packet. This patch simply reuses the hardware RX timestamp.

The rationale to clone this timestamp value is that existing tools
which rely of libpcap (such as tcpdump) expect support for both TX and
RX hardware timestamps in order to activate the feature (i.e. no
granular control to activate either of TX or RX hardware timestamps).

Signed-off-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
---
 drivers/net/can/dev/skb.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/net/can/dev/skb.c b/drivers/net/can/dev/skb.c
index 8bb62dd864c8..07e0feac8629 100644
--- a/drivers/net/can/dev/skb.c
+++ b/drivers/net/can/dev/skb.c
@@ -72,6 +72,9 @@ int can_put_echo_skb(struct sk_buff *skb, struct net_device *dev,
 		/* save frame_len to reuse it when transmission is completed */
 		can_skb_prv(skb)->frame_len = frame_len;
 
+		if (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)
+			skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;
+
 		skb_tx_timestamp(skb);
 
 		/* save this skb for tx interrupt echo handling */
@@ -107,6 +110,9 @@ __can_get_echo_skb(struct net_device *dev, unsigned int idx, u8 *len_ptr,
 		struct can_skb_priv *can_skb_priv = can_skb_prv(skb);
 		struct canfd_frame *cf = (struct canfd_frame *)skb->data;
 
+		if (skb_shinfo(skb)->tx_flags & SKBTX_IN_PROGRESS)
+			skb_tstamp_tx(skb, skb_hwtstamps(skb));
+
 		/* get the real payload length for netdev statistics */
 		if (cf->can_id & CAN_RTR_FLAG)
 			*len_ptr = 0;
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 92+ messages in thread

* [PATCH v4 07/14] can: dev: add generic function can_ethtool_op_get_ts_info_hwts()
  2022-07-27 10:16 ` [PATCH v4 00/14] can: add ethtool support and reporting of timestamping capabilities Vincent Mailhol
                     ` (5 preceding siblings ...)
  2022-07-27 10:16   ` [PATCH v4 06/14] can: dev: add hardware TX timestamp Vincent Mailhol
@ 2022-07-27 10:16   ` Vincent Mailhol
  2022-07-27 10:16   ` [PATCH v4 08/14] can: dev: add generic function can_eth_ioctl_hwts() Vincent Mailhol
                     ` (7 subsequent siblings)
  14 siblings, 0 replies; 92+ messages in thread
From: Vincent Mailhol @ 2022-07-27 10:16 UTC (permalink / raw)
  To: linux-can, Marc Kleine-Budde
  Cc: Stephane Grosjean, Jimmy Assarsson, Oliver Hartkopp,
	Dario Binacchi, Max Staudt, Vincent Mailhol

Add function can_ethtool_op_get_ts_info_hwts(). This function will be
used by CAN devices with hardware TX/RX timestamping support to
implement ethtool_ops::get_ts_info. This function does not offer
support to activate/deactivate hardware timestamps at device level nor
support the filter options (which is currently the case for all CAN
devices with hardware timestamping support).

The fact that hardware timestamp can not be deactivated at hardware
level does not impact the userland. As long as the user do not set
SO_TIMESTAMPING using a setsockopt() or ioctl(), the kernel will not
emit TX timestamps (RX timestamps will still be reproted as it is the
case currently).

Drivers which need more fine grained control remains free to implement
their own function, but we foresee that the generic function
introduced here will be sufficient for the majority.

Signed-off-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
---
 drivers/net/can/dev/dev.c | 21 +++++++++++++++++++++
 include/linux/can/dev.h   |  3 +++
 2 files changed, 24 insertions(+)

diff --git a/drivers/net/can/dev/dev.c b/drivers/net/can/dev/dev.c
index 523eaacfe29e..f307034ff4fd 100644
--- a/drivers/net/can/dev/dev.c
+++ b/drivers/net/can/dev/dev.c
@@ -322,6 +322,27 @@ int can_change_mtu(struct net_device *dev, int new_mtu)
 }
 EXPORT_SYMBOL_GPL(can_change_mtu);
 
+/* generic implementation of ethtool_ops::get_ts_info for CAN devices
+ * supporting hardware timestamps
+ */
+int can_ethtool_op_get_ts_info_hwts(struct net_device *dev,
+				    struct ethtool_ts_info *info)
+{
+	info->so_timestamping =
+		SOF_TIMESTAMPING_TX_SOFTWARE |
+		SOF_TIMESTAMPING_RX_SOFTWARE |
+		SOF_TIMESTAMPING_SOFTWARE |
+		SOF_TIMESTAMPING_TX_HARDWARE |
+		SOF_TIMESTAMPING_RX_HARDWARE |
+		SOF_TIMESTAMPING_RAW_HARDWARE;
+	info->phc_index = -1;
+	info->tx_types = BIT(HWTSTAMP_TX_ON);
+	info->rx_filters = BIT(HWTSTAMP_FILTER_ALL);
+
+	return 0;
+}
+EXPORT_SYMBOL(can_ethtool_op_get_ts_info_hwts);
+
 /* Common open function when the device gets opened.
  *
  * This function should be called in the open function of the device
diff --git a/include/linux/can/dev.h b/include/linux/can/dev.h
index e22dc03c850e..752bd45d8ebf 100644
--- a/include/linux/can/dev.h
+++ b/include/linux/can/dev.h
@@ -20,6 +20,7 @@
 #include <linux/can/length.h>
 #include <linux/can/netlink.h>
 #include <linux/can/skb.h>
+#include <linux/ethtool.h>
 #include <linux/netdevice.h>
 
 /*
@@ -162,6 +163,8 @@ struct can_priv *safe_candev_priv(struct net_device *dev);
 int open_candev(struct net_device *dev);
 void close_candev(struct net_device *dev);
 int can_change_mtu(struct net_device *dev, int new_mtu);
+int can_ethtool_op_get_ts_info_hwts(struct net_device *dev,
+				    struct ethtool_ts_info *info);
 
 int register_candev(struct net_device *dev);
 void unregister_candev(struct net_device *dev);
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 92+ messages in thread

* [PATCH v4 08/14] can: dev: add generic function can_eth_ioctl_hwts()
  2022-07-27 10:16 ` [PATCH v4 00/14] can: add ethtool support and reporting of timestamping capabilities Vincent Mailhol
                     ` (6 preceding siblings ...)
  2022-07-27 10:16   ` [PATCH v4 07/14] can: dev: add generic function can_ethtool_op_get_ts_info_hwts() Vincent Mailhol
@ 2022-07-27 10:16   ` Vincent Mailhol
  2022-07-27 10:16   ` [PATCH v4 09/14] can: mcp251xfd: advertise timestamping capabilities and add ioctl support Vincent Mailhol
                     ` (6 subsequent siblings)
  14 siblings, 0 replies; 92+ messages in thread
From: Vincent Mailhol @ 2022-07-27 10:16 UTC (permalink / raw)
  To: linux-can, Marc Kleine-Budde
  Cc: Stephane Grosjean, Jimmy Assarsson, Oliver Hartkopp,
	Dario Binacchi, Max Staudt, Vincent Mailhol

Tools based on libpcap (such as tcpdump) expect the SIOCSHWTSTAMP
ioctl call to be supported. This is also specified in the kernel doc
[1]. The purpose of this ioctl is to toggle the hardware timestamps.

Currently, CAN devices which support hardware timestamping have those
always activated. can_eth_ioctl_hwts() is a dumb function that will
always succeed when requested to set tx_type to HWTSTAMP_TX_ON or
rx_filter to HWTSTAMP_FILTER_ALL.

[1] Kernel doc: Timestamping, section 3.1 "Hardware Timestamping
Implementation: Device Drivers"
Link: https://docs.kernel.org/networking/timestamping.html#hardware-timestamping-implementation-device-drivers

Signed-off-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
---
 drivers/net/can/dev/dev.c | 29 +++++++++++++++++++++++++++++
 include/linux/can/dev.h   |  1 +
 2 files changed, 30 insertions(+)

diff --git a/drivers/net/can/dev/dev.c b/drivers/net/can/dev/dev.c
index f307034ff4fd..c1956b1e9faf 100644
--- a/drivers/net/can/dev/dev.c
+++ b/drivers/net/can/dev/dev.c
@@ -322,6 +322,35 @@ int can_change_mtu(struct net_device *dev, int new_mtu)
 }
 EXPORT_SYMBOL_GPL(can_change_mtu);
 
+/* generic implementation of netdev_ops::ndo_eth_ioctl for CAN devices
+ * supporting hardware timestamps
+ */
+int can_eth_ioctl_hwts(struct net_device *netdev, struct ifreq *ifr, int cmd)
+{
+	struct hwtstamp_config hwts_cfg = { 0 };
+
+	switch (cmd) {
+	case SIOCSHWTSTAMP: /* set */
+		if (copy_from_user(&hwts_cfg, ifr->ifr_data, sizeof(hwts_cfg)))
+			return -EFAULT;
+		if (hwts_cfg.tx_type == HWTSTAMP_TX_ON &&
+		    hwts_cfg.rx_filter == HWTSTAMP_FILTER_ALL)
+			return 0;
+		return -ERANGE;
+
+	case SIOCGHWTSTAMP: /* get */
+		hwts_cfg.tx_type = HWTSTAMP_TX_ON;
+		hwts_cfg.rx_filter = HWTSTAMP_FILTER_ALL;
+		if (copy_to_user(ifr->ifr_data, &hwts_cfg, sizeof(hwts_cfg)))
+			return -EFAULT;
+		return 0;
+
+	default:
+		return -EOPNOTSUPP;
+	}
+}
+EXPORT_SYMBOL(can_eth_ioctl_hwts);
+
 /* generic implementation of ethtool_ops::get_ts_info for CAN devices
  * supporting hardware timestamps
  */
diff --git a/include/linux/can/dev.h b/include/linux/can/dev.h
index 752bd45d8ebf..c3e50e537e39 100644
--- a/include/linux/can/dev.h
+++ b/include/linux/can/dev.h
@@ -163,6 +163,7 @@ struct can_priv *safe_candev_priv(struct net_device *dev);
 int open_candev(struct net_device *dev);
 void close_candev(struct net_device *dev);
 int can_change_mtu(struct net_device *dev, int new_mtu);
+int can_eth_ioctl_hwts(struct net_device *netdev, struct ifreq *ifr, int cmd);
 int can_ethtool_op_get_ts_info_hwts(struct net_device *dev,
 				    struct ethtool_ts_info *info);
 
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 92+ messages in thread

* [PATCH v4 09/14] can: mcp251xfd: advertise timestamping capabilities and add ioctl support
  2022-07-27 10:16 ` [PATCH v4 00/14] can: add ethtool support and reporting of timestamping capabilities Vincent Mailhol
                     ` (7 preceding siblings ...)
  2022-07-27 10:16   ` [PATCH v4 08/14] can: dev: add generic function can_eth_ioctl_hwts() Vincent Mailhol
@ 2022-07-27 10:16   ` Vincent Mailhol
  2022-07-27 10:16   ` [PATCH v4 10/14] can: etas_es58x: " Vincent Mailhol
                     ` (5 subsequent siblings)
  14 siblings, 0 replies; 92+ messages in thread
From: Vincent Mailhol @ 2022-07-27 10:16 UTC (permalink / raw)
  To: linux-can, Marc Kleine-Budde
  Cc: Stephane Grosjean, Jimmy Assarsson, Oliver Hartkopp,
	Dario Binacchi, Max Staudt, Vincent Mailhol

Currently, userland has no methods to query which timestamping
features are supported by the mcp251xfd driver (aside maybe of getting
RX messages and observe whether or not hardware timestamps stay at
zero).

The canonical way for a network driver to advertise what kind of
timestamping it supports is to implement
ethtool_ops::get_ts_info(). Here, we use the CAN specific
can_ethtool_op_get_ts_info_hwts() function to achieve this.

In addition, the driver currently does not support the hardware
timestamps ioctls. According to [1], SIOCSHWTSTAMP is "must" and
SIOCGHWTSTAMP is "should". This patch fills up that gap by
implementing net_device_ops::ndo_eth_ioctl() using the CAN specific
function can_eth_ioctl_hwts().

[1] kernel doc Timestamping, section 3.1: "Hardware Timestamping
Implementation: Device Drivers"
Link: https://docs.kernel.org/networking/timestamping.html#hardware-timestamping-implementation-device-drivers

Signed-off-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
---
 drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c    | 1 +
 drivers/net/can/spi/mcp251xfd/mcp251xfd-ethtool.c | 1 +
 2 files changed, 2 insertions(+)

diff --git a/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c b/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c
index 7fc86ed405c6..68df6d4641b5 100644
--- a/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c
+++ b/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c
@@ -1671,6 +1671,7 @@ static const struct net_device_ops mcp251xfd_netdev_ops = {
 	.ndo_open = mcp251xfd_open,
 	.ndo_stop = mcp251xfd_stop,
 	.ndo_start_xmit	= mcp251xfd_start_xmit,
+	.ndo_eth_ioctl = can_eth_ioctl_hwts,
 	.ndo_change_mtu = can_change_mtu,
 };
 
diff --git a/drivers/net/can/spi/mcp251xfd/mcp251xfd-ethtool.c b/drivers/net/can/spi/mcp251xfd/mcp251xfd-ethtool.c
index 6c7a57f16cc6..3585f02575df 100644
--- a/drivers/net/can/spi/mcp251xfd/mcp251xfd-ethtool.c
+++ b/drivers/net/can/spi/mcp251xfd/mcp251xfd-ethtool.c
@@ -124,6 +124,7 @@ static const struct ethtool_ops mcp251xfd_ethtool_ops = {
 	.set_ringparam = mcp251xfd_ring_set_ringparam,
 	.get_coalesce = mcp251xfd_ring_get_coalesce,
 	.set_coalesce = mcp251xfd_ring_set_coalesce,
+	.get_ts_info = can_ethtool_op_get_ts_info_hwts,
 };
 
 void mcp251xfd_ethtool_init(struct mcp251xfd_priv *priv)
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 92+ messages in thread

* [PATCH v4 10/14] can: etas_es58x: advertise timestamping capabilities and add ioctl support
  2022-07-27 10:16 ` [PATCH v4 00/14] can: add ethtool support and reporting of timestamping capabilities Vincent Mailhol
                     ` (8 preceding siblings ...)
  2022-07-27 10:16   ` [PATCH v4 09/14] can: mcp251xfd: advertise timestamping capabilities and add ioctl support Vincent Mailhol
@ 2022-07-27 10:16   ` Vincent Mailhol
  2022-07-27 10:16   ` [PATCH v4 11/14] can: kvaser_pciefd: " Vincent Mailhol
                     ` (4 subsequent siblings)
  14 siblings, 0 replies; 92+ messages in thread
From: Vincent Mailhol @ 2022-07-27 10:16 UTC (permalink / raw)
  To: linux-can, Marc Kleine-Budde
  Cc: Stephane Grosjean, Jimmy Assarsson, Oliver Hartkopp,
	Dario Binacchi, Max Staudt, Vincent Mailhol

Currently, userland has no method to query which timestamping features
are supported by the etas_es58x driver (aside maybe of getting RX
messages and observe whether or not hardware timestamps stay at zero).

The canonical way for a network driver to advertise what kind of
timestamping is supports is to implement
ethtool_ops::get_ts_info(). Here, we use the CAN specific
can_ethtool_op_get_ts_info_hwts() function to achieve this.

In addition, the driver currently does not support the hardware
timestamps ioctls. According to [1], SIOCSHWTSTAMP is "must" and
SIOCGHWTSTAMP is "should". This patch fills up that gap by
implementing net_device_ops::ndo_eth_ioctl() using the CAN specific
function can_eth_ioctl_hwts().

[1] kernel doc Timestamping, section 3.1: "Hardware Timestamping
Implementation: Device Drivers"
Link: https://docs.kernel.org/networking/timestamping.html#hardware-timestamping-implementation-device-drivers

Signed-off-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
---
 drivers/net/can/usb/etas_es58x/es58x_core.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/net/can/usb/etas_es58x/es58x_core.c b/drivers/net/can/usb/etas_es58x/es58x_core.c
index 7353745f92d7..5e2585c85500 100644
--- a/drivers/net/can/usb/etas_es58x/es58x_core.c
+++ b/drivers/net/can/usb/etas_es58x/es58x_core.c
@@ -10,6 +10,7 @@
  * Copyright (c) 2020, 2021 Vincent Mailhol <mailhol.vincent@wanadoo.fr>
  */
 
+#include <linux/ethtool.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/usb.h>
@@ -1981,7 +1982,12 @@ static netdev_tx_t es58x_start_xmit(struct sk_buff *skb,
 static const struct net_device_ops es58x_netdev_ops = {
 	.ndo_open = es58x_open,
 	.ndo_stop = es58x_stop,
-	.ndo_start_xmit = es58x_start_xmit
+	.ndo_start_xmit = es58x_start_xmit,
+	.ndo_eth_ioctl = can_eth_ioctl_hwts,
+};
+
+static const struct ethtool_ops es58x_ethtool_ops = {
+	.get_ts_info = can_ethtool_op_get_ts_info_hwts,
 };
 
 /**
@@ -2088,6 +2094,7 @@ static int es58x_init_netdev(struct es58x_device *es58x_dev, int channel_idx)
 	es58x_init_priv(es58x_dev, es58x_priv(netdev), channel_idx);
 
 	netdev->netdev_ops = &es58x_netdev_ops;
+	netdev->ethtool_ops = &es58x_ethtool_ops;
 	netdev->flags |= IFF_ECHO;	/* We support local echo */
 	netdev->dev_port = channel_idx;
 
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 92+ messages in thread

* [PATCH v4 11/14] can: kvaser_pciefd: advertise timestamping capabilities and add ioctl support
  2022-07-27 10:16 ` [PATCH v4 00/14] can: add ethtool support and reporting of timestamping capabilities Vincent Mailhol
                     ` (9 preceding siblings ...)
  2022-07-27 10:16   ` [PATCH v4 10/14] can: etas_es58x: " Vincent Mailhol
@ 2022-07-27 10:16   ` Vincent Mailhol
  2022-07-27 10:16   ` [PATCH v4 12/14] can: kvaser_usb: " Vincent Mailhol
                     ` (3 subsequent siblings)
  14 siblings, 0 replies; 92+ messages in thread
From: Vincent Mailhol @ 2022-07-27 10:16 UTC (permalink / raw)
  To: linux-can, Marc Kleine-Budde
  Cc: Stephane Grosjean, Jimmy Assarsson, Oliver Hartkopp,
	Dario Binacchi, Max Staudt, Vincent Mailhol

Currently, userland has no method to query which timestamping features
are supported by the kvaser_pciefd driver (aside maybe of getting RX
messages and observe whether or not hardware timestamps stay at zero).

The canonical way for a network driver to advertise what kind of
timestamping it supports is to implement
ethtool_ops::get_ts_info(). Here, we use the CAN specific
can_ethtool_op_get_ts_info_hwts() function to achieve this.

In addition, the driver currently does not support the hardware
timestamps ioctls. According to [1], SIOCSHWTSTAMP is "must" and
SIOCGHWTSTAMP is "should". This patch fills up that gap by
implementing net_device_ops::ndo_eth_ioctl() using the CAN specific
function can_eth_ioctl_hwts().

[1] kernel doc Timestamping, section 3.1: "Hardware Timestamping
Implementation: Device Drivers"
Link: https://docs.kernel.org/networking/timestamping.html#hardware-timestamping-implementation-device-drivers

CC: Jimmy Assarsson <extja@kvaser.com>
Signed-off-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
---
 drivers/net/can/kvaser_pciefd.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/drivers/net/can/kvaser_pciefd.c b/drivers/net/can/kvaser_pciefd.c
index dcd2c9d50d5e..ed54c0b3c7d4 100644
--- a/drivers/net/can/kvaser_pciefd.c
+++ b/drivers/net/can/kvaser_pciefd.c
@@ -9,6 +9,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/device.h>
+#include <linux/ethtool.h>
 #include <linux/pci.h>
 #include <linux/can/dev.h>
 #include <linux/timer.h>
@@ -919,10 +920,15 @@ static void kvaser_pciefd_bec_poll_timer(struct timer_list *data)
 static const struct net_device_ops kvaser_pciefd_netdev_ops = {
 	.ndo_open = kvaser_pciefd_open,
 	.ndo_stop = kvaser_pciefd_stop,
+	.ndo_eth_ioctl = can_eth_ioctl_hwts,
 	.ndo_start_xmit = kvaser_pciefd_start_xmit,
 	.ndo_change_mtu = can_change_mtu,
 };
 
+static const struct ethtool_ops kvaser_pciefd_ethtool_ops = {
+	.get_ts_info = can_ethtool_op_get_ts_info_hwts,
+};
+
 static int kvaser_pciefd_setup_can_ctrls(struct kvaser_pciefd *pcie)
 {
 	int i;
@@ -939,6 +945,7 @@ static int kvaser_pciefd_setup_can_ctrls(struct kvaser_pciefd *pcie)
 
 		can = netdev_priv(netdev);
 		netdev->netdev_ops = &kvaser_pciefd_netdev_ops;
+		netdev->ethtool_ops = &kvaser_pciefd_ethtool_ops;
 		can->reg_base = pcie->reg_base + KVASER_PCIEFD_KCAN0_BASE +
 				i * KVASER_PCIEFD_KCAN_BASE_OFFSET;
 
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 92+ messages in thread

* [PATCH v4 12/14] can: kvaser_usb: advertise timestamping capabilities and add ioctl support
  2022-07-27 10:16 ` [PATCH v4 00/14] can: add ethtool support and reporting of timestamping capabilities Vincent Mailhol
                     ` (10 preceding siblings ...)
  2022-07-27 10:16   ` [PATCH v4 11/14] can: kvaser_pciefd: " Vincent Mailhol
@ 2022-07-27 10:16   ` Vincent Mailhol
  2022-07-27 10:16   ` [PATCH v4 13/14] can: peak_canfd: " Vincent Mailhol
                     ` (2 subsequent siblings)
  14 siblings, 0 replies; 92+ messages in thread
From: Vincent Mailhol @ 2022-07-27 10:16 UTC (permalink / raw)
  To: linux-can, Marc Kleine-Budde
  Cc: Stephane Grosjean, Jimmy Assarsson, Oliver Hartkopp,
	Dario Binacchi, Max Staudt, Vincent Mailhol

Currently, userland has no method to query which timestamping features
are supported by the kvaser_usb driver (aside maybe of getting RX
messages and observe whether or not hardware timestamps stay at zero).

The canonical way for a network driver to advertise what kind of
timestamping it supports is to implement
ethtool_ops::get_ts_info(). Here, we use the CAN specific
can_ethtool_op_get_ts_info_hwts() function to achieve this.

In addition, the driver currently does not support the hardware
timestamps ioctls. According to [1], SIOCSHWTSTAMP is "must" and
SIOCGHWTSTAMP is "should". This patch fills up that gap by
implementing net_device_ops::ndo_eth_ioctl() using the CAN specific
function can_eth_ioctl_hwts().

[1] kernel doc Timestamping, section 3.1: "Hardware Timestamping
Implementation: Device Drivers"
Link: https://docs.kernel.org/networking/timestamping.html#hardware-timestamping-implementation-device-drivers

CC: Jimmy Assarsson <extja@kvaser.com>
Signed-off-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
---

Hi Jimmy, as far as I understand, only the hydra has the hardware
timestamping. If not the case, let me know.

This is not tested. If you find any issue or if you want to modify,
feel free to pick up that patch and resend it.
---
 drivers/net/can/usb/kvaser_usb/kvaser_usb.h   |  1 +
 .../net/can/usb/kvaser_usb/kvaser_usb_core.c  | 27 +++++++++++++++++--
 2 files changed, 26 insertions(+), 2 deletions(-)

diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb.h b/drivers/net/can/usb/kvaser_usb/kvaser_usb.h
index eefcbe3aadce..841da29cef93 100644
--- a/drivers/net/can/usb/kvaser_usb/kvaser_usb.h
+++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb.h
@@ -39,6 +39,7 @@
 #define KVASER_USB_QUIRK_HAS_SILENT_MODE	BIT(0)
 #define KVASER_USB_QUIRK_HAS_TXRX_ERRORS	BIT(1)
 #define KVASER_USB_QUIRK_IGNORE_CLK_FREQ	BIT(2)
+#define KVASER_USB_QUIRK_HAS_HARDWARE_TIMESTAMP	BIT(3)
 
 /* Device capabilities */
 #define KVASER_USB_CAP_BERR_CAP			0x01
diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c b/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c
index f211bfcb1d97..5e357f5d3116 100644
--- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c
+++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c
@@ -13,6 +13,7 @@
 
 #include <linux/completion.h>
 #include <linux/device.h>
+#include <linux/ethtool.h>
 #include <linux/gfp.h>
 #include <linux/if.h>
 #include <linux/kernel.h>
@@ -89,7 +90,7 @@
 #define USB_HYBRID_PRO_CANLIN_PRODUCT_ID	278
 
 static const struct kvaser_usb_driver_info kvaser_usb_driver_info_hydra = {
-	.quirks = 0,
+	.quirks = KVASER_USB_QUIRK_HAS_HARDWARE_TIMESTAMP,
 	.ops = &kvaser_usb_hydra_dev_ops,
 };
 
@@ -665,6 +666,22 @@ static const struct net_device_ops kvaser_usb_netdev_ops = {
 	.ndo_change_mtu = can_change_mtu,
 };
 
+static const struct net_device_ops kvaser_usb_netdev_ops_hwts = {
+	.ndo_open = kvaser_usb_open,
+	.ndo_stop = kvaser_usb_close,
+	.ndo_eth_ioctl = can_eth_ioctl_hwts,
+	.ndo_start_xmit = kvaser_usb_start_xmit,
+	.ndo_change_mtu = can_change_mtu,
+};
+
+static const struct ethtool_ops kvaser_usb_ethtool_ops = {
+	.get_ts_info = ethtool_op_get_ts_info,
+};
+
+static const struct ethtool_ops kvaser_usb_ethtool_ops_hwts = {
+	.get_ts_info = can_ethtool_op_get_ts_info_hwts,
+};
+
 static void kvaser_usb_remove_interfaces(struct kvaser_usb *dev)
 {
 	int i;
@@ -742,7 +759,13 @@ static int kvaser_usb_init_one(struct kvaser_usb *dev, int channel)
 	netdev->flags |= IFF_ECHO;
 
 	netdev->netdev_ops = &kvaser_usb_netdev_ops;
-
+	if (driver_info->quirks & KVASER_USB_QUIRK_HAS_HARDWARE_TIMESTAMP) {
+		netdev->netdev_ops = &kvaser_usb_netdev_ops_hwts;
+		netdev->ethtool_ops = &kvaser_usb_ethtool_ops_hwts;
+	} else {
+		netdev->netdev_ops = &kvaser_usb_netdev_ops;
+		netdev->ethtool_ops = &kvaser_usb_ethtool_ops;
+	}
 	SET_NETDEV_DEV(netdev, &dev->intf->dev);
 	netdev->dev_id = channel;
 
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 92+ messages in thread

* [PATCH v4 13/14] can: peak_canfd: advertise timestamping capabilities and add ioctl support
  2022-07-27 10:16 ` [PATCH v4 00/14] can: add ethtool support and reporting of timestamping capabilities Vincent Mailhol
                     ` (11 preceding siblings ...)
  2022-07-27 10:16   ` [PATCH v4 12/14] can: kvaser_usb: " Vincent Mailhol
@ 2022-07-27 10:16   ` Vincent Mailhol
  2022-07-27 10:16   ` [PATCH v4 14/14] can: peak_usb: " Vincent Mailhol
  2022-07-28 10:09   ` [PATCH v4 00/14] can: add ethtool support and reporting of timestamping capabilities Marc Kleine-Budde
  14 siblings, 0 replies; 92+ messages in thread
From: Vincent Mailhol @ 2022-07-27 10:16 UTC (permalink / raw)
  To: linux-can, Marc Kleine-Budde
  Cc: Stephane Grosjean, Jimmy Assarsson, Oliver Hartkopp,
	Dario Binacchi, Max Staudt, Vincent Mailhol

Currently, userland has no method to query which timestamping features
are supported by the peak_canfd driver (aside maybe of getting RX
messages and observe whether or not hardware timestamps stay at zero).

The canonical way to add hardware timestamp support is to implement
ethtool_ops::get_ts_info() in order to advertise the timestamping
capabilities and to implement net_device_ops::ndo_eth_ioctl() as
requested in [1]. Currently, the driver only supports hardware RX
timestamps [2] but not hardware TX. For this reason, the generic
function can_ethtool_op_get_ts_info_hwts() and can_eth_ioctl_hwts()
can not be reused and instead this patch adds peak_get_ts_info() and
peak_eth_ioctl().

[1] kernel doc Timestamping, section 3.1: "Hardware Timestamping
Implementation: Device Drivers"
Link: https://docs.kernel.org/networking/timestamping.html#hardware-timestamping-implementation-device-drivers

[2] https://lore.kernel.org/linux-can/20220727084257.brcbbf7lksoeekbr@pengutronix.de/

CC: Stephane Grosjean <s.grosjean@peak-system.com>
Signed-off-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
---
 drivers/net/can/peak_canfd/peak_canfd.c | 48 +++++++++++++++++++++++++
 1 file changed, 48 insertions(+)

diff --git a/drivers/net/can/peak_canfd/peak_canfd.c b/drivers/net/can/peak_canfd/peak_canfd.c
index afb9adb3d5c2..f8420cc1d907 100644
--- a/drivers/net/can/peak_canfd/peak_canfd.c
+++ b/drivers/net/can/peak_canfd/peak_canfd.c
@@ -7,6 +7,7 @@
 
 #include <linux/can.h>
 #include <linux/can/dev.h>
+#include <linux/ethtool.h>
 
 #include "peak_canfd_user.h"
 
@@ -742,13 +743,59 @@ static netdev_tx_t peak_canfd_start_xmit(struct sk_buff *skb,
 	return NETDEV_TX_OK;
 }
 
+static int peak_eth_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
+{
+	struct hwtstamp_config hwts_cfg = { 0 };
+
+	switch (cmd) {
+	case SIOCSHWTSTAMP: /* set */
+		if (copy_from_user(&hwts_cfg, ifr->ifr_data, sizeof(hwts_cfg)))
+			return -EFAULT;
+		if (hwts_cfg.tx_type == HWTSTAMP_TX_OFF &&
+		    hwts_cfg.rx_filter == HWTSTAMP_FILTER_ALL)
+			return 0;
+		return -ERANGE;
+
+	case SIOCGHWTSTAMP: /* get */
+		hwts_cfg.tx_type = HWTSTAMP_TX_OFF;
+		hwts_cfg.rx_filter = HWTSTAMP_FILTER_ALL;
+		if (copy_to_user(ifr->ifr_data, &hwts_cfg, sizeof(hwts_cfg)))
+			return -EFAULT;
+		return 0;
+
+	default:
+		return -EOPNOTSUPP;
+	}
+}
+
 static const struct net_device_ops peak_canfd_netdev_ops = {
 	.ndo_open = peak_canfd_open,
 	.ndo_stop = peak_canfd_close,
+	.ndo_eth_ioctl = peak_eth_ioctl,
 	.ndo_start_xmit = peak_canfd_start_xmit,
 	.ndo_change_mtu = can_change_mtu,
 };
 
+static int peak_get_ts_info(struct net_device *dev,
+			    struct ethtool_ts_info *info)
+{
+	info->so_timestamping =
+		SOF_TIMESTAMPING_TX_SOFTWARE |
+		SOF_TIMESTAMPING_RX_SOFTWARE |
+		SOF_TIMESTAMPING_SOFTWARE |
+		SOF_TIMESTAMPING_RX_HARDWARE |
+		SOF_TIMESTAMPING_RAW_HARDWARE;
+	info->phc_index = -1;
+	info->tx_types = BIT(HWTSTAMP_TX_OFF);
+	info->rx_filters = BIT(HWTSTAMP_FILTER_ALL);
+
+	return 0;
+}
+
+static const struct ethtool_ops peak_canfd_ethtool_ops = {
+	.get_ts_info = peak_get_ts_info,
+};
+
 struct net_device *alloc_peak_canfd_dev(int sizeof_priv, int index,
 					int echo_skb_max)
 {
@@ -789,6 +836,7 @@ struct net_device *alloc_peak_canfd_dev(int sizeof_priv, int index,
 
 	ndev->flags |= IFF_ECHO;
 	ndev->netdev_ops = &peak_canfd_netdev_ops;
+	ndev->ethtool_ops = &peak_canfd_ethtool_ops;
 	ndev->dev_id = index;
 
 	return ndev;
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 92+ messages in thread

* [PATCH v4 14/14] can: peak_usb: advertise timestamping capabilities and add ioctl support
  2022-07-27 10:16 ` [PATCH v4 00/14] can: add ethtool support and reporting of timestamping capabilities Vincent Mailhol
                     ` (12 preceding siblings ...)
  2022-07-27 10:16   ` [PATCH v4 13/14] can: peak_canfd: " Vincent Mailhol
@ 2022-07-27 10:16   ` Vincent Mailhol
  2022-07-28 10:09   ` [PATCH v4 00/14] can: add ethtool support and reporting of timestamping capabilities Marc Kleine-Budde
  14 siblings, 0 replies; 92+ messages in thread
From: Vincent Mailhol @ 2022-07-27 10:16 UTC (permalink / raw)
  To: linux-can, Marc Kleine-Budde
  Cc: Stephane Grosjean, Jimmy Assarsson, Oliver Hartkopp,
	Dario Binacchi, Max Staudt, Vincent Mailhol

Currently, userland has no method to query which timestamping features
are supported by the peak_usb driver (aside maybe of getting RX
messages and observe whether or not hardware timestamps stay at zero).

The canonical way to add hardware timestamp support is to implement
ethtool_ops::get_ts_info() in order to advertise the timestamping
capabilities and to implement net_device_ops::ndo_eth_ioctl() as
requested in [1]. Currently, the driver only supports hardware RX
timestamps [2] but not hardware TX. For this reason, the generic
function can_ethtool_op_get_ts_info_hwts() and can_eth_ioctl_hwts()
can not be reused and instead this patch adds pcan_get_ts_info() and
peak_eth_ioctl().

[1] kernel doc Timestamping, section 3.1: "Hardware Timestamping
Implementation: Device Drivers"
Link: https://docs.kernel.org/networking/timestamping.html#hardware-timestamping-implementation-device-drivers

[2] https://lore.kernel.org/linux-can/20220727080634.l6uttnbrmwbabh3o@pengutronix.de/

CC: Stephane Grosjean <s.grosjean@peak-system.com>
Signed-off-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
---
 drivers/net/can/usb/peak_usb/pcan_usb.c      |  1 +
 drivers/net/can/usb/peak_usb/pcan_usb_core.c | 41 ++++++++++++++++++++
 drivers/net/can/usb/peak_usb/pcan_usb_core.h |  1 +
 drivers/net/can/usb/peak_usb/pcan_usb_fd.c   |  1 +
 drivers/net/can/usb/peak_usb/pcan_usb_pro.c  |  1 +
 5 files changed, 45 insertions(+)

diff --git a/drivers/net/can/usb/peak_usb/pcan_usb.c b/drivers/net/can/usb/peak_usb/pcan_usb.c
index d07b7ee79e3e..687dd542f7f6 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb.c
+++ b/drivers/net/can/usb/peak_usb/pcan_usb.c
@@ -965,6 +965,7 @@ static int pcan_usb_set_phys_id(struct net_device *netdev,
 
 static const struct ethtool_ops pcan_usb_ethtool_ops = {
 	.set_phys_id = pcan_usb_set_phys_id,
+	.get_ts_info = pcan_get_ts_info,
 };
 
 /*
diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_core.c b/drivers/net/can/usb/peak_usb/pcan_usb_core.c
index 27b0a72fd885..8c9d53f6e24c 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb_core.c
+++ b/drivers/net/can/usb/peak_usb/pcan_usb_core.c
@@ -775,13 +775,54 @@ static int peak_usb_set_data_bittiming(struct net_device *netdev)
 	return 0;
 }
 
+static int peak_eth_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
+{
+	struct hwtstamp_config hwts_cfg = { 0 };
+
+	switch (cmd) {
+	case SIOCSHWTSTAMP: /* set */
+		if (copy_from_user(&hwts_cfg, ifr->ifr_data, sizeof(hwts_cfg)))
+			return -EFAULT;
+		if (hwts_cfg.tx_type == HWTSTAMP_TX_OFF &&
+		    hwts_cfg.rx_filter == HWTSTAMP_FILTER_ALL)
+			return 0;
+		return -ERANGE;
+
+	case SIOCGHWTSTAMP: /* get */
+		hwts_cfg.tx_type = HWTSTAMP_TX_OFF;
+		hwts_cfg.rx_filter = HWTSTAMP_FILTER_ALL;
+		if (copy_to_user(ifr->ifr_data, &hwts_cfg, sizeof(hwts_cfg)))
+			return -EFAULT;
+		return 0;
+
+	default:
+		return -EOPNOTSUPP;
+	}
+}
+
 static const struct net_device_ops peak_usb_netdev_ops = {
 	.ndo_open = peak_usb_ndo_open,
 	.ndo_stop = peak_usb_ndo_stop,
+	.ndo_eth_ioctl = peak_eth_ioctl,
 	.ndo_start_xmit = peak_usb_ndo_start_xmit,
 	.ndo_change_mtu = can_change_mtu,
 };
 
+int pcan_get_ts_info(struct net_device *dev, struct ethtool_ts_info *info)
+{
+	info->so_timestamping =
+		SOF_TIMESTAMPING_TX_SOFTWARE |
+		SOF_TIMESTAMPING_RX_SOFTWARE |
+		SOF_TIMESTAMPING_SOFTWARE |
+		SOF_TIMESTAMPING_RX_HARDWARE |
+		SOF_TIMESTAMPING_RAW_HARDWARE;
+	info->phc_index = -1;
+	info->tx_types = BIT(HWTSTAMP_TX_OFF);
+	info->rx_filters = BIT(HWTSTAMP_FILTER_ALL);
+
+	return 0;
+}
+
 /*
  * create one device which is attached to CAN controller #ctrl_idx of the
  * usb adapter.
diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_core.h b/drivers/net/can/usb/peak_usb/pcan_usb_core.h
index 9c90487b9c92..f6bdd8b3f290 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb_core.h
+++ b/drivers/net/can/usb/peak_usb/pcan_usb_core.h
@@ -145,5 +145,6 @@ int peak_usb_netif_rx(struct sk_buff *skb,
 int peak_usb_netif_rx_64(struct sk_buff *skb, u32 ts_low, u32 ts_high);
 void peak_usb_async_complete(struct urb *urb);
 void peak_usb_restart_complete(struct peak_usb_device *dev);
+int pcan_get_ts_info(struct net_device *dev, struct ethtool_ts_info *info);
 
 #endif
diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_fd.c b/drivers/net/can/usb/peak_usb/pcan_usb_fd.c
index 3d7e0e370505..2ea1500df393 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb_fd.c
+++ b/drivers/net/can/usb/peak_usb/pcan_usb_fd.c
@@ -1080,6 +1080,7 @@ static int pcan_usb_fd_set_phys_id(struct net_device *netdev,
 
 static const struct ethtool_ops pcan_usb_fd_ethtool_ops = {
 	.set_phys_id = pcan_usb_fd_set_phys_id,
+	.get_ts_info = pcan_get_ts_info,
 };
 
 /* describes the PCAN-USB FD adapter */
diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_pro.c b/drivers/net/can/usb/peak_usb/pcan_usb_pro.c
index 457887113e75..5d8f6a40bb2c 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb_pro.c
+++ b/drivers/net/can/usb/peak_usb/pcan_usb_pro.c
@@ -1022,6 +1022,7 @@ static int pcan_usb_pro_set_phys_id(struct net_device *netdev,
 
 static const struct ethtool_ops pcan_usb_pro_ethtool_ops = {
 	.set_phys_id = pcan_usb_pro_set_phys_id,
+	.get_ts_info = pcan_get_ts_info,
 };
 
 /*
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 92+ messages in thread

* Re: [PATCH v1 10/24] can: tree-wide: implement ethtool_ops::get_drvinfo()
  2022-07-27  9:05             ` Vincent MAILHOL
@ 2022-07-27 11:19               ` Marc Kleine-Budde
  0 siblings, 0 replies; 92+ messages in thread
From: Marc Kleine-Budde @ 2022-07-27 11:19 UTC (permalink / raw)
  To: Vincent MAILHOL
  Cc: Dario Binacchi, linux-can, Stephane Grosjean, Jimmy Assarsson,
	Oliver Hartkopp, Max Staudt

[-- Attachment #1: Type: text/plain, Size: 509 bytes --]

On 27.07.2022 18:05:15, Vincent MAILHOL wrote:
> Yes, but this is not related to the timestamp series. So if I do it, I
> will do it separately (and I do not commit that I will do it).

That didn't age well :)

Thanks a lot,
Marc

-- 
Pengutronix e.K.                 | Marc Kleine-Budde           |
Embedded Linux                   | https://www.pengutronix.de  |
Vertretung West/Dortmund         | Phone: +49-231-2826-924     |
Amtsgericht Hildesheim, HRA 2686 | Fax:   +49-5121-206917-5555 |

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 92+ messages in thread

* Re: [PATCH v4 01/14] can: can327: add software tx timestamps
  2022-07-27 10:16   ` [PATCH v4 01/14] can: can327: add software tx timestamps Vincent Mailhol
@ 2022-07-27 20:24     ` Max Staudt
  0 siblings, 0 replies; 92+ messages in thread
From: Max Staudt @ 2022-07-27 20:24 UTC (permalink / raw)
  To: Vincent Mailhol
  Cc: linux-can, Marc Kleine-Budde, Stephane Grosjean, Jimmy Assarsson,
	Oliver Hartkopp, Dario Binacchi

On Wed, 27 Jul 2022 19:16:28 +0900
Vincent Mailhol <mailhol.vincent@wanadoo.fr> wrote:

> TX timestamps were added to the can_put_echo_skb() function of can_dev
> modules in [1]. However, can327 does not rely on that function and as
> such does not offer TX timestamping.
> 
> Add a call to skb_tx_timestamp() in the can327_netdev_start_xmit()
> function so that the module now supports TX software timestamps.
> 
> [1] commit 741b91f1b0ea ("can: dev: can_put_echo_skb(): add software
> tx timestamps")
> Link: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=741b91f1b0ea34f00f6a7d4539b767c409291fcf


Thanks!

Note to self: When I get around to do prober TX echo, I'll need to
remove this again...


Max

^ permalink raw reply	[flat|nested] 92+ messages in thread

* Re: [PATCH v4 05/14] can: tree-wide: advertise software timestamping capabilities
  2022-07-27 10:16   ` [PATCH v4 05/14] can: tree-wide: advertise software timestamping capabilities Vincent Mailhol
@ 2022-07-28  9:38     ` Marc Kleine-Budde
  2022-07-28 13:28       ` Vincent MAILHOL
  0 siblings, 1 reply; 92+ messages in thread
From: Marc Kleine-Budde @ 2022-07-28  9:38 UTC (permalink / raw)
  To: Vincent Mailhol
  Cc: linux-can, Stephane Grosjean, Jimmy Assarsson, Oliver Hartkopp,
	Dario Binacchi, Max Staudt

[-- Attachment #1: Type: text/plain, Size: 2124 bytes --]

On 27.07.2022 19:16:32, Vincent Mailhol wrote:
> 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>

[...]

> diff --git a/drivers/net/can/mscan/mscan.c b/drivers/net/can/mscan/mscan.c
> index 78a21ab63601..b1677588a4c8 100644
> --- a/drivers/net/can/mscan/mscan.c
> +++ b/drivers/net/can/mscan/mscan.c
> @@ -676,6 +676,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 */

| drivers/net/can/mscan/mscan.c: In function ‘alloc_mscandev’:
| drivers/net/can/mscan/mscan.c:679:29: error: ‘mscan_ethtool_ops’ undeclared (first use in this function)
|   679 |         dev->ethtool_ops = &mscan_ethtool_ops;
|       |                             ^~~~~~~~~~~~~~~~~
| drivers/net/can/mscan/mscan.c:679:29: note: each undeclared identifier is reported only once for each function it appears in

I'm fixing this.

Marc

-- 
Pengutronix e.K.                 | Marc Kleine-Budde           |
Embedded Linux                   | https://www.pengutronix.de  |
Vertretung West/Dortmund         | Phone: +49-231-2826-924     |
Amtsgericht Hildesheim, HRA 2686 | Fax:   +49-5121-206917-5555 |

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 92+ messages in thread

* Re: [PATCH v4 00/14] can: add ethtool support and reporting of timestamping capabilities
  2022-07-27 10:16 ` [PATCH v4 00/14] can: add ethtool support and reporting of timestamping capabilities Vincent Mailhol
                     ` (13 preceding siblings ...)
  2022-07-27 10:16   ` [PATCH v4 14/14] can: peak_usb: " Vincent Mailhol
@ 2022-07-28 10:09   ` Marc Kleine-Budde
  14 siblings, 0 replies; 92+ messages in thread
From: Marc Kleine-Budde @ 2022-07-28 10:09 UTC (permalink / raw)
  To: Vincent Mailhol
  Cc: linux-can, Stephane Grosjean, Jimmy Assarsson, Oliver Hartkopp,
	Dario Binacchi, Max Staudt

[-- Attachment #1: Type: text/plain, Size: 3668 bytes --]

On 27.07.2022 19:16:27, Vincent Mailhol wrote:
> This series revolves around ethtool and timestamping. Its ultimate
> goal is that the timestamping implementation within socketCAN meets
> the specification of other network drivers in the kernel. This way,
> tcpdump or other tools derived from libpcap can be used to do
> timestamping on CAN devices.
> 
> * Example on a device with hardware timestamp support *
> 
> Before this series:
> | # tcpdump -j adapter_unsynced -i can0
> | tcpdump: WARNING: When trying to set timestamp type
> | 'adapter_unsynced' on can0: That type of time stamp is not supported
> | by that device
> 
> After applying this series, the warning disappears and tcpdump can be
> used to get RX hardware timestamps.
> 
> 
> This series is articulated in three major parts.
> 
> * Part 1: Add TX software timestamps and report the software
>   timestamping capabilities through ethtool.
> 
> All the drivers using can_put_echo_skb() already support TX software
> timestamps. However, the five drivers not using this function (namely
> can327, janz-ican3, slcan, vcan and vxcan) lack such support. Patch 1
> to 4 adds this support.  Finally, patch 5 advertises the timesamping
> capabilities of all drivers which do not support hardware timestamps.
> 
> 
> * Part 2: add TX hardware timestapms
> 
> This part is a single patch. In SocketCAN TX hardware is equal to the
> RX hardware timestamps of the corresponding loopback frame. Reuse the
> TX hardware timestamp to populate the RX hardware timestamp. While the
> need of this feature can be debatable, we implement it here so that
> generic timestamping tools which are agnostic of the specificity of
> SocketCAN can still obtain the value. For example, tcpdump expects for
> both TX and RX hardware timestamps to be supported in order to do:
> | # tcpdump -j adapter_unsynced -i canX
> 
> 
> * Part 3: report the hardware timestamping capabilities and implement
>   the hardware timestamps ioctls.
> 
> The kernel documentation specifies in [1] that, for the drivers which
> support hardware timestamping, SIOCSHWTSTAMP ioctl must be supported
> and that SIOCGHWTSTAMP ioctl should be supported. Currently, none of
> the CAN drivers do so. This is a gap.
> 
> Furthermore, even if not specified, the tools based on libpcap
> (e.g. tcpdump) also expect ethtool_ops::get_ts_info to be implemented.
> 
> This last part first adds some generic implementation of
> net_device_ops::ndo_eth_ioctl and ethtool_ops::get_ts_info which can
> be used by the drivers with hardware timestamping capabilities.
> 
> It then uses those generic functions to add ioctl and reporting
> functionalities to the drivers with hardware timestamping support
> (namely: mcp251xfd, etas_es58x, kvaser_{pciefd,usb}, peak_{canfd,usb})
> 
> 
> [1] Kernel doc: Timestamping, section 3.1 "Hardware Timestamping
> Implementation: Device Drivers"
> Link: https://docs.kernel.org/networking/timestamping.html#hardware-timestamping-implementation-device-drivers
> 
> 
> * Testing *
> 
> I also developed a tool to test all the different timestamps. For
> those who would also like to test it, please have a look at:
> https://lore.kernel.org/linux-can/20220725134345.432367-1-mailhol.vincent@wanadoo.fr/T/

Applied to linux-can-next/master with fixed mscan driver.

regards,
Marc

-- 
Pengutronix e.K.                 | Marc Kleine-Budde           |
Embedded Linux                   | https://www.pengutronix.de  |
Vertretung West/Dortmund         | Phone: +49-231-2826-924     |
Amtsgericht Hildesheim, HRA 2686 | Fax:   +49-5121-206917-5555 |

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 92+ messages in thread

* Re: [PATCH v4 05/14] can: tree-wide: advertise software timestamping capabilities
  2022-07-28  9:38     ` Marc Kleine-Budde
@ 2022-07-28 13:28       ` Vincent MAILHOL
  2022-07-28 13:35         ` Marc Kleine-Budde
  0 siblings, 1 reply; 92+ messages in thread
From: Vincent MAILHOL @ 2022-07-28 13:28 UTC (permalink / raw)
  To: Marc Kleine-Budde
  Cc: linux-can, Stephane Grosjean, Jimmy Assarsson, Oliver Hartkopp,
	Dario Binacchi, Max Staudt

On Thu. 28 juil. 2022 at 18:42, Marc Kleine-Budde <mkl@pengutronix.de> wrote:
> On 27.07.2022 19:16:32, Vincent Mailhol wrote:
> > 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>
>
> [...]
>
> > diff --git a/drivers/net/can/mscan/mscan.c b/drivers/net/can/mscan/mscan.c
> > index 78a21ab63601..b1677588a4c8 100644
> > --- a/drivers/net/can/mscan/mscan.c
> > +++ b/drivers/net/can/mscan/mscan.c
> > @@ -676,6 +676,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 */
>
> | drivers/net/can/mscan/mscan.c: In function ‘alloc_mscandev’:
> | drivers/net/can/mscan/mscan.c:679:29: error: ‘mscan_ethtool_ops’ undeclared (first use in this function)
> |   679 |         dev->ethtool_ops = &mscan_ethtool_ops;
> |       |                             ^~~~~~~~~~~~~~~~~
> | drivers/net/can/mscan/mscan.c:679:29: note: each undeclared identifier is reported only once for each function it appears in
>
> I'm fixing this.

Thanks for catching this.

mscan does not show up in the menuconfig by default because it
requires CONFIG_PPC. And it is not possible to add CONFIG_COMPILE_TEST
to mscan's KBUILD file because some PPC specific symbols would be
missing. So this is yet another pitfall.


Yours sincerely,
Vincent Mailhol

^ permalink raw reply	[flat|nested] 92+ messages in thread

* Re: [PATCH v4 05/14] can: tree-wide: advertise software timestamping capabilities
  2022-07-28 13:28       ` Vincent MAILHOL
@ 2022-07-28 13:35         ` Marc Kleine-Budde
  0 siblings, 0 replies; 92+ messages in thread
From: Marc Kleine-Budde @ 2022-07-28 13:35 UTC (permalink / raw)
  To: Vincent MAILHOL
  Cc: linux-can, Stephane Grosjean, Jimmy Assarsson, Oliver Hartkopp,
	Dario Binacchi, Max Staudt

[-- Attachment #1: Type: text/plain, Size: 1605 bytes --]

On 28.07.2022 22:28:51, Vincent MAILHOL wrote:
> > > diff --git a/drivers/net/can/mscan/mscan.c b/drivers/net/can/mscan/mscan.c
> > > index 78a21ab63601..b1677588a4c8 100644
> > > --- a/drivers/net/can/mscan/mscan.c
> > > +++ b/drivers/net/can/mscan/mscan.c
> > > @@ -676,6 +676,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 */
> >
> > | drivers/net/can/mscan/mscan.c: In function ‘alloc_mscandev’:
> > | drivers/net/can/mscan/mscan.c:679:29: error: ‘mscan_ethtool_ops’ undeclared (first use in this function)
> > |   679 |         dev->ethtool_ops = &mscan_ethtool_ops;
> > |       |                             ^~~~~~~~~~~~~~~~~
> > | drivers/net/can/mscan/mscan.c:679:29: note: each undeclared identifier is reported only once for each function it appears in
> >
> > I'm fixing this.
> 
> Thanks for catching this.

n.p.

> mscan does not show up in the menuconfig by default because it
> requires CONFIG_PPC. And it is not possible to add CONFIG_COMPILE_TEST
> to mscan's KBUILD file because some PPC specific symbols would be
> missing. So this is yet another pitfall.

:(

Marc

-- 
Pengutronix e.K.                 | Marc Kleine-Budde           |
Embedded Linux                   | https://www.pengutronix.de  |
Vertretung West/Dortmund         | Phone: +49-231-2826-924     |
Amtsgericht Hildesheim, HRA 2686 | Fax:   +49-5121-206917-5555 |

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 92+ messages in thread

end of thread, other threads:[~2022-07-28 13:36 UTC | newest]

Thread overview: 92+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-07-25 13:31 [PATCH v1 00/24] can: add ethtool support and reporting of timestamping capabilities Vincent Mailhol
2022-07-25 13:31 ` [PATCH v1 01/24] can: can327: use KBUILD_MODNAME instead of hard coded name Vincent Mailhol
2022-07-25 13:31 ` [PATCH v1 02/24] can: ems_ubs: " Vincent Mailhol
2022-07-25 13:31 ` [PATCH v1 03/24] can: slcan: add DRV_NAME and define pr_fmt to replace hardcoded names Vincent Mailhol
2022-07-25 13:31 ` [PATCH v1 04/24] can: softing: add DRV_NAME " Vincent Mailhol
2022-07-25 13:31 ` [PATCH v1 05/24] can: esd_usb: use KBUILD_MODNAME instead of hard coded name Vincent Mailhol
2022-07-25 13:31 ` [PATCH v1 06/24] can: gs_ubs: " Vincent Mailhol
2022-07-25 13:31 ` [PATCH v1 07/24] can: softing: add DRV_NAME to replace hardcoded names Vincent Mailhol
2022-07-25 13:31 ` [PATCH v1 08/24] can: ubs_8dev: use KBUILD_MODNAME instead of hard coded name Vincent Mailhol
2022-07-25 13:31 ` [PATCH v1 09/24] can: etas_es58x: remove DRV_VERSION Vincent Mailhol
2022-07-25 13:31 ` [PATCH v1 10/24] can: tree-wide: implement ethtool_ops::get_drvinfo() Vincent Mailhol
2022-07-25 14:09   ` Marc Kleine-Budde
2022-07-25 14:29     ` Vincent MAILHOL
2022-07-26  7:29   ` Dario Binacchi
2022-07-26  8:42     ` Vincent MAILHOL
2022-07-26  9:21       ` Dario Binacchi
2022-07-26  9:59         ` Vincent MAILHOL
2022-07-27  8:19           ` Marc Kleine-Budde
2022-07-27  9:05             ` Vincent MAILHOL
2022-07-27 11:19               ` Marc Kleine-Budde
2022-07-25 13:31 ` [PATCH v1 11/24] can: can327: add software tx timestamps Vincent Mailhol
2022-07-25 13:31 ` [PATCH v1 12/24] can: janz-ican3: add software tx timestamp Vincent Mailhol
2022-07-25 13:31 ` [PATCH v1 13/24] can: slcan: add software tx timestamps Vincent Mailhol
2022-07-25 13:31 ` [PATCH v1 14/24] can: v(x)can: " Vincent Mailhol
2022-07-25 13:31 ` [PATCH v1 15/24] can: tree-wide: advertise software timestamping capabilities Vincent Mailhol
2022-07-25 13:32 ` [PATCH v1 16/24] can: dev: add hardware TX timestamp Vincent Mailhol
2022-07-25 13:32 ` [PATCH v1 17/24] can: dev: add generic function can_ethtool_op_get_ts_info_hwts() Vincent Mailhol
2022-07-25 13:32 ` [PATCH v1 18/24] can: dev: add generic function can_eth_ioctl_hwts() Vincent Mailhol
2022-07-25 14:22   ` Marc Kleine-Budde
2022-07-25 14:41     ` Vincent MAILHOL
2022-07-25 16:19       ` Marc Kleine-Budde
2022-07-25 13:32 ` [PATCH v1 19/24] can: mcp251xfd: advertise timestamping capabilities and add ioctl support Vincent Mailhol
2022-07-25 13:32 ` [PATCH v1 20/24] can: etas_es58x: " Vincent Mailhol
2022-07-25 13:32 ` [PATCH v1 21/24] can: kvaser_pciefd: " Vincent Mailhol
2022-07-25 13:32 ` [PATCH v1 22/24] can: kvaser_usb: " Vincent Mailhol
2022-07-25 13:32 ` [PATCH v1 23/24] can: peak_canfd: " Vincent Mailhol
2022-07-25 13:32 ` [PATCH v1 24/24] can: peak_usb: " Vincent Mailhol
2022-07-25 13:53 ` [PATCH v1 00/24] can: add ethtool support and reporting of timestamping capabilities Vincent MAILHOL
2022-07-25 15:53 ` [PATCH v2 00/14] " Vincent Mailhol
2022-07-25 15:53   ` [PATCH v2 01/14] can: can327: add software tx timestamps Vincent Mailhol
2022-07-25 15:53   ` [PATCH v2 02/14] can: janz-ican3: add software tx timestamp Vincent Mailhol
2022-07-25 15:53   ` [PATCH v2 03/14] can: slcan: add software tx timestamps Vincent Mailhol
2022-07-25 15:53   ` [PATCH v2 04/14] can: v(x)can: " Vincent Mailhol
2022-07-25 15:53   ` [PATCH v2 05/14] can: tree-wide: advertise software timestamping capabilities Vincent Mailhol
2022-07-25 15:53   ` [PATCH v2 06/14] can: dev: add hardware TX timestamp Vincent Mailhol
2022-07-25 15:53   ` [PATCH v2 07/14] can: dev: add generic function can_ethtool_op_get_ts_info_hwts() Vincent Mailhol
2022-07-25 15:53   ` [PATCH v2 08/14] can: dev: add generic function can_eth_ioctl_hwts() Vincent Mailhol
2022-07-25 15:53   ` [PATCH v2 09/14] can: mcp251xfd: advertise timestamping capabilities and add ioctl support Vincent Mailhol
2022-07-25 15:53   ` [PATCH v2 10/14] can: etas_es58x: " Vincent Mailhol
2022-07-25 15:53   ` [PATCH v2 11/14] can: kvaser_pciefd: " Vincent Mailhol
2022-07-25 15:53   ` [PATCH v2 12/14] can: kvaser_usb: " Vincent Mailhol
2022-07-25 15:53   ` [PATCH v2 13/14] can: peak_canfd: " Vincent Mailhol
2022-07-25 15:53   ` [PATCH v2 14/14] can: peak_usb: " Vincent Mailhol
2022-07-26 10:24 ` [PATCH v3 00/14] Vincent Mailhol
2022-07-26 10:24   ` [PATCH v3 01/14] can: can327: add software tx timestamps Vincent Mailhol
2022-07-26 10:24   ` [PATCH v3 02/14] can: janz-ican3: add software tx timestamp Vincent Mailhol
2022-07-26 10:24   ` [PATCH v3 03/14] can: slcan: add software tx timestamps Vincent Mailhol
2022-07-26 10:24   ` [PATCH v3 04/14] can: v(x)can: " Vincent Mailhol
2022-07-26 10:24   ` [PATCH v3 05/14] can: tree-wide: advertise software timestamping capabilities Vincent Mailhol
2022-07-26 10:24   ` [PATCH v3 06/14] can: dev: add hardware TX timestamp Vincent Mailhol
2022-07-26 10:24   ` [PATCH v3 07/14] can: dev: add generic function can_ethtool_op_get_ts_info_hwts() Vincent Mailhol
2022-07-26 10:24   ` [PATCH v3 08/14] can: dev: add generic function can_eth_ioctl_hwts() Vincent Mailhol
2022-07-26 10:24   ` [PATCH v3 09/14] can: mcp251xfd: advertise timestamping capabilities and add ioctl support Vincent Mailhol
2022-07-26 10:24   ` [PATCH v3 10/14] can: etas_es58x: " Vincent Mailhol
2022-07-26 10:24   ` [PATCH v3 11/14] can: kvaser_pciefd: " Vincent Mailhol
2022-07-26 10:24   ` [PATCH v3 12/14] can: kvaser_usb: " Vincent Mailhol
2022-07-26 10:24   ` [PATCH v3 13/14] can: peak_canfd: " Vincent Mailhol
2022-07-26 10:24   ` [PATCH v3 14/14] can: peak_usb: " Vincent Mailhol
2022-07-27  8:06     ` Marc Kleine-Budde
2022-07-27  8:29       ` Vincent MAILHOL
2022-07-27  8:42         ` Marc Kleine-Budde
2022-07-27  9:17           ` Vincent MAILHOL
2022-07-27 10:16 ` [PATCH v4 00/14] can: add ethtool support and reporting of timestamping capabilities Vincent Mailhol
2022-07-27 10:16   ` [PATCH v4 01/14] can: can327: add software tx timestamps Vincent Mailhol
2022-07-27 20:24     ` Max Staudt
2022-07-27 10:16   ` [PATCH v4 02/14] can: janz-ican3: add software tx timestamp Vincent Mailhol
2022-07-27 10:16   ` [PATCH v4 03/14] can: slcan: add software tx timestamps Vincent Mailhol
2022-07-27 10:16   ` [PATCH v4 04/14] can: v(x)can: " Vincent Mailhol
2022-07-27 10:16   ` [PATCH v4 05/14] can: tree-wide: advertise software timestamping capabilities Vincent Mailhol
2022-07-28  9:38     ` Marc Kleine-Budde
2022-07-28 13:28       ` Vincent MAILHOL
2022-07-28 13:35         ` Marc Kleine-Budde
2022-07-27 10:16   ` [PATCH v4 06/14] can: dev: add hardware TX timestamp Vincent Mailhol
2022-07-27 10:16   ` [PATCH v4 07/14] can: dev: add generic function can_ethtool_op_get_ts_info_hwts() Vincent Mailhol
2022-07-27 10:16   ` [PATCH v4 08/14] can: dev: add generic function can_eth_ioctl_hwts() Vincent Mailhol
2022-07-27 10:16   ` [PATCH v4 09/14] can: mcp251xfd: advertise timestamping capabilities and add ioctl support Vincent Mailhol
2022-07-27 10:16   ` [PATCH v4 10/14] can: etas_es58x: " Vincent Mailhol
2022-07-27 10:16   ` [PATCH v4 11/14] can: kvaser_pciefd: " Vincent Mailhol
2022-07-27 10:16   ` [PATCH v4 12/14] can: kvaser_usb: " Vincent Mailhol
2022-07-27 10:16   ` [PATCH v4 13/14] can: peak_canfd: " Vincent Mailhol
2022-07-27 10:16   ` [PATCH v4 14/14] can: peak_usb: " Vincent Mailhol
2022-07-28 10:09   ` [PATCH v4 00/14] can: add ethtool support and reporting of timestamping capabilities Marc Kleine-Budde

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.