History

ethtool: provide EEE settings with EEE_GET request

Implement EEE_GET request to get EEE settings of a network device. These are traditionally available via ETHTOOL_GEEE ioctl request. The netlink interface allows reporting EEE status for all link modes supported by kernel but only first 32 link modes are provided at the moment as only those are reported by the ethtool_ops callback and drivers. v2: fix alignment (whitespace only)

Michal Kubecek committed 6 years ago

Commit b7eeefe1 parent bf37faa6 files · +192 −2Browse files

Unified · Split

6 files
  1. Documentation/networking/ethtool-netlink.rst +33 −1
  2. include/uapi/linux/ethtool_netlink.h +19 −0
  3. net/ethtool/Makefile +1 −1
  4. net/ethtool/eee.c +130 −0
  5. net/ethtool/netlink.c +8 −0
  6. net/ethtool/netlink.h +1 −0
Documentation/networking/ethtool-netlink.rst+33−1
@@ -201,6 +201,7 @@ Userspace to kernel: · 200 unmodified lines
201201 ``ETHTOOL_MSG_COALESCE_SET`` set coalescing parameters
202202 ``ETHTOOL_MSG_PAUSE_GET`` get pause parameters
203203 ``ETHTOOL_MSG_PAUSE_SET`` set pause parameters
204+ ``ETHTOOL_MSG_EEE_GET`` get EEE settings
204205 ===================================== ================================
205206
206207 Kernel to userspace:
@@ -229,6 +230,7 @@ Kernel to userspace: · 22 unmodified lines
229230 ``ETHTOOL_MSG_COALESCE_NTF`` coalescing parameters
230231 ``ETHTOOL_MSG_PAUSE_GET_REPLY`` pause parameters
231232 ``ETHTOOL_MSG_PAUSE_NTF`` pause parameters
233+ ``ETHTOOL_MSG_EEE_GET_REPLY`` EEE settings
232234 ===================================== =================================
233235
234236 ``GET`` requests are sent by userspace applications to retrieve device
@@ -872,6 +874,36 @@ Request contents: · 637 unmodified lines
872874 ===================================== ====== ==========================
873875
874876
877+EEE_GET
878+=======
879+
880+Gets channel counts like ``ETHTOOL_GEEE`` ioctl request.
881+
882+Request contents:
883+
884+ ===================================== ====== ==========================
885+ ``ETHTOOL_A_EEE_HEADER`` nested request header
886+ ===================================== ====== ==========================
887+
888+Kernel response contents:
889+
890+ ===================================== ====== ==========================
891+ ``ETHTOOL_A_EEE_HEADER`` nested request header
892+ ``ETHTOOL_A_EEE_MODES_OURS`` bool supported/advertised modes
893+ ``ETHTOOL_A_EEE_MODES_PEER`` bool peer advertised link modes
894+ ``ETHTOOL_A_EEE_ACTIVE`` bool EEE is actively used
895+ ``ETHTOOL_A_EEE_ENABLED`` bool EEE is enabled
896+ ``ETHTOOL_A_EEE_TX_LPI_ENABLED`` bool Tx lpi enabled
897+ ``ETHTOOL_A_EEE_TX_LPI_TIMER`` u32 Tx lpi timeout (in us)
898+ ===================================== ====== ==========================
899+
900+In ``ETHTOOL_A_EEE_MODES_OURS``, mask consists of link modes for which EEE is
901+enabled, value of link modes for which EEE is advertised. Link modes for which
902+peer advertises EEE are listed in ``ETHTOOL_A_EEE_MODES_PEER`` (no mask). The
903+netlink interface allows reporting EEE status for all link modes but only
904+first 32 are provided by the ``ethtool_ops`` callback.
905+
906+
875907 Request translation
876908 ===================
877909
@@ -950,7 +982,7 @@ have their netlink replacement yet. · 72 unmodified lines
950982 ``ETHTOOL_GET_TS_INFO`` n/a
951983 ``ETHTOOL_GMODULEINFO`` n/a
952984 ``ETHTOOL_GMODULEEEPROM`` n/a
953− ``ETHTOOL_GEEE`` n/a
985+ ``ETHTOOL_GEEE`` ``ETHTOOL_MSG_EEE_GET``
954986 ``ETHTOOL_SEEE`` n/a
955987 ``ETHTOOL_GRSSH`` n/a
956988 ``ETHTOOL_SRSSH`` n/a
include/uapi/linux/ethtool_netlink.h+19−0
@@ -36,6 +36,7 @@ enum { · 35 unmodified lines
3636 ETHTOOL_MSG_COALESCE_SET,
3737 ETHTOOL_MSG_PAUSE_GET,
3838 ETHTOOL_MSG_PAUSE_SET,
39+ ETHTOOL_MSG_EEE_GET,
3940
4041 /* add new constants above here */
4142 __ETHTOOL_MSG_USER_CNT,
@@ -68,6 +69,7 @@ enum { · 26 unmodified lines
6869 ETHTOOL_MSG_COALESCE_NTF,
6970 ETHTOOL_MSG_PAUSE_GET_REPLY,
7071 ETHTOOL_MSG_PAUSE_NTF,
72+ ETHTOOL_MSG_EEE_GET_REPLY,
7173
7274 /* add new constants above here */
7375 __ETHTOOL_MSG_KERNEL_CNT,
@@ -365,6 +367,23 @@ enum { · 291 unmodified lines
365367 ETHTOOL_A_PAUSE_MAX = (__ETHTOOL_A_PAUSE_CNT - 1)
366368 };
367369
370+/* EEE */
371+
372+enum {
373+ ETHTOOL_A_EEE_UNSPEC,
374+ ETHTOOL_A_EEE_HEADER, /* nest - _A_HEADER_* */
375+ ETHTOOL_A_EEE_MODES_OURS, /* bitset */
376+ ETHTOOL_A_EEE_MODES_PEER, /* bitset */
377+ ETHTOOL_A_EEE_ACTIVE, /* u8 */
378+ ETHTOOL_A_EEE_ENABLED, /* u8 */
379+ ETHTOOL_A_EEE_TX_LPI_ENABLED, /* u8 */
380+ ETHTOOL_A_EEE_TX_LPI_TIMER, /* u32 */
381+
382+ /* add new constants above here */
383+ __ETHTOOL_A_EEE_CNT,
384+ ETHTOOL_A_EEE_MAX = (__ETHTOOL_A_EEE_CNT - 1)
385+};
386+
368387 /* generic netlink info */
369388 #define ETHTOOL_GENL_NAME "ethtool"
370389 #define ETHTOOL_GENL_VERSION 1
net/ethtool/Makefile+1−1
@@ -6,4 +6,4 @@ obj-$(CONFIG_ETHTOOL_NETLINK) += ethtool_nl.o · 5 unmodified lines
66
77 ethtool_nl-y := netlink.o bitset.o strset.o linkinfo.o linkmodes.o \
88 linkstate.o debug.o wol.o features.o privflags.o rings.o \
9− channels.o coalesce.o pause.o
9+ channels.o coalesce.o pause.o eee.o
net/ethtool/eee.c+130−0
@@ -0,0 +1,130 @@
1+// SPDX-License-Identifier: GPL-2.0-only
2+
3+#include "netlink.h"
4+#include "common.h"
5+#include "bitset.h"
6+
7+#define EEE_MODES_COUNT \
8+ (sizeof_field(struct ethtool_eee, supported) * BITS_PER_BYTE)
9+
10+struct eee_req_info {
11+ struct ethnl_req_info base;
12+};
13+
14+struct eee_reply_data {
15+ struct ethnl_reply_data base;
16+ struct ethtool_eee eee;
17+};
18+
19+#define EEE_REPDATA(__reply_base) \
20+ container_of(__reply_base, struct eee_reply_data, base)
21+
22+static const struct nla_policy
23+eee_get_policy[ETHTOOL_A_EEE_MAX + 1] = {
24+ [ETHTOOL_A_EEE_UNSPEC] = { .type = NLA_REJECT },
25+ [ETHTOOL_A_EEE_HEADER] = { .type = NLA_NESTED },
26+ [ETHTOOL_A_EEE_MODES_OURS] = { .type = NLA_REJECT },
27+ [ETHTOOL_A_EEE_MODES_PEER] = { .type = NLA_REJECT },
28+ [ETHTOOL_A_EEE_ACTIVE] = { .type = NLA_REJECT },
29+ [ETHTOOL_A_EEE_ENABLED] = { .type = NLA_REJECT },
30+ [ETHTOOL_A_EEE_TX_LPI_ENABLED] = { .type = NLA_REJECT },
31+ [ETHTOOL_A_EEE_TX_LPI_TIMER] = { .type = NLA_REJECT },
32+};
33+
34+static int eee_prepare_data(const struct ethnl_req_info *req_base,
35+ struct ethnl_reply_data *reply_base,
36+ struct genl_info *info)
37+{
38+ struct eee_reply_data *data = EEE_REPDATA(reply_base);
39+ struct net_device *dev = reply_base->dev;
40+ int ret;
41+
42+ if (!dev->ethtool_ops->get_eee)
43+ return -EOPNOTSUPP;
44+ ret = ethnl_ops_begin(dev);
45+ if (ret < 0)
46+ return ret;
47+ ret = dev->ethtool_ops->get_eee(dev, &data->eee);
48+ ethnl_ops_complete(dev);
49+
50+ return ret;
51+}
52+
53+static int eee_reply_size(const struct ethnl_req_info *req_base,
54+ const struct ethnl_reply_data *reply_base)
55+{
56+ bool compact = req_base->flags & ETHTOOL_FLAG_COMPACT_BITSETS;
57+ const struct eee_reply_data *data = EEE_REPDATA(reply_base);
58+ const struct ethtool_eee *eee = &data->eee;
59+ int len = 0;
60+ int ret;
61+
62+ BUILD_BUG_ON(sizeof(eee->advertised) * BITS_PER_BYTE !=
63+ EEE_MODES_COUNT);
64+ BUILD_BUG_ON(sizeof(eee->lp_advertised) * BITS_PER_BYTE !=
65+ EEE_MODES_COUNT);
66+
67+ /* MODES_OURS */
68+ ret = ethnl_bitset32_size(&eee->advertised, &eee->supported,
69+ EEE_MODES_COUNT, link_mode_names, compact);
70+ if (ret < 0)
71+ return ret;
72+ len += ret;
73+ /* MODES_PEERS */
74+ ret = ethnl_bitset32_size(&eee->lp_advertised, NULL,
75+ EEE_MODES_COUNT, link_mode_names, compact);
76+ if (ret < 0)
77+ return ret;
78+ len += ret;
79+
80+ len += nla_total_size(sizeof(u8)) + /* _EEE_ACTIVE */
81+ nla_total_size(sizeof(u8)) + /* _EEE_ENABLED */
82+ nla_total_size(sizeof(u8)) + /* _EEE_TX_LPI_ENABLED */
83+ nla_total_size(sizeof(u32)); /* _EEE_TX_LPI_TIMER */
84+
85+ return len;
86+}
87+
88+static int eee_fill_reply(struct sk_buff *skb,
89+ const struct ethnl_req_info *req_base,
90+ const struct ethnl_reply_data *reply_base)
91+{
92+ bool compact = req_base->flags & ETHTOOL_FLAG_COMPACT_BITSETS;
93+ const struct eee_reply_data *data = EEE_REPDATA(reply_base);
94+ const struct ethtool_eee *eee = &data->eee;
95+ int ret;
96+
97+ ret = ethnl_put_bitset32(skb, ETHTOOL_A_EEE_MODES_OURS,
98+ &eee->advertised, &eee->supported,
99+ EEE_MODES_COUNT, link_mode_names, compact);
100+ if (ret < 0)
101+ return ret;
102+ ret = ethnl_put_bitset32(skb, ETHTOOL_A_EEE_MODES_PEER,
103+ &eee->lp_advertised, NULL, EEE_MODES_COUNT,
104+ link_mode_names, compact);
105+ if (ret < 0)
106+ return ret;
107+
108+ if (nla_put_u8(skb, ETHTOOL_A_EEE_ACTIVE, !!eee->eee_active) ||
109+ nla_put_u8(skb, ETHTOOL_A_EEE_ENABLED, !!eee->eee_enabled) ||
110+ nla_put_u8(skb, ETHTOOL_A_EEE_TX_LPI_ENABLED,
111+ !!eee->tx_lpi_enabled) ||
112+ nla_put_u32(skb, ETHTOOL_A_EEE_TX_LPI_TIMER, eee->tx_lpi_timer))
113+ return -EMSGSIZE;
114+
115+ return 0;
116+}
117+
118+const struct ethnl_request_ops ethnl_eee_request_ops = {
119+ .request_cmd = ETHTOOL_MSG_EEE_GET,
120+ .reply_cmd = ETHTOOL_MSG_EEE_GET_REPLY,
121+ .hdr_attr = ETHTOOL_A_EEE_HEADER,
122+ .max_attr = ETHTOOL_A_EEE_MAX,
123+ .req_info_size = sizeof(struct eee_req_info),
124+ .reply_data_size = sizeof(struct eee_reply_data),
125+ .request_policy = eee_get_policy,
126+
127+ .prepare_data = eee_prepare_data,
128+ .reply_size = eee_reply_size,
129+ .fill_reply = eee_fill_reply,
130+};
net/ethtool/netlink.c+8−0
@@ -229,6 +229,7 @@ ethnl_default_requests[__ETHTOOL_MSG_USER_CNT] = { · 228 unmodified lines
229229 [ETHTOOL_MSG_CHANNELS_GET] = &ethnl_channels_request_ops,
230230 [ETHTOOL_MSG_COALESCE_GET] = &ethnl_coalesce_request_ops,
231231 [ETHTOOL_MSG_PAUSE_GET] = &ethnl_pause_request_ops,
232+ [ETHTOOL_MSG_EEE_GET] = &ethnl_eee_request_ops,
232233 };
233234
234235 static struct ethnl_dump_ctx *ethnl_dump_context(struct netlink_callback *cb)
@@ -816,6 +817,13 @@ static const struct genl_ops ethtool_genl_ops[] = { · 581 unmodified lines
816817 .flags = GENL_UNS_ADMIN_PERM,
817818 .doit = ethnl_set_pause,
818819 },
820+ {
821+ .cmd = ETHTOOL_MSG_EEE_GET,
822+ .doit = ethnl_default_doit,
823+ .start = ethnl_default_start,
824+ .dumpit = ethnl_default_dumpit,
825+ .done = ethnl_default_done,
826+ },
819827 };
820828
821829 static const struct genl_multicast_group ethtool_nl_mcgrps[] = {
net/ethtool/netlink.h+1−0
@@ -343,6 +343,7 @@ extern const struct ethnl_request_ops ethnl_rings_request_ops; · 342 unmodified lines
343343 extern const struct ethnl_request_ops ethnl_channels_request_ops;
344344 extern const struct ethnl_request_ops ethnl_coalesce_request_ops;
345345 extern const struct ethnl_request_ops ethnl_pause_request_ops;
346+extern const struct ethnl_request_ops ethnl_eee_request_ops;
346347
347348 int ethnl_set_linkinfo(struct sk_buff *skb, struct genl_info *info);
348349 int ethnl_set_linkmodes(struct sk_buff *skb, struct genl_info *info);