1
linux/drivers/net/can/slcan/slcan-ethtool.c
Vincent Mailhol 409c188c57 can: tree-wide: advertise software timestamping capabilities
Currently, some CAN drivers support hardware timestamping, some do
not. But userland has no method to query which features are supported
(aside maybe of getting RX messages and observe whether or not
hardware timestamps stay at zero).

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

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

This way, userland can do:

| $ ethtool --show-time-stamping canX

to confirm the device timestamping capacities.

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

Signed-off-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
Link: https://lore.kernel.org/all/20220727101641.198847-6-mailhol.vincent@wanadoo.fr
[mkl: mscan: add missing mscan_ethtool_ops]
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
2022-07-28 11:44:01 +02:00

62 lines
1.5 KiB
C

// SPDX-License-Identifier: GPL-2.0+
/* Copyright (c) 2022 Amarula Solutions, Dario Binacchi <dario.binacchi@amarulasolutions.com>
*
*/
#include <linux/can/dev.h>
#include <linux/ethtool.h>
#include <linux/kernel.h>
#include <linux/netdevice.h>
#include <linux/platform_device.h>
#include "slcan.h"
static const char slcan_priv_flags_strings[][ETH_GSTRING_LEN] = {
#define SLCAN_PRIV_FLAGS_ERR_RST_ON_OPEN BIT(0)
"err-rst-on-open",
};
static void slcan_get_strings(struct net_device *ndev, u32 stringset, u8 *data)
{
switch (stringset) {
case ETH_SS_PRIV_FLAGS:
memcpy(data, slcan_priv_flags_strings,
sizeof(slcan_priv_flags_strings));
}
}
static u32 slcan_get_priv_flags(struct net_device *ndev)
{
u32 flags = 0;
if (slcan_err_rst_on_open(ndev))
flags |= SLCAN_PRIV_FLAGS_ERR_RST_ON_OPEN;
return flags;
}
static int slcan_set_priv_flags(struct net_device *ndev, u32 flags)
{
bool err_rst_op_open = !!(flags & SLCAN_PRIV_FLAGS_ERR_RST_ON_OPEN);
return slcan_enable_err_rst_on_open(ndev, err_rst_op_open);
}
static int slcan_get_sset_count(struct net_device *netdev, int sset)
{
switch (sset) {
case ETH_SS_PRIV_FLAGS:
return ARRAY_SIZE(slcan_priv_flags_strings);
default:
return -EOPNOTSUPP;
}
}
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,
.get_ts_info = ethtool_op_get_ts_info,
};