Skip to content

Commit fd77be7

Browse files
mkubecekdavem330
authored andcommitted
ethtool: set EEE settings with EEE_SET request
Implement EEE_SET netlink request to set EEE settings of a network device. These are traditionally set with ETHTOOL_SEEE ioctl request. The netlink interface allows setting the EEE status for all link modes supported by kernel but only first 32 link modes can be set at the moment as only those are supported by the ethtool_ops callback. Signed-off-by: Michal Kubecek <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent b7eeefe commit fd77be7

File tree

5 files changed

+104
-1
lines changed

5 files changed

+104
-1
lines changed

Documentation/networking/ethtool-netlink.rst

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,7 @@ Userspace to kernel:
202202
``ETHTOOL_MSG_PAUSE_GET`` get pause parameters
203203
``ETHTOOL_MSG_PAUSE_SET`` set pause parameters
204204
``ETHTOOL_MSG_EEE_GET`` get EEE settings
205+
``ETHTOOL_MSG_EEE_SET`` set EEE settings
205206
===================================== ================================
206207

207208
Kernel to userspace:
@@ -904,6 +905,28 @@ netlink interface allows reporting EEE status for all link modes but only
904905
first 32 are provided by the ``ethtool_ops`` callback.
905906

906907

908+
EEE_SET
909+
=======
910+
911+
Sets pause parameters like ``ETHTOOL_GEEEPARAM`` ioctl request.
912+
913+
Request contents:
914+
915+
===================================== ====== ==========================
916+
``ETHTOOL_A_EEE_HEADER`` nested request header
917+
``ETHTOOL_A_EEE_MODES_OURS`` bool advertised modes
918+
``ETHTOOL_A_EEE_ENABLED`` bool EEE is enabled
919+
``ETHTOOL_A_EEE_TX_LPI_ENABLED`` bool Tx lpi enabled
920+
``ETHTOOL_A_EEE_TX_LPI_TIMER`` u32 Tx lpi timeout (in us)
921+
===================================== ====== ==========================
922+
923+
``ETHTOOL_A_EEE_MODES_OURS`` is used to either list link modes to advertise
924+
EEE for (if there is no mask) or specify changes to the list (if there is
925+
a mask). The netlink interface allows reporting EEE status for all link modes
926+
but only first 32 can be set at the moment as that is what the ``ethtool_ops``
927+
callback supports.
928+
929+
907930
Request translation
908931
===================
909932

@@ -983,7 +1006,7 @@ have their netlink replacement yet.
9831006
``ETHTOOL_GMODULEINFO`` n/a
9841007
``ETHTOOL_GMODULEEEPROM`` n/a
9851008
``ETHTOOL_GEEE`` ``ETHTOOL_MSG_EEE_GET``
986-
``ETHTOOL_SEEE`` n/a
1009+
``ETHTOOL_SEEE`` ``ETHTOOL_MSG_EEE_SET``
9871010
``ETHTOOL_GRSSH`` n/a
9881011
``ETHTOOL_SRSSH`` n/a
9891012
``ETHTOOL_GTUNABLE`` n/a

