1 | // SPDX-License-Identifier: GPL-2.0+ |
2 | /* Copyright (c) 2022 Amarula Solutions, Dario Binacchi <dario.binacchi@amarulasolutions.com> |
3 | * |
4 | */ |
5 | |
6 | #include <linux/can/dev.h> |
7 | #include <linux/ethtool.h> |
8 | #include <linux/kernel.h> |
9 | #include <linux/netdevice.h> |
10 | #include <linux/platform_device.h> |
11 | |
12 | #include "slcan.h" |
13 | |
14 | static const char slcan_priv_flags_strings[][ETH_GSTRING_LEN] = { |
15 | #define SLCAN_PRIV_FLAGS_ERR_RST_ON_OPEN BIT(0) |
16 | "err-rst-on-open" , |
17 | }; |
18 | |
19 | static void slcan_get_strings(struct net_device *ndev, u32 stringset, u8 *data) |
20 | { |
21 | switch (stringset) { |
22 | case ETH_SS_PRIV_FLAGS: |
23 | memcpy(data, slcan_priv_flags_strings, |
24 | sizeof(slcan_priv_flags_strings)); |
25 | } |
26 | } |
27 | |
28 | static u32 slcan_get_priv_flags(struct net_device *ndev) |
29 | { |
30 | u32 flags = 0; |
31 | |
32 | if (slcan_err_rst_on_open(ndev)) |
33 | flags |= SLCAN_PRIV_FLAGS_ERR_RST_ON_OPEN; |
34 | |
35 | return flags; |
36 | } |
37 | |
38 | static int slcan_set_priv_flags(struct net_device *ndev, u32 flags) |
39 | { |
40 | bool err_rst_op_open = !!(flags & SLCAN_PRIV_FLAGS_ERR_RST_ON_OPEN); |
41 | |
42 | return slcan_enable_err_rst_on_open(ndev, on: err_rst_op_open); |
43 | } |
44 | |
45 | static int slcan_get_sset_count(struct net_device *netdev, int sset) |
46 | { |
47 | switch (sset) { |
48 | case ETH_SS_PRIV_FLAGS: |
49 | return ARRAY_SIZE(slcan_priv_flags_strings); |
50 | default: |
51 | return -EOPNOTSUPP; |
52 | } |
53 | } |
54 | |
55 | const struct ethtool_ops slcan_ethtool_ops = { |
56 | .get_strings = slcan_get_strings, |
57 | .get_priv_flags = slcan_get_priv_flags, |
58 | .set_priv_flags = slcan_set_priv_flags, |
59 | .get_sset_count = slcan_get_sset_count, |
60 | .get_ts_info = ethtool_op_get_ts_info, |
61 | }; |
62 | |