include/uapi/linux/ethtool_netlink.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ enum {
3737
ETHTOOL_MSG_PAUSE_GET,
3838
ETHTOOL_MSG_PAUSE_SET,
3939
ETHTOOL_MSG_EEE_GET,
40+
ETHTOOL_MSG_EEE_SET,
4041

4142
/* add new constants above here */
4243
__ETHTOOL_MSG_USER_CNT,

net/ethtool/eee.c

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,3 +128,76 @@ const struct ethnl_request_ops ethnl_eee_request_ops = {
128128
.reply_size = eee_reply_size,
129129
.fill_reply = eee_fill_reply,
130130
};
131+
132+
/* EEE_SET */
133+
134+
static const struct nla_policy
135+
eee_set_policy[ETHTOOL_A_EEE_MAX + 1] = {
136+
[ETHTOOL_A_EEE_UNSPEC] = { .type = NLA_REJECT },
137+
[ETHTOOL_A_EEE_HEADER] = { .type = NLA_NESTED },
138+
[ETHTOOL_A_EEE_MODES_OURS] = { .type = NLA_NESTED },
139+
[ETHTOOL_A_EEE_MODES_PEER] = { .type = NLA_REJECT },
140+
[ETHTOOL_A_EEE_ACTIVE] = { .type = NLA_REJECT },
141+
[ETHTOOL_A_EEE_ENABLED] = { .type = NLA_U8 },
142+
[ETHTOOL_A_EEE_TX_LPI_ENABLED] = { .type = NLA_U8 },
143+
[ETHTOOL_A_EEE_TX_LPI_TIMER] = { .type = NLA_U32 },
144+
};
145+
146+
int ethnl_set_eee(struct sk_buff *skb, struct genl_info *info)
147+
{
148+
struct nlattr *tb[ETHTOOL_A_EEE_MAX + 1];
149+
struct ethtool_eee eee = {};
150+
struct ethnl_req_info req_info = {};
151+
const struct ethtool_ops *ops;
152+
struct net_device *dev;
153+
bool mod = false;
154+
int ret;
155+
156+
ret = nlmsg_parse(info->nlhdr, GENL_HDRLEN, tb, ETHTOOL_A_EEE_MAX,
157+
eee_set_policy, info->extack);
158+
if (ret < 0)
159+
return ret;
160+
ret = ethnl_parse_header_dev_get(&req_info,
161+
tb[ETHTOOL_A_EEE_HEADER],
162+
genl_info_net(info), info->extack,
163+
true);
164+
if (ret < 0)
165+
return ret;
166+
dev = req_info.dev;
167+
ops = dev->ethtool_ops;
168+
ret = -EOPNOTSUPP;
169+
if (!ops->get_eee || !ops->set_eee)
170+
goto out_dev;
171+
172+
rtnl_lock();
173+
ret = ethnl_ops_begin(dev);
174+
if (ret < 0)
175+
goto out_rtnl;
176+
ret = ops->get_eee(dev, &eee);
177+
if (ret < 0)
178+
goto out_ops;
179+
180+
ret = ethnl_update_bitset32(&eee.advertised, EEE_MODES_COUNT,
181+
tb[ETHTOOL_A_EEE_MODES_OURS],
182+
link_mode_names, info->extack, &mod);
183+
if (ret < 0)
184+
goto out_ops;
185+
ethnl_update_bool32(&eee.eee_enabled, tb[ETHTOOL_A_EEE_ENABLED], &mod);
186+
ethnl_update_bool32(&eee.tx_lpi_enabled,
187+
tb[ETHTOOL_A_EEE_TX_LPI_ENABLED], &mod);
188+
ethnl_update_bool32(&eee.tx_lpi_timer, tb[ETHTOOL_A_EEE_TX_LPI_TIMER],
189+
&mod);
190+
ret = 0;
191+
if (!mod)
192+
goto out_ops;
193+
194+
ret = dev->ethtool_ops->set_eee(dev, &eee);
195+
196+
out_ops:
197+
ethnl_ops_complete(dev);
198+
out_rtnl:
199+
rtnl_unlock();
200+
out_dev:
201+
dev_put(dev);
202+
return ret;
203+
}

net/ethtool/netlink.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -824,6 +824,11 @@ static const struct genl_ops ethtool_genl_ops[] = {
824824
.dumpit = ethnl_default_dumpit,
825825
.done = ethnl_default_done,
826826
},
827+
{
828+
.cmd = ETHTOOL_MSG_EEE_SET,
829+
.flags = GENL_UNS_ADMIN_PERM,
830+
.doit = ethnl_set_eee,
831+
},
827832
};
828833

829834
static const struct genl_multicast_group ethtool_nl_mcgrps[] = {

net/ethtool/netlink.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -355,5 +355,6 @@ int ethnl_set_rings(struct sk_buff *skb, struct genl_info *info);
355355
int ethnl_set_channels(struct sk_buff *skb, struct genl_info *info);
356356
int ethnl_set_coalesce(struct sk_buff *skb, struct genl_info *info);
357357
int ethnl_set_pause(struct sk_buff *skb, struct genl_info *info);
358+
int ethnl_set_eee(struct sk_buff *skb, struct genl_info *info);
358359

359360
#endif /* _NET_ETHTOOL_NETLINK_H */

0 commit comments

Comments
 (0)