Line data Source code
1 : // SPDX-License-Identifier: GPL-2.0-or-later
2 : /*
3 : * net/core/ethtool.c - Ethtool ioctl handler
4 : * Copyright (c) 2003 Matthew Wilcox <matthew@wil.cx>
5 : *
6 : * This file is where we call all the ethtool_ops commands to get
7 : * the information ethtool needs.
8 : */
9 :
10 : #include <linux/module.h>
11 : #include <linux/types.h>
12 : #include <linux/capability.h>
13 : #include <linux/errno.h>
14 : #include <linux/ethtool.h>
15 : #include <linux/netdevice.h>
16 : #include <linux/net_tstamp.h>
17 : #include <linux/phy.h>
18 : #include <linux/bitops.h>
19 : #include <linux/uaccess.h>
20 : #include <linux/vmalloc.h>
21 : #include <linux/sfp.h>
22 : #include <linux/slab.h>
23 : #include <linux/rtnetlink.h>
24 : #include <linux/sched/signal.h>
25 : #include <linux/net.h>
26 : #include <net/devlink.h>
27 : #include <net/xdp_sock_drv.h>
28 : #include <net/flow_offload.h>
29 : #include <linux/ethtool_netlink.h>
30 : #include <generated/utsrelease.h>
31 : #include "common.h"
32 :
33 : /*
34 : * Some useful ethtool_ops methods that're device independent.
35 : * If we find that all drivers want to do the same thing here,
36 : * we can turn these into dev_() function calls.
37 : */
38 :
39 0 : u32 ethtool_op_get_link(struct net_device *dev)
40 : {
41 0 : return netif_carrier_ok(dev) ? 1 : 0;
42 : }
43 : EXPORT_SYMBOL(ethtool_op_get_link);
44 :
45 0 : int ethtool_op_get_ts_info(struct net_device *dev, struct ethtool_ts_info *info)
46 : {
47 0 : info->so_timestamping =
48 : SOF_TIMESTAMPING_TX_SOFTWARE |
49 : SOF_TIMESTAMPING_RX_SOFTWARE |
50 : SOF_TIMESTAMPING_SOFTWARE;
51 0 : info->phc_index = -1;
52 0 : return 0;
53 : }
54 : EXPORT_SYMBOL(ethtool_op_get_ts_info);
55 :
56 : /* Handlers for each ethtool command */
57 :
58 0 : static int ethtool_get_features(struct net_device *dev, void __user *useraddr)
59 : {
60 0 : struct ethtool_gfeatures cmd = {
61 : .cmd = ETHTOOL_GFEATURES,
62 : .size = ETHTOOL_DEV_FEATURE_WORDS,
63 : };
64 0 : struct ethtool_get_features_block features[ETHTOOL_DEV_FEATURE_WORDS];
65 0 : u32 __user *sizeaddr;
66 0 : u32 copy_size;
67 0 : int i;
68 :
69 : /* in case feature bits run out again */
70 0 : BUILD_BUG_ON(ETHTOOL_DEV_FEATURE_WORDS * sizeof(u32) > sizeof(netdev_features_t));
71 :
72 0 : for (i = 0; i < ETHTOOL_DEV_FEATURE_WORDS; ++i) {
73 0 : features[i].available = (u32)(dev->hw_features >> (32 * i));
74 0 : features[i].requested = (u32)(dev->wanted_features >> (32 * i));
75 0 : features[i].active = (u32)(dev->features >> (32 * i));
76 0 : features[i].never_changed =
77 0 : (u32)(NETIF_F_NEVER_CHANGE >> (32 * i));
78 : }
79 :
80 0 : sizeaddr = useraddr + offsetof(struct ethtool_gfeatures, size);
81 0 : if (get_user(copy_size, sizeaddr))
82 : return -EFAULT;
83 :
84 0 : if (copy_size > ETHTOOL_DEV_FEATURE_WORDS)
85 : copy_size = ETHTOOL_DEV_FEATURE_WORDS;
86 :
87 0 : if (copy_to_user(useraddr, &cmd, sizeof(cmd)))
88 : return -EFAULT;
89 0 : useraddr += sizeof(cmd);
90 0 : if (copy_to_user(useraddr, features, copy_size * sizeof(*features)))
91 0 : return -EFAULT;
92 :
93 : return 0;
94 : }
95 :
96 2 : static int ethtool_set_features(struct net_device *dev, void __user *useraddr)
97 : {
98 2 : struct ethtool_sfeatures cmd;
99 2 : struct ethtool_set_features_block features[ETHTOOL_DEV_FEATURE_WORDS];
100 2 : netdev_features_t wanted = 0, valid = 0;
101 2 : int i, ret = 0;
102 :
103 2 : if (copy_from_user(&cmd, useraddr, sizeof(cmd)))
104 : return -EFAULT;
105 2 : useraddr += sizeof(cmd);
106 :
107 2 : if (cmd.size != ETHTOOL_DEV_FEATURE_WORDS)
108 : return -EINVAL;
109 :
110 2 : if (copy_from_user(features, useraddr, sizeof(features)))
111 : return -EFAULT;
112 :
113 6 : for (i = 0; i < ETHTOOL_DEV_FEATURE_WORDS; ++i) {
114 4 : valid |= (netdev_features_t)features[i].valid << (32 * i);
115 4 : wanted |= (netdev_features_t)features[i].requested << (32 * i);
116 : }
117 :
118 2 : if (valid & ~NETIF_F_ETHTOOL_BITS)
119 : return -EINVAL;
120 :
121 2 : if (valid & ~dev->hw_features) {
122 0 : valid &= dev->hw_features;
123 0 : ret |= ETHTOOL_F_UNSUPPORTED;
124 : }
125 :
126 2 : dev->wanted_features &= ~valid;
127 2 : dev->wanted_features |= wanted & valid;
128 2 : __netdev_update_features(dev);
129 :
130 2 : if ((dev->wanted_features ^ dev->features) & valid)
131 0 : ret |= ETHTOOL_F_WISH;
132 :
133 : return ret;
134 : }
135 :
136 4 : static int __ethtool_get_sset_count(struct net_device *dev, int sset)
137 : {
138 4 : const struct ethtool_phy_ops *phy_ops = ethtool_phy_ops;
139 4 : const struct ethtool_ops *ops = dev->ethtool_ops;
140 :
141 4 : if (sset == ETH_SS_FEATURES)
142 : return ARRAY_SIZE(netdev_features_strings);
143 :
144 0 : if (sset == ETH_SS_RSS_HASH_FUNCS)
145 : return ARRAY_SIZE(rss_hash_func_strings);
146 :
147 0 : if (sset == ETH_SS_TUNABLES)
148 : return ARRAY_SIZE(tunable_strings);
149 :
150 0 : if (sset == ETH_SS_PHY_TUNABLES)
151 : return ARRAY_SIZE(phy_tunable_strings);
152 :
153 0 : if (sset == ETH_SS_PHY_STATS && dev->phydev &&
154 0 : !ops->get_ethtool_phy_stats &&
155 0 : phy_ops && phy_ops->get_sset_count)
156 0 : return phy_ops->get_sset_count(dev->phydev);
157 :
158 0 : if (sset == ETH_SS_LINK_MODES)
159 : return __ETHTOOL_LINK_MODE_MASK_NBITS;
160 :
161 0 : if (ops->get_sset_count && ops->get_strings)
162 0 : return ops->get_sset_count(dev, sset);
163 : else
164 : return -EOPNOTSUPP;
165 : }
166 :
167 2 : static void __ethtool_get_strings(struct net_device *dev,
168 : u32 stringset, u8 *data)
169 : {
170 2 : const struct ethtool_phy_ops *phy_ops = ethtool_phy_ops;
171 2 : const struct ethtool_ops *ops = dev->ethtool_ops;
172 :
173 2 : if (stringset == ETH_SS_FEATURES)
174 2 : memcpy(data, netdev_features_strings,
175 : sizeof(netdev_features_strings));
176 0 : else if (stringset == ETH_SS_RSS_HASH_FUNCS)
177 0 : memcpy(data, rss_hash_func_strings,
178 : sizeof(rss_hash_func_strings));
179 0 : else if (stringset == ETH_SS_TUNABLES)
180 0 : memcpy(data, tunable_strings, sizeof(tunable_strings));
181 0 : else if (stringset == ETH_SS_PHY_TUNABLES)
182 0 : memcpy(data, phy_tunable_strings, sizeof(phy_tunable_strings));
183 0 : else if (stringset == ETH_SS_PHY_STATS && dev->phydev &&
184 0 : !ops->get_ethtool_phy_stats && phy_ops &&
185 0 : phy_ops->get_strings)
186 0 : phy_ops->get_strings(dev->phydev, data);
187 0 : else if (stringset == ETH_SS_LINK_MODES)
188 0 : memcpy(data, link_mode_names,
189 : __ETHTOOL_LINK_MODE_MASK_NBITS * ETH_GSTRING_LEN);
190 : else
191 : /* ops->get_strings is valid because checked earlier */
192 0 : ops->get_strings(dev, stringset, data);
193 2 : }
194 :
195 0 : static netdev_features_t ethtool_get_feature_mask(u32 eth_cmd)
196 : {
197 : /* feature masks of legacy discrete ethtool ops */
198 :
199 0 : switch (eth_cmd) {
200 : case ETHTOOL_GTXCSUM:
201 : case ETHTOOL_STXCSUM:
202 : return NETIF_F_CSUM_MASK | NETIF_F_FCOE_CRC |
203 : NETIF_F_SCTP_CRC;
204 0 : case ETHTOOL_GRXCSUM:
205 : case ETHTOOL_SRXCSUM:
206 0 : return NETIF_F_RXCSUM;
207 0 : case ETHTOOL_GSG:
208 : case ETHTOOL_SSG:
209 0 : return NETIF_F_SG | NETIF_F_FRAGLIST;
210 0 : case ETHTOOL_GTSO:
211 : case ETHTOOL_STSO:
212 0 : return NETIF_F_ALL_TSO;
213 0 : case ETHTOOL_GGSO:
214 : case ETHTOOL_SGSO:
215 0 : return NETIF_F_GSO;
216 0 : case ETHTOOL_GGRO:
217 : case ETHTOOL_SGRO:
218 0 : return NETIF_F_GRO;
219 0 : default:
220 0 : BUG();
221 : }
222 : }
223 :
224 0 : static int ethtool_get_one_feature(struct net_device *dev,
225 : char __user *useraddr, u32 ethcmd)
226 : {
227 0 : netdev_features_t mask = ethtool_get_feature_mask(ethcmd);
228 0 : struct ethtool_value edata = {
229 : .cmd = ethcmd,
230 0 : .data = !!(dev->features & mask),
231 : };
232 :
233 0 : if (copy_to_user(useraddr, &edata, sizeof(edata)))
234 0 : return -EFAULT;
235 : return 0;
236 : }
237 :
238 0 : static int ethtool_set_one_feature(struct net_device *dev,
239 : void __user *useraddr, u32 ethcmd)
240 : {
241 0 : struct ethtool_value edata;
242 0 : netdev_features_t mask;
243 :
244 0 : if (copy_from_user(&edata, useraddr, sizeof(edata)))
245 : return -EFAULT;
246 :
247 0 : mask = ethtool_get_feature_mask(ethcmd);
248 0 : mask &= dev->hw_features;
249 0 : if (!mask)
250 : return -EOPNOTSUPP;
251 :
252 0 : if (edata.data)
253 0 : dev->wanted_features |= mask;
254 : else
255 0 : dev->wanted_features &= ~mask;
256 :
257 0 : __netdev_update_features(dev);
258 :
259 0 : return 0;
260 : }
261 :
262 : #define ETH_ALL_FLAGS (ETH_FLAG_LRO | ETH_FLAG_RXVLAN | ETH_FLAG_TXVLAN | \
263 : ETH_FLAG_NTUPLE | ETH_FLAG_RXHASH)
264 : #define ETH_ALL_FEATURES (NETIF_F_LRO | NETIF_F_HW_VLAN_CTAG_RX | \
265 : NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_NTUPLE | \
266 : NETIF_F_RXHASH)
267 :
268 0 : static u32 __ethtool_get_flags(struct net_device *dev)
269 : {
270 0 : u32 flags = 0;
271 :
272 0 : if (dev->features & NETIF_F_LRO)
273 0 : flags |= ETH_FLAG_LRO;
274 0 : if (dev->features & NETIF_F_HW_VLAN_CTAG_RX)
275 0 : flags |= ETH_FLAG_RXVLAN;
276 0 : if (dev->features & NETIF_F_HW_VLAN_CTAG_TX)
277 0 : flags |= ETH_FLAG_TXVLAN;
278 0 : if (dev->features & NETIF_F_NTUPLE)
279 0 : flags |= ETH_FLAG_NTUPLE;
280 0 : if (dev->features & NETIF_F_RXHASH)
281 0 : flags |= ETH_FLAG_RXHASH;
282 :
283 0 : return flags;
284 : }
285 :
286 0 : static int __ethtool_set_flags(struct net_device *dev, u32 data)
287 : {
288 0 : netdev_features_t features = 0, changed;
289 :
290 0 : if (data & ~ETH_ALL_FLAGS)
291 : return -EINVAL;
292 :
293 0 : if (data & ETH_FLAG_LRO)
294 0 : features |= NETIF_F_LRO;
295 0 : if (data & ETH_FLAG_RXVLAN)
296 0 : features |= NETIF_F_HW_VLAN_CTAG_RX;
297 0 : if (data & ETH_FLAG_TXVLAN)
298 0 : features |= NETIF_F_HW_VLAN_CTAG_TX;
299 0 : if (data & ETH_FLAG_NTUPLE)
300 0 : features |= NETIF_F_NTUPLE;
301 0 : if (data & ETH_FLAG_RXHASH)
302 0 : features |= NETIF_F_RXHASH;
303 :
304 : /* allow changing only bits set in hw_features */
305 0 : changed = (features ^ dev->features) & ETH_ALL_FEATURES;
306 0 : if (changed & ~dev->hw_features)
307 0 : return (changed & dev->hw_features) ? -EINVAL : -EOPNOTSUPP;
308 :
309 0 : dev->wanted_features =
310 0 : (dev->wanted_features & ~changed) | (features & changed);
311 :
312 0 : __netdev_update_features(dev);
313 :
314 0 : return 0;
315 : }
316 :
317 : /* Given two link masks, AND them together and save the result in dst. */
318 0 : void ethtool_intersect_link_masks(struct ethtool_link_ksettings *dst,
319 : struct ethtool_link_ksettings *src)
320 : {
321 0 : unsigned int size = BITS_TO_LONGS(__ETHTOOL_LINK_MODE_MASK_NBITS);
322 0 : unsigned int idx = 0;
323 :
324 0 : for (; idx < size; idx++) {
325 0 : dst->link_modes.supported[idx] &=
326 0 : src->link_modes.supported[idx];
327 0 : dst->link_modes.advertising[idx] &=
328 0 : src->link_modes.advertising[idx];
329 : }
330 0 : }
331 : EXPORT_SYMBOL(ethtool_intersect_link_masks);
332 :
333 0 : void ethtool_convert_legacy_u32_to_link_mode(unsigned long *dst,
334 : u32 legacy_u32)
335 : {
336 0 : bitmap_zero(dst, __ETHTOOL_LINK_MODE_MASK_NBITS);
337 0 : dst[0] = legacy_u32;
338 0 : }
339 : EXPORT_SYMBOL(ethtool_convert_legacy_u32_to_link_mode);
340 :
341 : /* return false if src had higher bits set. lower bits always updated. */
342 0 : bool ethtool_convert_link_mode_to_legacy_u32(u32 *legacy_u32,
343 : const unsigned long *src)
344 : {
345 0 : bool retval = true;
346 :
347 : /* TODO: following test will soon always be true */
348 0 : if (__ETHTOOL_LINK_MODE_MASK_NBITS > 32) {
349 0 : __ETHTOOL_DECLARE_LINK_MODE_MASK(ext);
350 :
351 0 : bitmap_zero(ext, __ETHTOOL_LINK_MODE_MASK_NBITS);
352 0 : bitmap_fill(ext, 32);
353 0 : bitmap_complement(ext, ext, __ETHTOOL_LINK_MODE_MASK_NBITS);
354 0 : if (bitmap_intersects(ext, src,
355 : __ETHTOOL_LINK_MODE_MASK_NBITS)) {
356 : /* src mask goes beyond bit 31 */
357 0 : retval = false;
358 : }
359 : }
360 0 : *legacy_u32 = src[0];
361 0 : return retval;
362 : }
363 : EXPORT_SYMBOL(ethtool_convert_link_mode_to_legacy_u32);
364 :
365 : /* return false if ksettings link modes had higher bits
366 : * set. legacy_settings always updated (best effort)
367 : */
368 : static bool
369 0 : convert_link_ksettings_to_legacy_settings(
370 : struct ethtool_cmd *legacy_settings,
371 : const struct ethtool_link_ksettings *link_ksettings)
372 : {
373 0 : bool retval = true;
374 :
375 0 : memset(legacy_settings, 0, sizeof(*legacy_settings));
376 : /* this also clears the deprecated fields in legacy structure:
377 : * __u8 transceiver;
378 : * __u32 maxtxpkt;
379 : * __u32 maxrxpkt;
380 : */
381 :
382 0 : retval &= ethtool_convert_link_mode_to_legacy_u32(
383 0 : &legacy_settings->supported,
384 0 : link_ksettings->link_modes.supported);
385 0 : retval &= ethtool_convert_link_mode_to_legacy_u32(
386 0 : &legacy_settings->advertising,
387 0 : link_ksettings->link_modes.advertising);
388 0 : retval &= ethtool_convert_link_mode_to_legacy_u32(
389 0 : &legacy_settings->lp_advertising,
390 0 : link_ksettings->link_modes.lp_advertising);
391 0 : ethtool_cmd_speed_set(legacy_settings, link_ksettings->base.speed);
392 0 : legacy_settings->duplex
393 0 : = link_ksettings->base.duplex;
394 0 : legacy_settings->port
395 0 : = link_ksettings->base.port;
396 0 : legacy_settings->phy_address
397 0 : = link_ksettings->base.phy_address;
398 0 : legacy_settings->autoneg
399 0 : = link_ksettings->base.autoneg;
400 0 : legacy_settings->mdio_support
401 0 : = link_ksettings->base.mdio_support;
402 0 : legacy_settings->eth_tp_mdix
403 0 : = link_ksettings->base.eth_tp_mdix;
404 0 : legacy_settings->eth_tp_mdix_ctrl
405 0 : = link_ksettings->base.eth_tp_mdix_ctrl;
406 0 : legacy_settings->transceiver
407 0 : = link_ksettings->base.transceiver;
408 0 : return retval;
409 : }
410 :
411 : /* number of 32-bit words to store the user's link mode bitmaps */
412 : #define __ETHTOOL_LINK_MODE_MASK_NU32 \
413 : DIV_ROUND_UP(__ETHTOOL_LINK_MODE_MASK_NBITS, 32)
414 :
415 : /* layout of the struct passed from/to userland */
416 : struct ethtool_link_usettings {
417 : struct ethtool_link_settings base;
418 : struct {
419 : __u32 supported[__ETHTOOL_LINK_MODE_MASK_NU32];
420 : __u32 advertising[__ETHTOOL_LINK_MODE_MASK_NU32];
421 : __u32 lp_advertising[__ETHTOOL_LINK_MODE_MASK_NU32];
422 : } link_modes;
423 : };
424 :
425 : /* Internal kernel helper to query a device ethtool_link_settings. */
426 0 : int __ethtool_get_link_ksettings(struct net_device *dev,
427 : struct ethtool_link_ksettings *link_ksettings)
428 : {
429 0 : const struct link_mode_info *link_info;
430 0 : int err;
431 :
432 0 : ASSERT_RTNL();
433 :
434 0 : if (!dev->ethtool_ops->get_link_ksettings)
435 : return -EOPNOTSUPP;
436 :
437 0 : memset(link_ksettings, 0, sizeof(*link_ksettings));
438 :
439 0 : link_ksettings->link_mode = -1;
440 0 : err = dev->ethtool_ops->get_link_ksettings(dev, link_ksettings);
441 0 : if (err)
442 : return err;
443 :
444 0 : if (link_ksettings->link_mode != -1) {
445 0 : link_info = &link_mode_params[link_ksettings->link_mode];
446 0 : link_ksettings->base.speed = link_info->speed;
447 0 : link_ksettings->lanes = link_info->lanes;
448 0 : link_ksettings->base.duplex = link_info->duplex;
449 : }
450 :
451 : return 0;
452 : }
453 : EXPORT_SYMBOL(__ethtool_get_link_ksettings);
454 :
455 : /* convert ethtool_link_usettings in user space to a kernel internal
456 : * ethtool_link_ksettings. return 0 on success, errno on error.
457 : */
458 0 : static int load_link_ksettings_from_user(struct ethtool_link_ksettings *to,
459 : const void __user *from)
460 : {
461 0 : struct ethtool_link_usettings link_usettings;
462 :
463 0 : if (copy_from_user(&link_usettings, from, sizeof(link_usettings)))
464 : return -EFAULT;
465 :
466 0 : memcpy(&to->base, &link_usettings.base, sizeof(to->base));
467 0 : bitmap_from_arr32(to->link_modes.supported,
468 : link_usettings.link_modes.supported,
469 : __ETHTOOL_LINK_MODE_MASK_NBITS);
470 0 : bitmap_from_arr32(to->link_modes.advertising,
471 : link_usettings.link_modes.advertising,
472 : __ETHTOOL_LINK_MODE_MASK_NBITS);
473 0 : bitmap_from_arr32(to->link_modes.lp_advertising,
474 : link_usettings.link_modes.lp_advertising,
475 : __ETHTOOL_LINK_MODE_MASK_NBITS);
476 :
477 0 : return 0;
478 : }
479 :
480 : /* Check if the user is trying to change anything besides speed/duplex */
481 0 : bool ethtool_virtdev_validate_cmd(const struct ethtool_link_ksettings *cmd)
482 : {
483 0 : struct ethtool_link_settings base2 = {};
484 :
485 0 : base2.speed = cmd->base.speed;
486 0 : base2.port = PORT_OTHER;
487 0 : base2.duplex = cmd->base.duplex;
488 0 : base2.cmd = cmd->base.cmd;
489 0 : base2.link_mode_masks_nwords = cmd->base.link_mode_masks_nwords;
490 :
491 0 : return !memcmp(&base2, &cmd->base, sizeof(base2)) &&
492 0 : bitmap_empty(cmd->link_modes.supported,
493 0 : __ETHTOOL_LINK_MODE_MASK_NBITS) &&
494 0 : bitmap_empty(cmd->link_modes.lp_advertising,
495 : __ETHTOOL_LINK_MODE_MASK_NBITS);
496 : }
497 :
498 : /* convert a kernel internal ethtool_link_ksettings to
499 : * ethtool_link_usettings in user space. return 0 on success, errno on
500 : * error.
501 : */
502 : static int
503 0 : store_link_ksettings_for_user(void __user *to,
504 : const struct ethtool_link_ksettings *from)
505 : {
506 0 : struct ethtool_link_usettings link_usettings;
507 :
508 0 : memcpy(&link_usettings.base, &from->base, sizeof(link_usettings));
509 0 : bitmap_to_arr32(link_usettings.link_modes.supported,
510 0 : from->link_modes.supported,
511 : __ETHTOOL_LINK_MODE_MASK_NBITS);
512 0 : bitmap_to_arr32(link_usettings.link_modes.advertising,
513 0 : from->link_modes.advertising,
514 : __ETHTOOL_LINK_MODE_MASK_NBITS);
515 0 : bitmap_to_arr32(link_usettings.link_modes.lp_advertising,
516 0 : from->link_modes.lp_advertising,
517 : __ETHTOOL_LINK_MODE_MASK_NBITS);
518 :
519 0 : if (copy_to_user(to, &link_usettings, sizeof(link_usettings)))
520 0 : return -EFAULT;
521 :
522 : return 0;
523 : }
524 :
525 : /* Query device for its ethtool_link_settings. */
526 0 : static int ethtool_get_link_ksettings(struct net_device *dev,
527 : void __user *useraddr)
528 : {
529 0 : int err = 0;
530 0 : struct ethtool_link_ksettings link_ksettings;
531 :
532 0 : ASSERT_RTNL();
533 0 : if (!dev->ethtool_ops->get_link_ksettings)
534 : return -EOPNOTSUPP;
535 :
536 : /* handle bitmap nbits handshake */
537 0 : if (copy_from_user(&link_ksettings.base, useraddr,
538 : sizeof(link_ksettings.base)))
539 : return -EFAULT;
540 :
541 0 : if (__ETHTOOL_LINK_MODE_MASK_NU32
542 0 : != link_ksettings.base.link_mode_masks_nwords) {
543 : /* wrong link mode nbits requested */
544 0 : memset(&link_ksettings, 0, sizeof(link_ksettings));
545 0 : link_ksettings.base.cmd = ETHTOOL_GLINKSETTINGS;
546 : /* send back number of words required as negative val */
547 0 : compiletime_assert(__ETHTOOL_LINK_MODE_MASK_NU32 <= S8_MAX,
548 : "need too many bits for link modes!");
549 0 : link_ksettings.base.link_mode_masks_nwords
550 0 : = -((s8)__ETHTOOL_LINK_MODE_MASK_NU32);
551 :
552 : /* copy the base fields back to user, not the link
553 : * mode bitmaps
554 : */
555 0 : if (copy_to_user(useraddr, &link_ksettings.base,
556 : sizeof(link_ksettings.base)))
557 : return -EFAULT;
558 :
559 0 : return 0;
560 : }
561 :
562 : /* handshake successful: user/kernel agree on
563 : * link_mode_masks_nwords
564 : */
565 :
566 0 : memset(&link_ksettings, 0, sizeof(link_ksettings));
567 0 : err = dev->ethtool_ops->get_link_ksettings(dev, &link_ksettings);
568 0 : if (err < 0)
569 : return err;
570 :
571 : /* make sure we tell the right values to user */
572 0 : link_ksettings.base.cmd = ETHTOOL_GLINKSETTINGS;
573 0 : link_ksettings.base.link_mode_masks_nwords
574 0 : = __ETHTOOL_LINK_MODE_MASK_NU32;
575 0 : link_ksettings.base.master_slave_cfg = MASTER_SLAVE_CFG_UNSUPPORTED;
576 0 : link_ksettings.base.master_slave_state = MASTER_SLAVE_STATE_UNSUPPORTED;
577 :
578 0 : return store_link_ksettings_for_user(useraddr, &link_ksettings);
579 : }
580 :
581 : /* Update device ethtool_link_settings. */
582 0 : static int ethtool_set_link_ksettings(struct net_device *dev,
583 : void __user *useraddr)
584 : {
585 0 : int err;
586 0 : struct ethtool_link_ksettings link_ksettings;
587 :
588 0 : ASSERT_RTNL();
589 :
590 0 : if (!dev->ethtool_ops->set_link_ksettings)
591 : return -EOPNOTSUPP;
592 :
593 : /* make sure nbits field has expected value */
594 0 : if (copy_from_user(&link_ksettings.base, useraddr,
595 : sizeof(link_ksettings.base)))
596 : return -EFAULT;
597 :
598 0 : if (__ETHTOOL_LINK_MODE_MASK_NU32
599 0 : != link_ksettings.base.link_mode_masks_nwords)
600 : return -EINVAL;
601 :
602 : /* copy the whole structure, now that we know it has expected
603 : * format
604 : */
605 0 : err = load_link_ksettings_from_user(&link_ksettings, useraddr);
606 0 : if (err)
607 : return err;
608 :
609 : /* re-check nwords field, just in case */
610 0 : if (__ETHTOOL_LINK_MODE_MASK_NU32
611 0 : != link_ksettings.base.link_mode_masks_nwords)
612 : return -EINVAL;
613 :
614 0 : if (link_ksettings.base.master_slave_cfg ||
615 : link_ksettings.base.master_slave_state)
616 : return -EINVAL;
617 :
618 0 : err = dev->ethtool_ops->set_link_ksettings(dev, &link_ksettings);
619 0 : if (err >= 0) {
620 0 : ethtool_notify(dev, ETHTOOL_MSG_LINKINFO_NTF, NULL);
621 0 : ethtool_notify(dev, ETHTOOL_MSG_LINKMODES_NTF, NULL);
622 : }
623 0 : return err;
624 : }
625 :
626 0 : int ethtool_virtdev_set_link_ksettings(struct net_device *dev,
627 : const struct ethtool_link_ksettings *cmd,
628 : u32 *dev_speed, u8 *dev_duplex)
629 : {
630 0 : u32 speed;
631 0 : u8 duplex;
632 :
633 0 : speed = cmd->base.speed;
634 0 : duplex = cmd->base.duplex;
635 : /* don't allow custom speed and duplex */
636 0 : if (!ethtool_validate_speed(speed) ||
637 0 : !ethtool_validate_duplex(duplex) ||
638 0 : !ethtool_virtdev_validate_cmd(cmd))
639 0 : return -EINVAL;
640 0 : *dev_speed = speed;
641 0 : *dev_duplex = duplex;
642 :
643 0 : return 0;
644 : }
645 : EXPORT_SYMBOL(ethtool_virtdev_set_link_ksettings);
646 :
647 : /* Query device for its ethtool_cmd settings.
648 : *
649 : * Backward compatibility note: for compatibility with legacy ethtool, this is
650 : * now implemented via get_link_ksettings. When driver reports higher link mode
651 : * bits, a kernel warning is logged once (with name of 1st driver/device) to
652 : * recommend user to upgrade ethtool, but the command is successful (only the
653 : * lower link mode bits reported back to user). Deprecated fields from
654 : * ethtool_cmd (transceiver/maxrxpkt/maxtxpkt) are always set to zero.
655 : */
656 0 : static int ethtool_get_settings(struct net_device *dev, void __user *useraddr)
657 : {
658 0 : struct ethtool_link_ksettings link_ksettings;
659 0 : struct ethtool_cmd cmd;
660 0 : int err;
661 :
662 0 : ASSERT_RTNL();
663 0 : if (!dev->ethtool_ops->get_link_ksettings)
664 : return -EOPNOTSUPP;
665 :
666 0 : memset(&link_ksettings, 0, sizeof(link_ksettings));
667 0 : err = dev->ethtool_ops->get_link_ksettings(dev, &link_ksettings);
668 0 : if (err < 0)
669 : return err;
670 0 : convert_link_ksettings_to_legacy_settings(&cmd, &link_ksettings);
671 :
672 : /* send a sensible cmd tag back to user */
673 0 : cmd.cmd = ETHTOOL_GSET;
674 :
675 0 : if (copy_to_user(useraddr, &cmd, sizeof(cmd)))
676 0 : return -EFAULT;
677 :
678 : return 0;
679 : }
680 :
681 : /* Update device link settings with given ethtool_cmd.
682 : *
683 : * Backward compatibility note: for compatibility with legacy ethtool, this is
684 : * now always implemented via set_link_settings. When user's request updates
685 : * deprecated ethtool_cmd fields (transceiver/maxrxpkt/maxtxpkt), a kernel
686 : * warning is logged once (with name of 1st driver/device) to recommend user to
687 : * upgrade ethtool, and the request is rejected.
688 : */
689 0 : static int ethtool_set_settings(struct net_device *dev, void __user *useraddr)
690 : {
691 0 : struct ethtool_link_ksettings link_ksettings;
692 0 : struct ethtool_cmd cmd;
693 0 : int ret;
694 :
695 0 : ASSERT_RTNL();
696 :
697 0 : if (copy_from_user(&cmd, useraddr, sizeof(cmd)))
698 : return -EFAULT;
699 0 : if (!dev->ethtool_ops->set_link_ksettings)
700 : return -EOPNOTSUPP;
701 :
702 0 : if (!convert_legacy_settings_to_link_ksettings(&link_ksettings, &cmd))
703 : return -EINVAL;
704 0 : link_ksettings.base.link_mode_masks_nwords =
705 : __ETHTOOL_LINK_MODE_MASK_NU32;
706 0 : ret = dev->ethtool_ops->set_link_ksettings(dev, &link_ksettings);
707 0 : if (ret >= 0) {
708 0 : ethtool_notify(dev, ETHTOOL_MSG_LINKINFO_NTF, NULL);
709 0 : ethtool_notify(dev, ETHTOOL_MSG_LINKMODES_NTF, NULL);
710 : }
711 0 : return ret;
712 : }
713 :
714 2 : static noinline_for_stack int ethtool_get_drvinfo(struct net_device *dev,
715 : void __user *useraddr)
716 : {
717 2 : struct ethtool_drvinfo info;
718 2 : const struct ethtool_ops *ops = dev->ethtool_ops;
719 :
720 2 : memset(&info, 0, sizeof(info));
721 2 : info.cmd = ETHTOOL_GDRVINFO;
722 2 : strlcpy(info.version, UTS_RELEASE, sizeof(info.version));
723 2 : if (ops->get_drvinfo) {
724 1 : ops->get_drvinfo(dev, &info);
725 1 : } else if (dev->dev.parent && dev->dev.parent->driver) {
726 0 : strlcpy(info.bus_info, dev_name(dev->dev.parent),
727 : sizeof(info.bus_info));
728 0 : strlcpy(info.driver, dev->dev.parent->driver->name,
729 : sizeof(info.driver));
730 : } else {
731 : return -EOPNOTSUPP;
732 : }
733 :
734 : /*
735 : * this method of obtaining string set info is deprecated;
736 : * Use ETHTOOL_GSSET_INFO instead.
737 : */
738 1 : if (ops->get_sset_count) {
739 1 : int rc;
740 :
741 1 : rc = ops->get_sset_count(dev, ETH_SS_TEST);
742 1 : if (rc >= 0)
743 0 : info.testinfo_len = rc;
744 1 : rc = ops->get_sset_count(dev, ETH_SS_STATS);
745 1 : if (rc >= 0)
746 1 : info.n_stats = rc;
747 1 : rc = ops->get_sset_count(dev, ETH_SS_PRIV_FLAGS);
748 1 : if (rc >= 0)
749 0 : info.n_priv_flags = rc;
750 : }
751 1 : if (ops->get_regs_len) {
752 0 : int ret = ops->get_regs_len(dev);
753 :
754 0 : if (ret > 0)
755 0 : info.regdump_len = ret;
756 : }
757 :
758 1 : if (ops->get_eeprom_len)
759 0 : info.eedump_len = ops->get_eeprom_len(dev);
760 :
761 1 : if (!info.fw_version[0])
762 1 : devlink_compat_running_version(dev, info.fw_version,
763 : sizeof(info.fw_version));
764 :
765 1 : if (copy_to_user(useraddr, &info, sizeof(info)))
766 0 : return -EFAULT;
767 : return 0;
768 : }
769 :
770 2 : static noinline_for_stack int ethtool_get_sset_info(struct net_device *dev,
771 : void __user *useraddr)
772 : {
773 2 : struct ethtool_sset_info info;
774 2 : u64 sset_mask;
775 2 : int i, idx = 0, n_bits = 0, ret, rc;
776 2 : u32 *info_buf = NULL;
777 :
778 2 : if (copy_from_user(&info, useraddr, sizeof(info)))
779 : return -EFAULT;
780 :
781 : /* store copy of mask, because we zero struct later on */
782 2 : sset_mask = info.sset_mask;
783 2 : if (!sset_mask)
784 : return 0;
785 :
786 : /* calculate size of return buffer */
787 2 : n_bits = hweight64(sset_mask);
788 :
789 2 : memset(&info, 0, sizeof(info));
790 2 : info.cmd = ETHTOOL_GSSET_INFO;
791 :
792 2 : info_buf = kcalloc(n_bits, sizeof(u32), GFP_USER);
793 2 : if (!info_buf)
794 : return -ENOMEM;
795 :
796 : /*
797 : * fill return buffer based on input bitmask and successful
798 : * get_sset_count return
799 : */
800 130 : for (i = 0; i < 64; i++) {
801 128 : if (!(sset_mask & (1ULL << i)))
802 126 : continue;
803 :
804 2 : rc = __ethtool_get_sset_count(dev, i);
805 2 : if (rc >= 0) {
806 2 : info.sset_mask |= (1ULL << i);
807 2 : info_buf[idx++] = rc;
808 : }
809 : }
810 :
811 2 : ret = -EFAULT;
812 2 : if (copy_to_user(useraddr, &info, sizeof(info)))
813 0 : goto out;
814 :
815 2 : useraddr += offsetof(struct ethtool_sset_info, data);
816 4 : if (copy_to_user(useraddr, info_buf, idx * sizeof(u32)))
817 0 : goto out;
818 :
819 : ret = 0;
820 :
821 2 : out:
822 2 : kfree(info_buf);
823 2 : return ret;
824 : }
825 :
826 0 : static noinline_for_stack int ethtool_set_rxnfc(struct net_device *dev,
827 : u32 cmd, void __user *useraddr)
828 : {
829 0 : struct ethtool_rxnfc info;
830 0 : size_t info_size = sizeof(info);
831 0 : int rc;
832 :
833 0 : if (!dev->ethtool_ops->set_rxnfc)
834 : return -EOPNOTSUPP;
835 :
836 : /* struct ethtool_rxnfc was originally defined for
837 : * ETHTOOL_{G,S}RXFH with only the cmd, flow_type and data
838 : * members. User-space might still be using that
839 : * definition. */
840 0 : if (cmd == ETHTOOL_SRXFH)
841 0 : info_size = (offsetof(struct ethtool_rxnfc, data) +
842 : sizeof(info.data));
843 :
844 0 : if (copy_from_user(&info, useraddr, info_size))
845 : return -EFAULT;
846 :
847 0 : rc = dev->ethtool_ops->set_rxnfc(dev, &info);
848 0 : if (rc)
849 : return rc;
850 :
851 0 : if (cmd == ETHTOOL_SRXCLSRLINS &&
852 0 : copy_to_user(useraddr, &info, info_size))
853 0 : return -EFAULT;
854 :
855 : return 0;
856 : }
857 :
858 0 : static noinline_for_stack int ethtool_get_rxnfc(struct net_device *dev,
859 : u32 cmd, void __user *useraddr)
860 : {
861 0 : struct ethtool_rxnfc info;
862 0 : size_t info_size = sizeof(info);
863 0 : const struct ethtool_ops *ops = dev->ethtool_ops;
864 0 : int ret;
865 0 : void *rule_buf = NULL;
866 :
867 0 : if (!ops->get_rxnfc)
868 : return -EOPNOTSUPP;
869 :
870 : /* struct ethtool_rxnfc was originally defined for
871 : * ETHTOOL_{G,S}RXFH with only the cmd, flow_type and data
872 : * members. User-space might still be using that
873 : * definition. */
874 0 : if (cmd == ETHTOOL_GRXFH)
875 0 : info_size = (offsetof(struct ethtool_rxnfc, data) +
876 : sizeof(info.data));
877 :
878 0 : if (copy_from_user(&info, useraddr, info_size))
879 : return -EFAULT;
880 :
881 : /* If FLOW_RSS was requested then user-space must be using the
882 : * new definition, as FLOW_RSS is newer.
883 : */
884 0 : if (cmd == ETHTOOL_GRXFH && info.flow_type & FLOW_RSS) {
885 0 : info_size = sizeof(info);
886 0 : if (copy_from_user(&info, useraddr, info_size))
887 : return -EFAULT;
888 : /* Since malicious users may modify the original data,
889 : * we need to check whether FLOW_RSS is still requested.
890 : */
891 0 : if (!(info.flow_type & FLOW_RSS))
892 : return -EINVAL;
893 : }
894 :
895 0 : if (info.cmd != cmd)
896 : return -EINVAL;
897 :
898 0 : if (info.cmd == ETHTOOL_GRXCLSRLALL) {
899 0 : if (info.rule_cnt > 0) {
900 0 : if (info.rule_cnt <= KMALLOC_MAX_SIZE / sizeof(u32))
901 0 : rule_buf = kcalloc(info.rule_cnt, sizeof(u32),
902 : GFP_USER);
903 0 : if (!rule_buf)
904 0 : return -ENOMEM;
905 : }
906 : }
907 :
908 0 : ret = ops->get_rxnfc(dev, &info, rule_buf);
909 0 : if (ret < 0)
910 0 : goto err_out;
911 :
912 0 : ret = -EFAULT;
913 0 : if (copy_to_user(useraddr, &info, info_size))
914 0 : goto err_out;
915 :
916 0 : if (rule_buf) {
917 0 : useraddr += offsetof(struct ethtool_rxnfc, rule_locs);
918 0 : if (copy_to_user(useraddr, rule_buf,
919 0 : info.rule_cnt * sizeof(u32)))
920 0 : goto err_out;
921 : }
922 : ret = 0;
923 :
924 0 : err_out:
925 0 : kfree(rule_buf);
926 :
927 0 : return ret;
928 : }
929 :
930 0 : static int ethtool_copy_validate_indir(u32 *indir, void __user *useraddr,
931 : struct ethtool_rxnfc *rx_rings,
932 : u32 size)
933 : {
934 0 : int i;
935 :
936 0 : if (copy_from_user(indir, useraddr, size * sizeof(indir[0])))
937 : return -EFAULT;
938 :
939 : /* Validate ring indices */
940 0 : for (i = 0; i < size; i++)
941 0 : if (indir[i] >= rx_rings->data)
942 : return -EINVAL;
943 :
944 : return 0;
945 : }
946 :
947 : u8 netdev_rss_key[NETDEV_RSS_KEY_LEN] __read_mostly;
948 :
949 0 : void netdev_rss_key_fill(void *buffer, size_t len)
950 : {
951 0 : BUG_ON(len > sizeof(netdev_rss_key));
952 0 : net_get_random_once(netdev_rss_key, sizeof(netdev_rss_key));
953 0 : memcpy(buffer, netdev_rss_key, len);
954 0 : }
955 : EXPORT_SYMBOL(netdev_rss_key_fill);
956 :
957 0 : static noinline_for_stack int ethtool_get_rxfh_indir(struct net_device *dev,
958 : void __user *useraddr)
959 : {
960 0 : u32 user_size, dev_size;
961 0 : u32 *indir;
962 0 : int ret;
963 :
964 0 : if (!dev->ethtool_ops->get_rxfh_indir_size ||
965 0 : !dev->ethtool_ops->get_rxfh)
966 : return -EOPNOTSUPP;
967 0 : dev_size = dev->ethtool_ops->get_rxfh_indir_size(dev);
968 0 : if (dev_size == 0)
969 : return -EOPNOTSUPP;
970 :
971 0 : if (copy_from_user(&user_size,
972 0 : useraddr + offsetof(struct ethtool_rxfh_indir, size),
973 : sizeof(user_size)))
974 : return -EFAULT;
975 :
976 0 : if (copy_to_user(useraddr + offsetof(struct ethtool_rxfh_indir, size),
977 : &dev_size, sizeof(dev_size)))
978 : return -EFAULT;
979 :
980 : /* If the user buffer size is 0, this is just a query for the
981 : * device table size. Otherwise, if it's smaller than the
982 : * device table size it's an error.
983 : */
984 0 : if (user_size < dev_size)
985 0 : return user_size == 0 ? 0 : -EINVAL;
986 :
987 0 : indir = kcalloc(dev_size, sizeof(indir[0]), GFP_USER);
988 0 : if (!indir)
989 : return -ENOMEM;
990 :
991 0 : ret = dev->ethtool_ops->get_rxfh(dev, indir, NULL, NULL);
992 0 : if (ret)
993 0 : goto out;
994 :
995 0 : if (copy_to_user(useraddr +
996 : offsetof(struct ethtool_rxfh_indir, ring_index[0]),
997 : indir, dev_size * sizeof(indir[0])))
998 0 : ret = -EFAULT;
999 :
1000 0 : out:
1001 0 : kfree(indir);
1002 0 : return ret;
1003 : }
1004 :
1005 0 : static noinline_for_stack int ethtool_set_rxfh_indir(struct net_device *dev,
1006 : void __user *useraddr)
1007 : {
1008 0 : struct ethtool_rxnfc rx_rings;
1009 0 : u32 user_size, dev_size, i;
1010 0 : u32 *indir;
1011 0 : const struct ethtool_ops *ops = dev->ethtool_ops;
1012 0 : int ret;
1013 0 : u32 ringidx_offset = offsetof(struct ethtool_rxfh_indir, ring_index[0]);
1014 :
1015 0 : if (!ops->get_rxfh_indir_size || !ops->set_rxfh ||
1016 0 : !ops->get_rxnfc)
1017 : return -EOPNOTSUPP;
1018 :
1019 0 : dev_size = ops->get_rxfh_indir_size(dev);
1020 0 : if (dev_size == 0)
1021 : return -EOPNOTSUPP;
1022 :
1023 0 : if (copy_from_user(&user_size,
1024 0 : useraddr + offsetof(struct ethtool_rxfh_indir, size),
1025 : sizeof(user_size)))
1026 : return -EFAULT;
1027 :
1028 0 : if (user_size != 0 && user_size != dev_size)
1029 : return -EINVAL;
1030 :
1031 0 : indir = kcalloc(dev_size, sizeof(indir[0]), GFP_USER);
1032 0 : if (!indir)
1033 : return -ENOMEM;
1034 :
1035 0 : rx_rings.cmd = ETHTOOL_GRXRINGS;
1036 0 : ret = ops->get_rxnfc(dev, &rx_rings, NULL);
1037 0 : if (ret)
1038 0 : goto out;
1039 :
1040 0 : if (user_size == 0) {
1041 0 : for (i = 0; i < dev_size; i++)
1042 0 : indir[i] = ethtool_rxfh_indir_default(i, rx_rings.data);
1043 : } else {
1044 0 : ret = ethtool_copy_validate_indir(indir,
1045 : useraddr + ringidx_offset,
1046 : &rx_rings,
1047 : dev_size);
1048 0 : if (ret)
1049 0 : goto out;
1050 : }
1051 :
1052 0 : ret = ops->set_rxfh(dev, indir, NULL, ETH_RSS_HASH_NO_CHANGE);
1053 0 : if (ret)
1054 0 : goto out;
1055 :
1056 : /* indicate whether rxfh was set to default */
1057 0 : if (user_size == 0)
1058 0 : dev->priv_flags &= ~IFF_RXFH_CONFIGURED;
1059 : else
1060 0 : dev->priv_flags |= IFF_RXFH_CONFIGURED;
1061 :
1062 0 : out:
1063 0 : kfree(indir);
1064 0 : return ret;
1065 : }
1066 :
1067 0 : static noinline_for_stack int ethtool_get_rxfh(struct net_device *dev,
1068 : void __user *useraddr)
1069 : {
1070 0 : int ret;
1071 0 : const struct ethtool_ops *ops = dev->ethtool_ops;
1072 0 : u32 user_indir_size, user_key_size;
1073 0 : u32 dev_indir_size = 0, dev_key_size = 0;
1074 0 : struct ethtool_rxfh rxfh;
1075 0 : u32 total_size;
1076 0 : u32 indir_bytes;
1077 0 : u32 *indir = NULL;
1078 0 : u8 dev_hfunc = 0;
1079 0 : u8 *hkey = NULL;
1080 0 : u8 *rss_config;
1081 :
1082 0 : if (!ops->get_rxfh)
1083 : return -EOPNOTSUPP;
1084 :
1085 0 : if (ops->get_rxfh_indir_size)
1086 0 : dev_indir_size = ops->get_rxfh_indir_size(dev);
1087 0 : if (ops->get_rxfh_key_size)
1088 0 : dev_key_size = ops->get_rxfh_key_size(dev);
1089 :
1090 0 : if (copy_from_user(&rxfh, useraddr, sizeof(rxfh)))
1091 : return -EFAULT;
1092 0 : user_indir_size = rxfh.indir_size;
1093 0 : user_key_size = rxfh.key_size;
1094 :
1095 : /* Check that reserved fields are 0 for now */
1096 0 : if (rxfh.rsvd8[0] || rxfh.rsvd8[1] || rxfh.rsvd8[2] || rxfh.rsvd32)
1097 : return -EINVAL;
1098 : /* Most drivers don't handle rss_context, check it's 0 as well */
1099 0 : if (rxfh.rss_context && !ops->get_rxfh_context)
1100 : return -EOPNOTSUPP;
1101 :
1102 0 : rxfh.indir_size = dev_indir_size;
1103 0 : rxfh.key_size = dev_key_size;
1104 0 : if (copy_to_user(useraddr, &rxfh, sizeof(rxfh)))
1105 : return -EFAULT;
1106 :
1107 0 : if ((user_indir_size && (user_indir_size != dev_indir_size)) ||
1108 0 : (user_key_size && (user_key_size != dev_key_size)))
1109 : return -EINVAL;
1110 :
1111 0 : indir_bytes = user_indir_size * sizeof(indir[0]);
1112 0 : total_size = indir_bytes + user_key_size;
1113 0 : rss_config = kzalloc(total_size, GFP_USER);
1114 0 : if (!rss_config)
1115 : return -ENOMEM;
1116 :
1117 0 : if (user_indir_size)
1118 0 : indir = (u32 *)rss_config;
1119 :
1120 0 : if (user_key_size)
1121 0 : hkey = rss_config + indir_bytes;
1122 :
1123 0 : if (rxfh.rss_context)
1124 0 : ret = dev->ethtool_ops->get_rxfh_context(dev, indir, hkey,
1125 : &dev_hfunc,
1126 : rxfh.rss_context);
1127 : else
1128 0 : ret = dev->ethtool_ops->get_rxfh(dev, indir, hkey, &dev_hfunc);
1129 0 : if (ret)
1130 0 : goto out;
1131 :
1132 0 : if (copy_to_user(useraddr + offsetof(struct ethtool_rxfh, hfunc),
1133 : &dev_hfunc, sizeof(rxfh.hfunc))) {
1134 : ret = -EFAULT;
1135 0 : } else if (copy_to_user(useraddr +
1136 : offsetof(struct ethtool_rxfh, rss_config[0]),
1137 : rss_config, total_size)) {
1138 0 : ret = -EFAULT;
1139 : }
1140 0 : out:
1141 0 : kfree(rss_config);
1142 :
1143 0 : return ret;
1144 : }
1145 :
1146 0 : static noinline_for_stack int ethtool_set_rxfh(struct net_device *dev,
1147 : void __user *useraddr)
1148 : {
1149 0 : int ret;
1150 0 : const struct ethtool_ops *ops = dev->ethtool_ops;
1151 0 : struct ethtool_rxnfc rx_rings;
1152 0 : struct ethtool_rxfh rxfh;
1153 0 : u32 dev_indir_size = 0, dev_key_size = 0, i;
1154 0 : u32 *indir = NULL, indir_bytes = 0;
1155 0 : u8 *hkey = NULL;
1156 0 : u8 *rss_config;
1157 0 : u32 rss_cfg_offset = offsetof(struct ethtool_rxfh, rss_config[0]);
1158 0 : bool delete = false;
1159 :
1160 0 : if (!ops->get_rxnfc || !ops->set_rxfh)
1161 : return -EOPNOTSUPP;
1162 :
1163 0 : if (ops->get_rxfh_indir_size)
1164 0 : dev_indir_size = ops->get_rxfh_indir_size(dev);
1165 0 : if (ops->get_rxfh_key_size)
1166 0 : dev_key_size = ops->get_rxfh_key_size(dev);
1167 :
1168 0 : if (copy_from_user(&rxfh, useraddr, sizeof(rxfh)))
1169 : return -EFAULT;
1170 :
1171 : /* Check that reserved fields are 0 for now */
1172 0 : if (rxfh.rsvd8[0] || rxfh.rsvd8[1] || rxfh.rsvd8[2] || rxfh.rsvd32)
1173 : return -EINVAL;
1174 : /* Most drivers don't handle rss_context, check it's 0 as well */
1175 0 : if (rxfh.rss_context && !ops->set_rxfh_context)
1176 : return -EOPNOTSUPP;
1177 :
1178 : /* If either indir, hash key or function is valid, proceed further.
1179 : * Must request at least one change: indir size, hash key or function.
1180 : */
1181 0 : if ((rxfh.indir_size &&
1182 0 : rxfh.indir_size != ETH_RXFH_INDIR_NO_CHANGE &&
1183 0 : rxfh.indir_size != dev_indir_size) ||
1184 0 : (rxfh.key_size && (rxfh.key_size != dev_key_size)) ||
1185 0 : (rxfh.indir_size == ETH_RXFH_INDIR_NO_CHANGE &&
1186 0 : rxfh.key_size == 0 && rxfh.hfunc == ETH_RSS_HASH_NO_CHANGE))
1187 : return -EINVAL;
1188 :
1189 0 : if (rxfh.indir_size != ETH_RXFH_INDIR_NO_CHANGE)
1190 0 : indir_bytes = dev_indir_size * sizeof(indir[0]);
1191 :
1192 0 : rss_config = kzalloc(indir_bytes + rxfh.key_size, GFP_USER);
1193 0 : if (!rss_config)
1194 : return -ENOMEM;
1195 :
1196 0 : rx_rings.cmd = ETHTOOL_GRXRINGS;
1197 0 : ret = ops->get_rxnfc(dev, &rx_rings, NULL);
1198 0 : if (ret)
1199 0 : goto out;
1200 :
1201 : /* rxfh.indir_size == 0 means reset the indir table to default (master
1202 : * context) or delete the context (other RSS contexts).
1203 : * rxfh.indir_size == ETH_RXFH_INDIR_NO_CHANGE means leave it unchanged.
1204 : */
1205 0 : if (rxfh.indir_size &&
1206 : rxfh.indir_size != ETH_RXFH_INDIR_NO_CHANGE) {
1207 0 : indir = (u32 *)rss_config;
1208 0 : ret = ethtool_copy_validate_indir(indir,
1209 : useraddr + rss_cfg_offset,
1210 : &rx_rings,
1211 : rxfh.indir_size);
1212 0 : if (ret)
1213 0 : goto out;
1214 0 : } else if (rxfh.indir_size == 0) {
1215 0 : if (rxfh.rss_context == 0) {
1216 0 : indir = (u32 *)rss_config;
1217 0 : for (i = 0; i < dev_indir_size; i++)
1218 0 : indir[i] = ethtool_rxfh_indir_default(i, rx_rings.data);
1219 : } else {
1220 : delete = true;
1221 : }
1222 : }
1223 :
1224 0 : if (rxfh.key_size) {
1225 0 : hkey = rss_config + indir_bytes;
1226 0 : if (copy_from_user(hkey,
1227 0 : useraddr + rss_cfg_offset + indir_bytes,
1228 : rxfh.key_size)) {
1229 0 : ret = -EFAULT;
1230 0 : goto out;
1231 : }
1232 : }
1233 :
1234 0 : if (rxfh.rss_context)
1235 0 : ret = ops->set_rxfh_context(dev, indir, hkey, rxfh.hfunc,
1236 : &rxfh.rss_context, delete);
1237 : else
1238 0 : ret = ops->set_rxfh(dev, indir, hkey, rxfh.hfunc);
1239 0 : if (ret)
1240 0 : goto out;
1241 :
1242 0 : if (copy_to_user(useraddr + offsetof(struct ethtool_rxfh, rss_context),
1243 : &rxfh.rss_context, sizeof(rxfh.rss_context)))
1244 0 : ret = -EFAULT;
1245 :
1246 0 : if (!rxfh.rss_context) {
1247 : /* indicate whether rxfh was set to default */
1248 0 : if (rxfh.indir_size == 0)
1249 0 : dev->priv_flags &= ~IFF_RXFH_CONFIGURED;
1250 0 : else if (rxfh.indir_size != ETH_RXFH_INDIR_NO_CHANGE)
1251 0 : dev->priv_flags |= IFF_RXFH_CONFIGURED;
1252 : }
1253 :
1254 0 : out:
1255 0 : kfree(rss_config);
1256 0 : return ret;
1257 : }
1258 :
1259 0 : static int ethtool_get_regs(struct net_device *dev, char __user *useraddr)
1260 : {
1261 0 : struct ethtool_regs regs;
1262 0 : const struct ethtool_ops *ops = dev->ethtool_ops;
1263 0 : void *regbuf;
1264 0 : int reglen, ret;
1265 :
1266 0 : if (!ops->get_regs || !ops->get_regs_len)
1267 : return -EOPNOTSUPP;
1268 :
1269 0 : if (copy_from_user(®s, useraddr, sizeof(regs)))
1270 : return -EFAULT;
1271 :
1272 0 : reglen = ops->get_regs_len(dev);
1273 0 : if (reglen <= 0)
1274 : return reglen;
1275 :
1276 0 : if (regs.len > reglen)
1277 0 : regs.len = reglen;
1278 :
1279 0 : regbuf = vzalloc(reglen);
1280 0 : if (!regbuf)
1281 : return -ENOMEM;
1282 :
1283 0 : if (regs.len < reglen)
1284 0 : reglen = regs.len;
1285 :
1286 0 : ops->get_regs(dev, ®s, regbuf);
1287 :
1288 0 : ret = -EFAULT;
1289 0 : if (copy_to_user(useraddr, ®s, sizeof(regs)))
1290 0 : goto out;
1291 0 : useraddr += offsetof(struct ethtool_regs, data);
1292 0 : if (copy_to_user(useraddr, regbuf, reglen))
1293 0 : goto out;
1294 : ret = 0;
1295 :
1296 0 : out:
1297 0 : vfree(regbuf);
1298 0 : return ret;
1299 : }
1300 :
1301 0 : static int ethtool_reset(struct net_device *dev, char __user *useraddr)
1302 : {
1303 0 : struct ethtool_value reset;
1304 0 : int ret;
1305 :
1306 0 : if (!dev->ethtool_ops->reset)
1307 : return -EOPNOTSUPP;
1308 :
1309 0 : if (copy_from_user(&reset, useraddr, sizeof(reset)))
1310 : return -EFAULT;
1311 :
1312 0 : ret = dev->ethtool_ops->reset(dev, &reset.data);
1313 0 : if (ret)
1314 : return ret;
1315 :
1316 0 : if (copy_to_user(useraddr, &reset, sizeof(reset)))
1317 0 : return -EFAULT;
1318 : return 0;
1319 : }
1320 :
1321 0 : static int ethtool_get_wol(struct net_device *dev, char __user *useraddr)
1322 : {
1323 0 : struct ethtool_wolinfo wol;
1324 :
1325 0 : if (!dev->ethtool_ops->get_wol)
1326 : return -EOPNOTSUPP;
1327 :
1328 0 : memset(&wol, 0, sizeof(struct ethtool_wolinfo));
1329 0 : wol.cmd = ETHTOOL_GWOL;
1330 0 : dev->ethtool_ops->get_wol(dev, &wol);
1331 :
1332 0 : if (copy_to_user(useraddr, &wol, sizeof(wol)))
1333 0 : return -EFAULT;
1334 : return 0;
1335 : }
1336 :
1337 0 : static int ethtool_set_wol(struct net_device *dev, char __user *useraddr)
1338 : {
1339 0 : struct ethtool_wolinfo wol;
1340 0 : int ret;
1341 :
1342 0 : if (!dev->ethtool_ops->set_wol)
1343 : return -EOPNOTSUPP;
1344 :
1345 0 : if (copy_from_user(&wol, useraddr, sizeof(wol)))
1346 : return -EFAULT;
1347 :
1348 0 : ret = dev->ethtool_ops->set_wol(dev, &wol);
1349 0 : if (ret)
1350 : return ret;
1351 :
1352 0 : dev->wol_enabled = !!wol.wolopts;
1353 0 : ethtool_notify(dev, ETHTOOL_MSG_WOL_NTF, NULL);
1354 :
1355 0 : return 0;
1356 : }
1357 :
1358 0 : static int ethtool_get_eee(struct net_device *dev, char __user *useraddr)
1359 : {
1360 0 : struct ethtool_eee edata;
1361 0 : int rc;
1362 :
1363 0 : if (!dev->ethtool_ops->get_eee)
1364 : return -EOPNOTSUPP;
1365 :
1366 0 : memset(&edata, 0, sizeof(struct ethtool_eee));
1367 0 : edata.cmd = ETHTOOL_GEEE;
1368 0 : rc = dev->ethtool_ops->get_eee(dev, &edata);
1369 :
1370 0 : if (rc)
1371 : return rc;
1372 :
1373 0 : if (copy_to_user(useraddr, &edata, sizeof(edata)))
1374 0 : return -EFAULT;
1375 :
1376 : return 0;
1377 : }
1378 :
1379 0 : static int ethtool_set_eee(struct net_device *dev, char __user *useraddr)
1380 : {
1381 0 : struct ethtool_eee edata;
1382 0 : int ret;
1383 :
1384 0 : if (!dev->ethtool_ops->set_eee)
1385 : return -EOPNOTSUPP;
1386 :
1387 0 : if (copy_from_user(&edata, useraddr, sizeof(edata)))
1388 : return -EFAULT;
1389 :
1390 0 : ret = dev->ethtool_ops->set_eee(dev, &edata);
1391 0 : if (!ret)
1392 0 : ethtool_notify(dev, ETHTOOL_MSG_EEE_NTF, NULL);
1393 0 : return ret;
1394 : }
1395 :
1396 0 : static int ethtool_nway_reset(struct net_device *dev)
1397 : {
1398 0 : if (!dev->ethtool_ops->nway_reset)
1399 : return -EOPNOTSUPP;
1400 :
1401 0 : return dev->ethtool_ops->nway_reset(dev);
1402 : }
1403 :
1404 0 : static int ethtool_get_link(struct net_device *dev, char __user *useraddr)
1405 : {
1406 0 : struct ethtool_value edata = { .cmd = ETHTOOL_GLINK };
1407 0 : int link = __ethtool_get_link(dev);
1408 :
1409 0 : if (link < 0)
1410 : return link;
1411 :
1412 0 : edata.data = link;
1413 0 : if (copy_to_user(useraddr, &edata, sizeof(edata)))
1414 0 : return -EFAULT;
1415 : return 0;
1416 : }
1417 :
1418 0 : static int ethtool_get_any_eeprom(struct net_device *dev, void __user *useraddr,
1419 : int (*getter)(struct net_device *,
1420 : struct ethtool_eeprom *, u8 *),
1421 : u32 total_len)
1422 : {
1423 0 : struct ethtool_eeprom eeprom;
1424 0 : void __user *userbuf = useraddr + sizeof(eeprom);
1425 0 : u32 bytes_remaining;
1426 0 : u8 *data;
1427 0 : int ret = 0;
1428 :
1429 0 : if (copy_from_user(&eeprom, useraddr, sizeof(eeprom)))
1430 : return -EFAULT;
1431 :
1432 : /* Check for wrap and zero */
1433 0 : if (eeprom.offset + eeprom.len <= eeprom.offset)
1434 : return -EINVAL;
1435 :
1436 : /* Check for exceeding total eeprom len */
1437 0 : if (eeprom.offset + eeprom.len > total_len)
1438 : return -EINVAL;
1439 :
1440 0 : data = kmalloc(PAGE_SIZE, GFP_USER);
1441 0 : if (!data)
1442 : return -ENOMEM;
1443 :
1444 0 : bytes_remaining = eeprom.len;
1445 0 : while (bytes_remaining > 0) {
1446 0 : eeprom.len = min(bytes_remaining, (u32)PAGE_SIZE);
1447 :
1448 0 : ret = getter(dev, &eeprom, data);
1449 0 : if (ret)
1450 : break;
1451 0 : if (copy_to_user(userbuf, data, eeprom.len)) {
1452 : ret = -EFAULT;
1453 : break;
1454 : }
1455 0 : userbuf += eeprom.len;
1456 0 : eeprom.offset += eeprom.len;
1457 0 : bytes_remaining -= eeprom.len;
1458 : }
1459 :
1460 0 : eeprom.len = userbuf - (useraddr + sizeof(eeprom));
1461 0 : eeprom.offset -= eeprom.len;
1462 0 : if (copy_to_user(useraddr, &eeprom, sizeof(eeprom)))
1463 0 : ret = -EFAULT;
1464 :
1465 0 : kfree(data);
1466 0 : return ret;
1467 : }
1468 :
1469 0 : static int ethtool_get_eeprom(struct net_device *dev, void __user *useraddr)
1470 : {
1471 0 : const struct ethtool_ops *ops = dev->ethtool_ops;
1472 :
1473 0 : if (!ops->get_eeprom || !ops->get_eeprom_len ||
1474 0 : !ops->get_eeprom_len(dev))
1475 0 : return -EOPNOTSUPP;
1476 :
1477 0 : return ethtool_get_any_eeprom(dev, useraddr, ops->get_eeprom,
1478 0 : ops->get_eeprom_len(dev));
1479 : }
1480 :
1481 0 : static int ethtool_set_eeprom(struct net_device *dev, void __user *useraddr)
1482 : {
1483 0 : struct ethtool_eeprom eeprom;
1484 0 : const struct ethtool_ops *ops = dev->ethtool_ops;
1485 0 : void __user *userbuf = useraddr + sizeof(eeprom);
1486 0 : u32 bytes_remaining;
1487 0 : u8 *data;
1488 0 : int ret = 0;
1489 :
1490 0 : if (!ops->set_eeprom || !ops->get_eeprom_len ||
1491 0 : !ops->get_eeprom_len(dev))
1492 0 : return -EOPNOTSUPP;
1493 :
1494 0 : if (copy_from_user(&eeprom, useraddr, sizeof(eeprom)))
1495 : return -EFAULT;
1496 :
1497 : /* Check for wrap and zero */
1498 0 : if (eeprom.offset + eeprom.len <= eeprom.offset)
1499 : return -EINVAL;
1500 :
1501 : /* Check for exceeding total eeprom len */
1502 0 : if (eeprom.offset + eeprom.len > ops->get_eeprom_len(dev))
1503 : return -EINVAL;
1504 :
1505 0 : data = kmalloc(PAGE_SIZE, GFP_USER);
1506 0 : if (!data)
1507 : return -ENOMEM;
1508 :
1509 0 : bytes_remaining = eeprom.len;
1510 0 : while (bytes_remaining > 0) {
1511 0 : eeprom.len = min(bytes_remaining, (u32)PAGE_SIZE);
1512 :
1513 0 : if (copy_from_user(data, userbuf, eeprom.len)) {
1514 : ret = -EFAULT;
1515 : break;
1516 : }
1517 0 : ret = ops->set_eeprom(dev, &eeprom, data);
1518 0 : if (ret)
1519 : break;
1520 0 : userbuf += eeprom.len;
1521 0 : eeprom.offset += eeprom.len;
1522 0 : bytes_remaining -= eeprom.len;
1523 : }
1524 :
1525 0 : kfree(data);
1526 0 : return ret;
1527 : }
1528 :
1529 0 : static noinline_for_stack int ethtool_get_coalesce(struct net_device *dev,
1530 : void __user *useraddr)
1531 : {
1532 0 : struct ethtool_coalesce coalesce = { .cmd = ETHTOOL_GCOALESCE };
1533 0 : int ret;
1534 :
1535 0 : if (!dev->ethtool_ops->get_coalesce)
1536 : return -EOPNOTSUPP;
1537 :
1538 0 : ret = dev->ethtool_ops->get_coalesce(dev, &coalesce);
1539 0 : if (ret)
1540 : return ret;
1541 :
1542 0 : if (copy_to_user(useraddr, &coalesce, sizeof(coalesce)))
1543 0 : return -EFAULT;
1544 : return 0;
1545 : }
1546 :
1547 : static bool
1548 0 : ethtool_set_coalesce_supported(struct net_device *dev,
1549 : struct ethtool_coalesce *coalesce)
1550 : {
1551 0 : u32 supported_params = dev->ethtool_ops->supported_coalesce_params;
1552 0 : u32 nonzero_params = 0;
1553 :
1554 0 : if (coalesce->rx_coalesce_usecs)
1555 0 : nonzero_params |= ETHTOOL_COALESCE_RX_USECS;
1556 0 : if (coalesce->rx_max_coalesced_frames)
1557 0 : nonzero_params |= ETHTOOL_COALESCE_RX_MAX_FRAMES;
1558 0 : if (coalesce->rx_coalesce_usecs_irq)
1559 0 : nonzero_params |= ETHTOOL_COALESCE_RX_USECS_IRQ;
1560 0 : if (coalesce->rx_max_coalesced_frames_irq)
1561 0 : nonzero_params |= ETHTOOL_COALESCE_RX_MAX_FRAMES_IRQ;
1562 0 : if (coalesce->tx_coalesce_usecs)
1563 0 : nonzero_params |= ETHTOOL_COALESCE_TX_USECS;
1564 0 : if (coalesce->tx_max_coalesced_frames)
1565 0 : nonzero_params |= ETHTOOL_COALESCE_TX_MAX_FRAMES;
1566 0 : if (coalesce->tx_coalesce_usecs_irq)
1567 0 : nonzero_params |= ETHTOOL_COALESCE_TX_USECS_IRQ;
1568 0 : if (coalesce->tx_max_coalesced_frames_irq)
1569 0 : nonzero_params |= ETHTOOL_COALESCE_TX_MAX_FRAMES_IRQ;
1570 0 : if (coalesce->stats_block_coalesce_usecs)
1571 0 : nonzero_params |= ETHTOOL_COALESCE_STATS_BLOCK_USECS;
1572 0 : if (coalesce->use_adaptive_rx_coalesce)
1573 0 : nonzero_params |= ETHTOOL_COALESCE_USE_ADAPTIVE_RX;
1574 0 : if (coalesce->use_adaptive_tx_coalesce)
1575 0 : nonzero_params |= ETHTOOL_COALESCE_USE_ADAPTIVE_TX;
1576 0 : if (coalesce->pkt_rate_low)
1577 0 : nonzero_params |= ETHTOOL_COALESCE_PKT_RATE_LOW;
1578 0 : if (coalesce->rx_coalesce_usecs_low)
1579 0 : nonzero_params |= ETHTOOL_COALESCE_RX_USECS_LOW;
1580 0 : if (coalesce->rx_max_coalesced_frames_low)
1581 0 : nonzero_params |= ETHTOOL_COALESCE_RX_MAX_FRAMES_LOW;
1582 0 : if (coalesce->tx_coalesce_usecs_low)
1583 0 : nonzero_params |= ETHTOOL_COALESCE_TX_USECS_LOW;
1584 0 : if (coalesce->tx_max_coalesced_frames_low)
1585 0 : nonzero_params |= ETHTOOL_COALESCE_TX_MAX_FRAMES_LOW;
1586 0 : if (coalesce->pkt_rate_high)
1587 0 : nonzero_params |= ETHTOOL_COALESCE_PKT_RATE_HIGH;
1588 0 : if (coalesce->rx_coalesce_usecs_high)
1589 0 : nonzero_params |= ETHTOOL_COALESCE_RX_USECS_HIGH;
1590 0 : if (coalesce->rx_max_coalesced_frames_high)
1591 0 : nonzero_params |= ETHTOOL_COALESCE_RX_MAX_FRAMES_HIGH;
1592 0 : if (coalesce->tx_coalesce_usecs_high)
1593 0 : nonzero_params |= ETHTOOL_COALESCE_TX_USECS_HIGH;
1594 0 : if (coalesce->tx_max_coalesced_frames_high)
1595 0 : nonzero_params |= ETHTOOL_COALESCE_TX_MAX_FRAMES_HIGH;
1596 0 : if (coalesce->rate_sample_interval)
1597 0 : nonzero_params |= ETHTOOL_COALESCE_RATE_SAMPLE_INTERVAL;
1598 :
1599 0 : return (supported_params & nonzero_params) == nonzero_params;
1600 : }
1601 :
1602 0 : static noinline_for_stack int ethtool_set_coalesce(struct net_device *dev,
1603 : void __user *useraddr)
1604 : {
1605 0 : struct ethtool_coalesce coalesce;
1606 0 : int ret;
1607 :
1608 0 : if (!dev->ethtool_ops->set_coalesce)
1609 : return -EOPNOTSUPP;
1610 :
1611 0 : if (copy_from_user(&coalesce, useraddr, sizeof(coalesce)))
1612 : return -EFAULT;
1613 :
1614 0 : if (!ethtool_set_coalesce_supported(dev, &coalesce))
1615 : return -EOPNOTSUPP;
1616 :
1617 0 : ret = dev->ethtool_ops->set_coalesce(dev, &coalesce);
1618 0 : if (!ret)
1619 0 : ethtool_notify(dev, ETHTOOL_MSG_COALESCE_NTF, NULL);
1620 0 : return ret;
1621 : }
1622 :
1623 0 : static int ethtool_get_ringparam(struct net_device *dev, void __user *useraddr)
1624 : {
1625 0 : struct ethtool_ringparam ringparam = { .cmd = ETHTOOL_GRINGPARAM };
1626 :
1627 0 : if (!dev->ethtool_ops->get_ringparam)
1628 : return -EOPNOTSUPP;
1629 :
1630 0 : dev->ethtool_ops->get_ringparam(dev, &ringparam);
1631 :
1632 0 : if (copy_to_user(useraddr, &ringparam, sizeof(ringparam)))
1633 0 : return -EFAULT;
1634 : return 0;
1635 : }
1636 :
1637 0 : static int ethtool_set_ringparam(struct net_device *dev, void __user *useraddr)
1638 : {
1639 0 : struct ethtool_ringparam ringparam, max = { .cmd = ETHTOOL_GRINGPARAM };
1640 0 : int ret;
1641 :
1642 0 : if (!dev->ethtool_ops->set_ringparam || !dev->ethtool_ops->get_ringparam)
1643 : return -EOPNOTSUPP;
1644 :
1645 0 : if (copy_from_user(&ringparam, useraddr, sizeof(ringparam)))
1646 : return -EFAULT;
1647 :
1648 0 : dev->ethtool_ops->get_ringparam(dev, &max);
1649 :
1650 : /* ensure new ring parameters are within the maximums */
1651 0 : if (ringparam.rx_pending > max.rx_max_pending ||
1652 0 : ringparam.rx_mini_pending > max.rx_mini_max_pending ||
1653 0 : ringparam.rx_jumbo_pending > max.rx_jumbo_max_pending ||
1654 0 : ringparam.tx_pending > max.tx_max_pending)
1655 : return -EINVAL;
1656 :
1657 0 : ret = dev->ethtool_ops->set_ringparam(dev, &ringparam);
1658 0 : if (!ret)
1659 0 : ethtool_notify(dev, ETHTOOL_MSG_RINGS_NTF, NULL);
1660 0 : return ret;
1661 : }
1662 :
1663 0 : static noinline_for_stack int ethtool_get_channels(struct net_device *dev,
1664 : void __user *useraddr)
1665 : {
1666 0 : struct ethtool_channels channels = { .cmd = ETHTOOL_GCHANNELS };
1667 :
1668 0 : if (!dev->ethtool_ops->get_channels)
1669 : return -EOPNOTSUPP;
1670 :
1671 0 : dev->ethtool_ops->get_channels(dev, &channels);
1672 :
1673 0 : if (copy_to_user(useraddr, &channels, sizeof(channels)))
1674 0 : return -EFAULT;
1675 : return 0;
1676 : }
1677 :
1678 0 : static noinline_for_stack int ethtool_set_channels(struct net_device *dev,
1679 : void __user *useraddr)
1680 : {
1681 0 : struct ethtool_channels channels, curr = { .cmd = ETHTOOL_GCHANNELS };
1682 0 : u16 from_channel, to_channel;
1683 0 : u32 max_rx_in_use = 0;
1684 0 : unsigned int i;
1685 0 : int ret;
1686 :
1687 0 : if (!dev->ethtool_ops->set_channels || !dev->ethtool_ops->get_channels)
1688 : return -EOPNOTSUPP;
1689 :
1690 0 : if (copy_from_user(&channels, useraddr, sizeof(channels)))
1691 : return -EFAULT;
1692 :
1693 0 : dev->ethtool_ops->get_channels(dev, &curr);
1694 :
1695 0 : if (channels.rx_count == curr.rx_count &&
1696 0 : channels.tx_count == curr.tx_count &&
1697 0 : channels.combined_count == curr.combined_count &&
1698 0 : channels.other_count == curr.other_count)
1699 : return 0;
1700 :
1701 : /* ensure new counts are within the maximums */
1702 0 : if (channels.rx_count > curr.max_rx ||
1703 0 : channels.tx_count > curr.max_tx ||
1704 0 : channels.combined_count > curr.max_combined ||
1705 0 : channels.other_count > curr.max_other)
1706 : return -EINVAL;
1707 :
1708 : /* ensure there is at least one RX and one TX channel */
1709 0 : if (!channels.combined_count &&
1710 0 : (!channels.rx_count || !channels.tx_count))
1711 : return -EINVAL;
1712 :
1713 : /* ensure the new Rx count fits within the configured Rx flow
1714 : * indirection table settings */
1715 0 : if (netif_is_rxfh_configured(dev) &&
1716 0 : !ethtool_get_max_rxfh_channel(dev, &max_rx_in_use) &&
1717 0 : (channels.combined_count + channels.rx_count) <= max_rx_in_use)
1718 : return -EINVAL;
1719 :
1720 : /* Disabling channels, query zero-copy AF_XDP sockets */
1721 0 : from_channel = channels.combined_count +
1722 0 : min(channels.rx_count, channels.tx_count);
1723 0 : to_channel = curr.combined_count + max(curr.rx_count, curr.tx_count);
1724 0 : for (i = from_channel; i < to_channel; i++)
1725 : if (xsk_get_pool_from_qid(dev, i))
1726 : return -EINVAL;
1727 :
1728 0 : ret = dev->ethtool_ops->set_channels(dev, &channels);
1729 0 : if (!ret)
1730 0 : ethtool_notify(dev, ETHTOOL_MSG_CHANNELS_NTF, NULL);
1731 0 : return ret;
1732 : }
1733 :
1734 0 : static int ethtool_get_pauseparam(struct net_device *dev, void __user *useraddr)
1735 : {
1736 0 : struct ethtool_pauseparam pauseparam = { .cmd = ETHTOOL_GPAUSEPARAM };
1737 :
1738 0 : if (!dev->ethtool_ops->get_pauseparam)
1739 : return -EOPNOTSUPP;
1740 :
1741 0 : dev->ethtool_ops->get_pauseparam(dev, &pauseparam);
1742 :
1743 0 : if (copy_to_user(useraddr, &pauseparam, sizeof(pauseparam)))
1744 0 : return -EFAULT;
1745 : return 0;
1746 : }
1747 :
1748 0 : static int ethtool_set_pauseparam(struct net_device *dev, void __user *useraddr)
1749 : {
1750 0 : struct ethtool_pauseparam pauseparam;
1751 0 : int ret;
1752 :
1753 0 : if (!dev->ethtool_ops->set_pauseparam)
1754 : return -EOPNOTSUPP;
1755 :
1756 0 : if (copy_from_user(&pauseparam, useraddr, sizeof(pauseparam)))
1757 : return -EFAULT;
1758 :
1759 0 : ret = dev->ethtool_ops->set_pauseparam(dev, &pauseparam);
1760 0 : if (!ret)
1761 0 : ethtool_notify(dev, ETHTOOL_MSG_PAUSE_NTF, NULL);
1762 0 : return ret;
1763 : }
1764 :
1765 0 : static int ethtool_self_test(struct net_device *dev, char __user *useraddr)
1766 : {
1767 0 : struct ethtool_test test;
1768 0 : const struct ethtool_ops *ops = dev->ethtool_ops;
1769 0 : u64 *data;
1770 0 : int ret, test_len;
1771 :
1772 0 : if (!ops->self_test || !ops->get_sset_count)
1773 : return -EOPNOTSUPP;
1774 :
1775 0 : test_len = ops->get_sset_count(dev, ETH_SS_TEST);
1776 0 : if (test_len < 0)
1777 : return test_len;
1778 0 : WARN_ON(test_len == 0);
1779 :
1780 0 : if (copy_from_user(&test, useraddr, sizeof(test)))
1781 : return -EFAULT;
1782 :
1783 0 : test.len = test_len;
1784 0 : data = kmalloc_array(test_len, sizeof(u64), GFP_USER);
1785 0 : if (!data)
1786 : return -ENOMEM;
1787 :
1788 0 : netif_testing_on(dev);
1789 0 : ops->self_test(dev, &test, data);
1790 0 : netif_testing_off(dev);
1791 :
1792 0 : ret = -EFAULT;
1793 0 : if (copy_to_user(useraddr, &test, sizeof(test)))
1794 0 : goto out;
1795 0 : useraddr += sizeof(test);
1796 0 : if (copy_to_user(useraddr, data, test.len * sizeof(u64)))
1797 0 : goto out;
1798 : ret = 0;
1799 :
1800 0 : out:
1801 0 : kfree(data);
1802 0 : return ret;
1803 : }
1804 :
1805 2 : static int ethtool_get_strings(struct net_device *dev, void __user *useraddr)
1806 : {
1807 2 : struct ethtool_gstrings gstrings;
1808 2 : u8 *data;
1809 2 : int ret;
1810 :
1811 2 : if (copy_from_user(&gstrings, useraddr, sizeof(gstrings)))
1812 : return -EFAULT;
1813 :
1814 2 : ret = __ethtool_get_sset_count(dev, gstrings.string_set);
1815 2 : if (ret < 0)
1816 : return ret;
1817 2 : if (ret > S32_MAX / ETH_GSTRING_LEN)
1818 : return -ENOMEM;
1819 2 : WARN_ON_ONCE(!ret);
1820 :
1821 2 : gstrings.len = ret;
1822 :
1823 2 : if (gstrings.len) {
1824 2 : data = vzalloc(array_size(gstrings.len, ETH_GSTRING_LEN));
1825 2 : if (!data)
1826 : return -ENOMEM;
1827 :
1828 2 : __ethtool_get_strings(dev, gstrings.string_set, data);
1829 : } else {
1830 : data = NULL;
1831 : }
1832 :
1833 2 : ret = -EFAULT;
1834 2 : if (copy_to_user(useraddr, &gstrings, sizeof(gstrings)))
1835 0 : goto out;
1836 2 : useraddr += sizeof(gstrings);
1837 2 : if (gstrings.len &&
1838 4 : copy_to_user(useraddr, data, gstrings.len * ETH_GSTRING_LEN))
1839 0 : goto out;
1840 : ret = 0;
1841 :
1842 2 : out:
1843 2 : vfree(data);
1844 2 : return ret;
1845 : }
1846 :
1847 0 : static int ethtool_phys_id(struct net_device *dev, void __user *useraddr)
1848 : {
1849 0 : struct ethtool_value id;
1850 0 : static bool busy;
1851 0 : const struct ethtool_ops *ops = dev->ethtool_ops;
1852 0 : int rc;
1853 :
1854 0 : if (!ops->set_phys_id)
1855 : return -EOPNOTSUPP;
1856 :
1857 0 : if (busy)
1858 : return -EBUSY;
1859 :
1860 0 : if (copy_from_user(&id, useraddr, sizeof(id)))
1861 : return -EFAULT;
1862 :
1863 0 : rc = ops->set_phys_id(dev, ETHTOOL_ID_ACTIVE);
1864 0 : if (rc < 0)
1865 : return rc;
1866 :
1867 : /* Drop the RTNL lock while waiting, but prevent reentry or
1868 : * removal of the device.
1869 : */
1870 0 : busy = true;
1871 0 : dev_hold(dev);
1872 0 : rtnl_unlock();
1873 :
1874 0 : if (rc == 0) {
1875 : /* Driver will handle this itself */
1876 0 : schedule_timeout_interruptible(
1877 0 : id.data ? (id.data * HZ) : MAX_SCHEDULE_TIMEOUT);
1878 : } else {
1879 : /* Driver expects to be called at twice the frequency in rc */
1880 0 : int n = rc * 2, interval = HZ / n;
1881 0 : u64 count = n * id.data, i = 0;
1882 :
1883 0 : do {
1884 0 : rtnl_lock();
1885 0 : rc = ops->set_phys_id(dev,
1886 0 : (i++ & 1) ? ETHTOOL_ID_OFF : ETHTOOL_ID_ON);
1887 0 : rtnl_unlock();
1888 0 : if (rc)
1889 : break;
1890 0 : schedule_timeout_interruptible(interval);
1891 0 : } while (!signal_pending(current) && (!id.data || i < count));
1892 : }
1893 :
1894 0 : rtnl_lock();
1895 0 : dev_put(dev);
1896 0 : busy = false;
1897 :
1898 0 : (void) ops->set_phys_id(dev, ETHTOOL_ID_INACTIVE);
1899 0 : return rc;
1900 : }
1901 :
1902 0 : static int ethtool_get_stats(struct net_device *dev, void __user *useraddr)
1903 : {
1904 0 : struct ethtool_stats stats;
1905 0 : const struct ethtool_ops *ops = dev->ethtool_ops;
1906 0 : u64 *data;
1907 0 : int ret, n_stats;
1908 :
1909 0 : if (!ops->get_ethtool_stats || !ops->get_sset_count)
1910 : return -EOPNOTSUPP;
1911 :
1912 0 : n_stats = ops->get_sset_count(dev, ETH_SS_STATS);
1913 0 : if (n_stats < 0)
1914 : return n_stats;
1915 0 : if (n_stats > S32_MAX / sizeof(u64))
1916 : return -ENOMEM;
1917 0 : WARN_ON_ONCE(!n_stats);
1918 0 : if (copy_from_user(&stats, useraddr, sizeof(stats)))
1919 : return -EFAULT;
1920 :
1921 0 : stats.n_stats = n_stats;
1922 :
1923 0 : if (n_stats) {
1924 0 : data = vzalloc(array_size(n_stats, sizeof(u64)));
1925 0 : if (!data)
1926 : return -ENOMEM;
1927 0 : ops->get_ethtool_stats(dev, &stats, data);
1928 : } else {
1929 : data = NULL;
1930 : }
1931 :
1932 0 : ret = -EFAULT;
1933 0 : if (copy_to_user(useraddr, &stats, sizeof(stats)))
1934 0 : goto out;
1935 0 : useraddr += sizeof(stats);
1936 0 : if (n_stats && copy_to_user(useraddr, data, array_size(n_stats, sizeof(u64))))
1937 0 : goto out;
1938 : ret = 0;
1939 :
1940 0 : out:
1941 0 : vfree(data);
1942 0 : return ret;
1943 : }
1944 :
1945 0 : static int ethtool_get_phy_stats(struct net_device *dev, void __user *useraddr)
1946 : {
1947 0 : const struct ethtool_phy_ops *phy_ops = ethtool_phy_ops;
1948 0 : const struct ethtool_ops *ops = dev->ethtool_ops;
1949 0 : struct phy_device *phydev = dev->phydev;
1950 0 : struct ethtool_stats stats;
1951 0 : u64 *data;
1952 0 : int ret, n_stats;
1953 :
1954 0 : if (!phydev && (!ops->get_ethtool_phy_stats || !ops->get_sset_count))
1955 : return -EOPNOTSUPP;
1956 :
1957 0 : if (dev->phydev && !ops->get_ethtool_phy_stats &&
1958 0 : phy_ops && phy_ops->get_sset_count)
1959 0 : n_stats = phy_ops->get_sset_count(dev->phydev);
1960 : else
1961 0 : n_stats = ops->get_sset_count(dev, ETH_SS_PHY_STATS);
1962 0 : if (n_stats < 0)
1963 : return n_stats;
1964 0 : if (n_stats > S32_MAX / sizeof(u64))
1965 : return -ENOMEM;
1966 0 : WARN_ON_ONCE(!n_stats);
1967 :
1968 0 : if (copy_from_user(&stats, useraddr, sizeof(stats)))
1969 : return -EFAULT;
1970 :
1971 0 : stats.n_stats = n_stats;
1972 :
1973 0 : if (n_stats) {
1974 0 : data = vzalloc(array_size(n_stats, sizeof(u64)));
1975 0 : if (!data)
1976 : return -ENOMEM;
1977 :
1978 0 : if (dev->phydev && !ops->get_ethtool_phy_stats &&
1979 0 : phy_ops && phy_ops->get_stats) {
1980 0 : ret = phy_ops->get_stats(dev->phydev, &stats, data);
1981 0 : if (ret < 0)
1982 0 : goto out;
1983 : } else {
1984 0 : ops->get_ethtool_phy_stats(dev, &stats, data);
1985 : }
1986 : } else {
1987 : data = NULL;
1988 : }
1989 :
1990 0 : ret = -EFAULT;
1991 0 : if (copy_to_user(useraddr, &stats, sizeof(stats)))
1992 0 : goto out;
1993 0 : useraddr += sizeof(stats);
1994 0 : if (n_stats && copy_to_user(useraddr, data, array_size(n_stats, sizeof(u64))))
1995 0 : goto out;
1996 : ret = 0;
1997 :
1998 0 : out:
1999 0 : vfree(data);
2000 0 : return ret;
2001 : }
2002 :
2003 0 : static int ethtool_get_perm_addr(struct net_device *dev, void __user *useraddr)
2004 : {
2005 0 : struct ethtool_perm_addr epaddr;
2006 :
2007 0 : if (copy_from_user(&epaddr, useraddr, sizeof(epaddr)))
2008 : return -EFAULT;
2009 :
2010 0 : if (epaddr.size < dev->addr_len)
2011 : return -ETOOSMALL;
2012 0 : epaddr.size = dev->addr_len;
2013 :
2014 0 : if (copy_to_user(useraddr, &epaddr, sizeof(epaddr)))
2015 : return -EFAULT;
2016 0 : useraddr += sizeof(epaddr);
2017 0 : if (copy_to_user(useraddr, dev->perm_addr, epaddr.size))
2018 0 : return -EFAULT;
2019 : return 0;
2020 : }
2021 :
2022 0 : static int ethtool_get_value(struct net_device *dev, char __user *useraddr,
2023 : u32 cmd, u32 (*actor)(struct net_device *))
2024 : {
2025 0 : struct ethtool_value edata = { .cmd = cmd };
2026 :
2027 0 : if (!actor)
2028 : return -EOPNOTSUPP;
2029 :
2030 0 : edata.data = actor(dev);
2031 :
2032 0 : if (copy_to_user(useraddr, &edata, sizeof(edata)))
2033 0 : return -EFAULT;
2034 : return 0;
2035 : }
2036 :
2037 0 : static int ethtool_set_value_void(struct net_device *dev, char __user *useraddr,
2038 : void (*actor)(struct net_device *, u32))
2039 : {
2040 0 : struct ethtool_value edata;
2041 :
2042 0 : if (!actor)
2043 : return -EOPNOTSUPP;
2044 :
2045 0 : if (copy_from_user(&edata, useraddr, sizeof(edata)))
2046 : return -EFAULT;
2047 :
2048 0 : actor(dev, edata.data);
2049 0 : return 0;
2050 : }
2051 :
2052 0 : static int ethtool_set_value(struct net_device *dev, char __user *useraddr,
2053 : int (*actor)(struct net_device *, u32))
2054 : {
2055 0 : struct ethtool_value edata;
2056 :
2057 0 : if (!actor)
2058 : return -EOPNOTSUPP;
2059 :
2060 0 : if (copy_from_user(&edata, useraddr, sizeof(edata)))
2061 : return -EFAULT;
2062 :
2063 0 : return actor(dev, edata.data);
2064 : }
2065 :
2066 0 : static noinline_for_stack int ethtool_flash_device(struct net_device *dev,
2067 : char __user *useraddr)
2068 : {
2069 0 : struct ethtool_flash efl;
2070 :
2071 0 : if (copy_from_user(&efl, useraddr, sizeof(efl)))
2072 : return -EFAULT;
2073 0 : efl.data[ETHTOOL_FLASH_MAX_FILENAME - 1] = 0;
2074 :
2075 0 : if (!dev->ethtool_ops->flash_device)
2076 0 : return devlink_compat_flash_update(dev, efl.data);
2077 :
2078 0 : return dev->ethtool_ops->flash_device(dev, &efl);
2079 : }
2080 :
2081 0 : static int ethtool_set_dump(struct net_device *dev,
2082 : void __user *useraddr)
2083 : {
2084 0 : struct ethtool_dump dump;
2085 :
2086 0 : if (!dev->ethtool_ops->set_dump)
2087 : return -EOPNOTSUPP;
2088 :
2089 0 : if (copy_from_user(&dump, useraddr, sizeof(dump)))
2090 : return -EFAULT;
2091 :
2092 0 : return dev->ethtool_ops->set_dump(dev, &dump);
2093 : }
2094 :
2095 0 : static int ethtool_get_dump_flag(struct net_device *dev,
2096 : void __user *useraddr)
2097 : {
2098 0 : int ret;
2099 0 : struct ethtool_dump dump;
2100 0 : const struct ethtool_ops *ops = dev->ethtool_ops;
2101 :
2102 0 : if (!ops->get_dump_flag)
2103 : return -EOPNOTSUPP;
2104 :
2105 0 : if (copy_from_user(&dump, useraddr, sizeof(dump)))
2106 : return -EFAULT;
2107 :
2108 0 : ret = ops->get_dump_flag(dev, &dump);
2109 0 : if (ret)
2110 : return ret;
2111 :
2112 0 : if (copy_to_user(useraddr, &dump, sizeof(dump)))
2113 0 : return -EFAULT;
2114 : return 0;
2115 : }
2116 :
2117 0 : static int ethtool_get_dump_data(struct net_device *dev,
2118 : void __user *useraddr)
2119 : {
2120 0 : int ret;
2121 0 : __u32 len;
2122 0 : struct ethtool_dump dump, tmp;
2123 0 : const struct ethtool_ops *ops = dev->ethtool_ops;
2124 0 : void *data = NULL;
2125 :
2126 0 : if (!ops->get_dump_data || !ops->get_dump_flag)
2127 : return -EOPNOTSUPP;
2128 :
2129 0 : if (copy_from_user(&dump, useraddr, sizeof(dump)))
2130 : return -EFAULT;
2131 :
2132 0 : memset(&tmp, 0, sizeof(tmp));
2133 0 : tmp.cmd = ETHTOOL_GET_DUMP_FLAG;
2134 0 : ret = ops->get_dump_flag(dev, &tmp);
2135 0 : if (ret)
2136 : return ret;
2137 :
2138 0 : len = min(tmp.len, dump.len);
2139 0 : if (!len)
2140 : return -EFAULT;
2141 :
2142 : /* Don't ever let the driver think there's more space available
2143 : * than it requested with .get_dump_flag().
2144 : */
2145 0 : dump.len = len;
2146 :
2147 : /* Always allocate enough space to hold the whole thing so that the
2148 : * driver does not need to check the length and bother with partial
2149 : * dumping.
2150 : */
2151 0 : data = vzalloc(tmp.len);
2152 0 : if (!data)
2153 : return -ENOMEM;
2154 0 : ret = ops->get_dump_data(dev, &dump, data);
2155 0 : if (ret)
2156 0 : goto out;
2157 :
2158 : /* There are two sane possibilities:
2159 : * 1. The driver's .get_dump_data() does not touch dump.len.
2160 : * 2. Or it may set dump.len to how much it really writes, which
2161 : * should be tmp.len (or len if it can do a partial dump).
2162 : * In any case respond to userspace with the actual length of data
2163 : * it's receiving.
2164 : */
2165 0 : WARN_ON(dump.len != len && dump.len != tmp.len);
2166 0 : dump.len = len;
2167 :
2168 0 : if (copy_to_user(useraddr, &dump, sizeof(dump))) {
2169 0 : ret = -EFAULT;
2170 0 : goto out;
2171 : }
2172 0 : useraddr += offsetof(struct ethtool_dump, data);
2173 0 : if (copy_to_user(useraddr, data, len))
2174 0 : ret = -EFAULT;
2175 0 : out:
2176 0 : vfree(data);
2177 0 : return ret;
2178 : }
2179 :
2180 0 : static int ethtool_get_ts_info(struct net_device *dev, void __user *useraddr)
2181 : {
2182 0 : struct ethtool_ts_info info;
2183 0 : int err;
2184 :
2185 0 : err = __ethtool_get_ts_info(dev, &info);
2186 0 : if (err)
2187 : return err;
2188 :
2189 0 : if (copy_to_user(useraddr, &info, sizeof(info)))
2190 0 : return -EFAULT;
2191 :
2192 : return 0;
2193 : }
2194 :
2195 0 : static int __ethtool_get_module_info(struct net_device *dev,
2196 : struct ethtool_modinfo *modinfo)
2197 : {
2198 0 : const struct ethtool_ops *ops = dev->ethtool_ops;
2199 0 : struct phy_device *phydev = dev->phydev;
2200 :
2201 0 : if (dev->sfp_bus)
2202 0 : return sfp_get_module_info(dev->sfp_bus, modinfo);
2203 :
2204 0 : if (phydev && phydev->drv && phydev->drv->module_info)
2205 0 : return phydev->drv->module_info(phydev, modinfo);
2206 :
2207 0 : if (ops->get_module_info)
2208 0 : return ops->get_module_info(dev, modinfo);
2209 :
2210 : return -EOPNOTSUPP;
2211 : }
2212 :
2213 0 : static int ethtool_get_module_info(struct net_device *dev,
2214 : void __user *useraddr)
2215 : {
2216 0 : int ret;
2217 0 : struct ethtool_modinfo modinfo;
2218 :
2219 0 : if (copy_from_user(&modinfo, useraddr, sizeof(modinfo)))
2220 : return -EFAULT;
2221 :
2222 0 : ret = __ethtool_get_module_info(dev, &modinfo);
2223 0 : if (ret)
2224 : return ret;
2225 :
2226 0 : if (copy_to_user(useraddr, &modinfo, sizeof(modinfo)))
2227 0 : return -EFAULT;
2228 :
2229 : return 0;
2230 : }
2231 :
2232 0 : static int __ethtool_get_module_eeprom(struct net_device *dev,
2233 : struct ethtool_eeprom *ee, u8 *data)
2234 : {
2235 0 : const struct ethtool_ops *ops = dev->ethtool_ops;
2236 0 : struct phy_device *phydev = dev->phydev;
2237 :
2238 0 : if (dev->sfp_bus)
2239 0 : return sfp_get_module_eeprom(dev->sfp_bus, ee, data);
2240 :
2241 0 : if (phydev && phydev->drv && phydev->drv->module_eeprom)
2242 0 : return phydev->drv->module_eeprom(phydev, ee, data);
2243 :
2244 0 : if (ops->get_module_eeprom)
2245 0 : return ops->get_module_eeprom(dev, ee, data);
2246 :
2247 : return -EOPNOTSUPP;
2248 : }
2249 :
2250 0 : static int ethtool_get_module_eeprom(struct net_device *dev,
2251 : void __user *useraddr)
2252 : {
2253 0 : int ret;
2254 0 : struct ethtool_modinfo modinfo;
2255 :
2256 0 : ret = __ethtool_get_module_info(dev, &modinfo);
2257 0 : if (ret)
2258 : return ret;
2259 :
2260 0 : return ethtool_get_any_eeprom(dev, useraddr,
2261 : __ethtool_get_module_eeprom,
2262 : modinfo.eeprom_len);
2263 : }
2264 :
2265 0 : static int ethtool_tunable_valid(const struct ethtool_tunable *tuna)
2266 : {
2267 0 : switch (tuna->id) {
2268 0 : case ETHTOOL_RX_COPYBREAK:
2269 : case ETHTOOL_TX_COPYBREAK:
2270 0 : if (tuna->len != sizeof(u32) ||
2271 : tuna->type_id != ETHTOOL_TUNABLE_U32)
2272 0 : return -EINVAL;
2273 : break;
2274 0 : case ETHTOOL_PFC_PREVENTION_TOUT:
2275 0 : if (tuna->len != sizeof(u16) ||
2276 : tuna->type_id != ETHTOOL_TUNABLE_U16)
2277 0 : return -EINVAL;
2278 : break;
2279 : default:
2280 : return -EINVAL;
2281 : }
2282 :
2283 : return 0;
2284 : }
2285 :
2286 0 : static int ethtool_get_tunable(struct net_device *dev, void __user *useraddr)
2287 : {
2288 0 : int ret;
2289 0 : struct ethtool_tunable tuna;
2290 0 : const struct ethtool_ops *ops = dev->ethtool_ops;
2291 0 : void *data;
2292 :
2293 0 : if (!ops->get_tunable)
2294 : return -EOPNOTSUPP;
2295 0 : if (copy_from_user(&tuna, useraddr, sizeof(tuna)))
2296 : return -EFAULT;
2297 0 : ret = ethtool_tunable_valid(&tuna);
2298 0 : if (ret)
2299 : return ret;
2300 0 : data = kmalloc(tuna.len, GFP_USER);
2301 0 : if (!data)
2302 : return -ENOMEM;
2303 0 : ret = ops->get_tunable(dev, &tuna, data);
2304 0 : if (ret)
2305 0 : goto out;
2306 0 : useraddr += sizeof(tuna);
2307 0 : ret = -EFAULT;
2308 0 : if (copy_to_user(useraddr, data, tuna.len))
2309 0 : goto out;
2310 : ret = 0;
2311 :
2312 0 : out:
2313 0 : kfree(data);
2314 0 : return ret;
2315 : }
2316 :
2317 0 : static int ethtool_set_tunable(struct net_device *dev, void __user *useraddr)
2318 : {
2319 0 : int ret;
2320 0 : struct ethtool_tunable tuna;
2321 0 : const struct ethtool_ops *ops = dev->ethtool_ops;
2322 0 : void *data;
2323 :
2324 0 : if (!ops->set_tunable)
2325 : return -EOPNOTSUPP;
2326 0 : if (copy_from_user(&tuna, useraddr, sizeof(tuna)))
2327 : return -EFAULT;
2328 0 : ret = ethtool_tunable_valid(&tuna);
2329 0 : if (ret)
2330 : return ret;
2331 0 : useraddr += sizeof(tuna);
2332 0 : data = memdup_user(useraddr, tuna.len);
2333 0 : if (IS_ERR(data))
2334 0 : return PTR_ERR(data);
2335 0 : ret = ops->set_tunable(dev, &tuna, data);
2336 :
2337 0 : kfree(data);
2338 0 : return ret;
2339 : }
2340 :
2341 : static noinline_for_stack int
2342 0 : ethtool_get_per_queue_coalesce(struct net_device *dev,
2343 : void __user *useraddr,
2344 : struct ethtool_per_queue_op *per_queue_opt)
2345 : {
2346 0 : u32 bit;
2347 0 : int ret;
2348 0 : DECLARE_BITMAP(queue_mask, MAX_NUM_QUEUE);
2349 :
2350 0 : if (!dev->ethtool_ops->get_per_queue_coalesce)
2351 : return -EOPNOTSUPP;
2352 :
2353 0 : useraddr += sizeof(*per_queue_opt);
2354 :
2355 0 : bitmap_from_arr32(queue_mask, per_queue_opt->queue_mask,
2356 : MAX_NUM_QUEUE);
2357 :
2358 0 : for_each_set_bit(bit, queue_mask, MAX_NUM_QUEUE) {
2359 0 : struct ethtool_coalesce coalesce = { .cmd = ETHTOOL_GCOALESCE };
2360 :
2361 0 : ret = dev->ethtool_ops->get_per_queue_coalesce(dev, bit, &coalesce);
2362 0 : if (ret != 0)
2363 0 : return ret;
2364 0 : if (copy_to_user(useraddr, &coalesce, sizeof(coalesce)))
2365 : return -EFAULT;
2366 0 : useraddr += sizeof(coalesce);
2367 : }
2368 :
2369 : return 0;
2370 : }
2371 :
2372 : static noinline_for_stack int
2373 0 : ethtool_set_per_queue_coalesce(struct net_device *dev,
2374 : void __user *useraddr,
2375 : struct ethtool_per_queue_op *per_queue_opt)
2376 : {
2377 0 : u32 bit;
2378 0 : int i, ret = 0;
2379 0 : int n_queue;
2380 0 : struct ethtool_coalesce *backup = NULL, *tmp = NULL;
2381 0 : DECLARE_BITMAP(queue_mask, MAX_NUM_QUEUE);
2382 :
2383 0 : if ((!dev->ethtool_ops->set_per_queue_coalesce) ||
2384 0 : (!dev->ethtool_ops->get_per_queue_coalesce))
2385 : return -EOPNOTSUPP;
2386 :
2387 0 : useraddr += sizeof(*per_queue_opt);
2388 :
2389 0 : bitmap_from_arr32(queue_mask, per_queue_opt->queue_mask, MAX_NUM_QUEUE);
2390 0 : n_queue = bitmap_weight(queue_mask, MAX_NUM_QUEUE);
2391 0 : tmp = backup = kmalloc_array(n_queue, sizeof(*backup), GFP_KERNEL);
2392 0 : if (!backup)
2393 : return -ENOMEM;
2394 :
2395 0 : for_each_set_bit(bit, queue_mask, MAX_NUM_QUEUE) {
2396 0 : struct ethtool_coalesce coalesce;
2397 :
2398 0 : ret = dev->ethtool_ops->get_per_queue_coalesce(dev, bit, tmp);
2399 0 : if (ret != 0)
2400 0 : goto roll_back;
2401 :
2402 0 : tmp++;
2403 :
2404 0 : if (copy_from_user(&coalesce, useraddr, sizeof(coalesce))) {
2405 0 : ret = -EFAULT;
2406 0 : goto roll_back;
2407 : }
2408 :
2409 0 : if (!ethtool_set_coalesce_supported(dev, &coalesce)) {
2410 0 : ret = -EOPNOTSUPP;
2411 0 : goto roll_back;
2412 : }
2413 :
2414 0 : ret = dev->ethtool_ops->set_per_queue_coalesce(dev, bit, &coalesce);
2415 0 : if (ret != 0)
2416 0 : goto roll_back;
2417 :
2418 0 : useraddr += sizeof(coalesce);
2419 : }
2420 :
2421 0 : roll_back:
2422 0 : if (ret != 0) {
2423 0 : tmp = backup;
2424 0 : for_each_set_bit(i, queue_mask, bit) {
2425 0 : dev->ethtool_ops->set_per_queue_coalesce(dev, i, tmp);
2426 0 : tmp++;
2427 : }
2428 : }
2429 0 : kfree(backup);
2430 :
2431 0 : return ret;
2432 : }
2433 :
2434 0 : static int noinline_for_stack ethtool_set_per_queue(struct net_device *dev,
2435 : void __user *useraddr, u32 sub_cmd)
2436 : {
2437 0 : struct ethtool_per_queue_op per_queue_opt;
2438 :
2439 0 : if (copy_from_user(&per_queue_opt, useraddr, sizeof(per_queue_opt)))
2440 : return -EFAULT;
2441 :
2442 0 : if (per_queue_opt.sub_command != sub_cmd)
2443 : return -EINVAL;
2444 :
2445 0 : switch (per_queue_opt.sub_command) {
2446 0 : case ETHTOOL_GCOALESCE:
2447 0 : return ethtool_get_per_queue_coalesce(dev, useraddr, &per_queue_opt);
2448 0 : case ETHTOOL_SCOALESCE:
2449 0 : return ethtool_set_per_queue_coalesce(dev, useraddr, &per_queue_opt);
2450 : default:
2451 : return -EOPNOTSUPP;
2452 : }
2453 : }
2454 :
2455 0 : static int ethtool_phy_tunable_valid(const struct ethtool_tunable *tuna)
2456 : {
2457 0 : switch (tuna->id) {
2458 0 : case ETHTOOL_PHY_DOWNSHIFT:
2459 : case ETHTOOL_PHY_FAST_LINK_DOWN:
2460 0 : if (tuna->len != sizeof(u8) ||
2461 : tuna->type_id != ETHTOOL_TUNABLE_U8)
2462 0 : return -EINVAL;
2463 : break;
2464 0 : case ETHTOOL_PHY_EDPD:
2465 0 : if (tuna->len != sizeof(u16) ||
2466 : tuna->type_id != ETHTOOL_TUNABLE_U16)
2467 0 : return -EINVAL;
2468 : break;
2469 : default:
2470 : return -EINVAL;
2471 : }
2472 :
2473 : return 0;
2474 : }
2475 :
2476 0 : static int get_phy_tunable(struct net_device *dev, void __user *useraddr)
2477 : {
2478 0 : struct phy_device *phydev = dev->phydev;
2479 0 : struct ethtool_tunable tuna;
2480 0 : bool phy_drv_tunable;
2481 0 : void *data;
2482 0 : int ret;
2483 :
2484 0 : phy_drv_tunable = phydev && phydev->drv && phydev->drv->get_tunable;
2485 0 : if (!phy_drv_tunable && !dev->ethtool_ops->get_phy_tunable)
2486 : return -EOPNOTSUPP;
2487 0 : if (copy_from_user(&tuna, useraddr, sizeof(tuna)))
2488 : return -EFAULT;
2489 0 : ret = ethtool_phy_tunable_valid(&tuna);
2490 0 : if (ret)
2491 : return ret;
2492 0 : data = kmalloc(tuna.len, GFP_USER);
2493 0 : if (!data)
2494 : return -ENOMEM;
2495 0 : if (phy_drv_tunable) {
2496 0 : mutex_lock(&phydev->lock);
2497 0 : ret = phydev->drv->get_tunable(phydev, &tuna, data);
2498 0 : mutex_unlock(&phydev->lock);
2499 : } else {
2500 0 : ret = dev->ethtool_ops->get_phy_tunable(dev, &tuna, data);
2501 : }
2502 0 : if (ret)
2503 0 : goto out;
2504 0 : useraddr += sizeof(tuna);
2505 0 : ret = -EFAULT;
2506 0 : if (copy_to_user(useraddr, data, tuna.len))
2507 0 : goto out;
2508 : ret = 0;
2509 :
2510 0 : out:
2511 0 : kfree(data);
2512 0 : return ret;
2513 : }
2514 :
2515 0 : static int set_phy_tunable(struct net_device *dev, void __user *useraddr)
2516 : {
2517 0 : struct phy_device *phydev = dev->phydev;
2518 0 : struct ethtool_tunable tuna;
2519 0 : bool phy_drv_tunable;
2520 0 : void *data;
2521 0 : int ret;
2522 :
2523 0 : phy_drv_tunable = phydev && phydev->drv && phydev->drv->get_tunable;
2524 0 : if (!phy_drv_tunable && !dev->ethtool_ops->set_phy_tunable)
2525 : return -EOPNOTSUPP;
2526 0 : if (copy_from_user(&tuna, useraddr, sizeof(tuna)))
2527 : return -EFAULT;
2528 0 : ret = ethtool_phy_tunable_valid(&tuna);
2529 0 : if (ret)
2530 : return ret;
2531 0 : useraddr += sizeof(tuna);
2532 0 : data = memdup_user(useraddr, tuna.len);
2533 0 : if (IS_ERR(data))
2534 0 : return PTR_ERR(data);
2535 0 : if (phy_drv_tunable) {
2536 0 : mutex_lock(&phydev->lock);
2537 0 : ret = phydev->drv->set_tunable(phydev, &tuna, data);
2538 0 : mutex_unlock(&phydev->lock);
2539 : } else {
2540 0 : ret = dev->ethtool_ops->set_phy_tunable(dev, &tuna, data);
2541 : }
2542 :
2543 0 : kfree(data);
2544 0 : return ret;
2545 : }
2546 :
2547 0 : static int ethtool_get_fecparam(struct net_device *dev, void __user *useraddr)
2548 : {
2549 0 : struct ethtool_fecparam fecparam = { .cmd = ETHTOOL_GFECPARAM };
2550 0 : int rc;
2551 :
2552 0 : if (!dev->ethtool_ops->get_fecparam)
2553 : return -EOPNOTSUPP;
2554 :
2555 0 : rc = dev->ethtool_ops->get_fecparam(dev, &fecparam);
2556 0 : if (rc)
2557 : return rc;
2558 :
2559 0 : if (copy_to_user(useraddr, &fecparam, sizeof(fecparam)))
2560 0 : return -EFAULT;
2561 : return 0;
2562 : }
2563 :
2564 0 : static int ethtool_set_fecparam(struct net_device *dev, void __user *useraddr)
2565 : {
2566 0 : struct ethtool_fecparam fecparam;
2567 :
2568 0 : if (!dev->ethtool_ops->set_fecparam)
2569 : return -EOPNOTSUPP;
2570 :
2571 0 : if (copy_from_user(&fecparam, useraddr, sizeof(fecparam)))
2572 : return -EFAULT;
2573 :
2574 0 : return dev->ethtool_ops->set_fecparam(dev, &fecparam);
2575 : }
2576 :
2577 : /* The main entry point in this file. Called from net/core/dev_ioctl.c */
2578 :
2579 8 : int dev_ethtool(struct net *net, struct ifreq *ifr)
2580 : {
2581 8 : struct net_device *dev = __dev_get_by_name(net, ifr->ifr_name);
2582 8 : void __user *useraddr = ifr->ifr_data;
2583 8 : u32 ethcmd, sub_cmd;
2584 8 : int rc;
2585 8 : netdev_features_t old_features;
2586 :
2587 16 : if (!dev || !netif_device_present(dev))
2588 0 : return -ENODEV;
2589 :
2590 8 : if (copy_from_user(ðcmd, useraddr, sizeof(ethcmd)))
2591 : return -EFAULT;
2592 :
2593 8 : if (ethcmd == ETHTOOL_PERQUEUE) {
2594 0 : if (copy_from_user(&sub_cmd, useraddr + sizeof(ethcmd), sizeof(sub_cmd)))
2595 : return -EFAULT;
2596 : } else {
2597 8 : sub_cmd = ethcmd;
2598 : }
2599 : /* Allow some commands to be done by anyone */
2600 8 : switch (sub_cmd) {
2601 : case ETHTOOL_GSET:
2602 : case ETHTOOL_GDRVINFO:
2603 : case ETHTOOL_GMSGLVL:
2604 : case ETHTOOL_GLINK:
2605 : case ETHTOOL_GCOALESCE:
2606 : case ETHTOOL_GRINGPARAM:
2607 : case ETHTOOL_GPAUSEPARAM:
2608 : case ETHTOOL_GRXCSUM:
2609 : case ETHTOOL_GTXCSUM:
2610 : case ETHTOOL_GSG:
2611 : case ETHTOOL_GSSET_INFO:
2612 : case ETHTOOL_GSTRINGS:
2613 : case ETHTOOL_GSTATS:
2614 : case ETHTOOL_GPHYSTATS:
2615 : case ETHTOOL_GTSO:
2616 : case ETHTOOL_GPERMADDR:
2617 : case ETHTOOL_GUFO:
2618 : case ETHTOOL_GGSO:
2619 : case ETHTOOL_GGRO:
2620 : case ETHTOOL_GFLAGS:
2621 : case ETHTOOL_GPFLAGS:
2622 : case ETHTOOL_GRXFH:
2623 : case ETHTOOL_GRXRINGS:
2624 : case ETHTOOL_GRXCLSRLCNT:
2625 : case ETHTOOL_GRXCLSRULE:
2626 : case ETHTOOL_GRXCLSRLALL:
2627 : case ETHTOOL_GRXFHINDIR:
2628 : case ETHTOOL_GRSSH:
2629 : case ETHTOOL_GFEATURES:
2630 : case ETHTOOL_GCHANNELS:
2631 : case ETHTOOL_GET_TS_INFO:
2632 : case ETHTOOL_GEEE:
2633 : case ETHTOOL_GTUNABLE:
2634 : case ETHTOOL_PHY_GTUNABLE:
2635 : case ETHTOOL_GLINKSETTINGS:
2636 : case ETHTOOL_GFECPARAM:
2637 : break;
2638 2 : default:
2639 2 : if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
2640 : return -EPERM;
2641 : }
2642 :
2643 8 : if (dev->ethtool_ops->begin) {
2644 0 : rc = dev->ethtool_ops->begin(dev);
2645 0 : if (rc < 0)
2646 : return rc;
2647 : }
2648 8 : old_features = dev->features;
2649 :
2650 8 : switch (ethcmd) {
2651 0 : case ETHTOOL_GSET:
2652 0 : rc = ethtool_get_settings(dev, useraddr);
2653 0 : break;
2654 0 : case ETHTOOL_SSET:
2655 0 : rc = ethtool_set_settings(dev, useraddr);
2656 0 : break;
2657 2 : case ETHTOOL_GDRVINFO:
2658 2 : rc = ethtool_get_drvinfo(dev, useraddr);
2659 2 : break;
2660 0 : case ETHTOOL_GREGS:
2661 0 : rc = ethtool_get_regs(dev, useraddr);
2662 0 : break;
2663 0 : case ETHTOOL_GWOL:
2664 0 : rc = ethtool_get_wol(dev, useraddr);
2665 0 : break;
2666 0 : case ETHTOOL_SWOL:
2667 0 : rc = ethtool_set_wol(dev, useraddr);
2668 0 : break;
2669 0 : case ETHTOOL_GMSGLVL:
2670 0 : rc = ethtool_get_value(dev, useraddr, ethcmd,
2671 0 : dev->ethtool_ops->get_msglevel);
2672 0 : break;
2673 0 : case ETHTOOL_SMSGLVL:
2674 0 : rc = ethtool_set_value_void(dev, useraddr,
2675 0 : dev->ethtool_ops->set_msglevel);
2676 0 : if (!rc)
2677 8 : ethtool_notify(dev, ETHTOOL_MSG_DEBUG_NTF, NULL);
2678 : break;
2679 0 : case ETHTOOL_GEEE:
2680 0 : rc = ethtool_get_eee(dev, useraddr);
2681 0 : break;
2682 0 : case ETHTOOL_SEEE:
2683 0 : rc = ethtool_set_eee(dev, useraddr);
2684 0 : break;
2685 : case ETHTOOL_NWAY_RST:
2686 0 : rc = ethtool_nway_reset(dev);
2687 : break;
2688 0 : case ETHTOOL_GLINK:
2689 0 : rc = ethtool_get_link(dev, useraddr);
2690 0 : break;
2691 0 : case ETHTOOL_GEEPROM:
2692 0 : rc = ethtool_get_eeprom(dev, useraddr);
2693 0 : break;
2694 0 : case ETHTOOL_SEEPROM:
2695 0 : rc = ethtool_set_eeprom(dev, useraddr);
2696 0 : break;
2697 0 : case ETHTOOL_GCOALESCE:
2698 0 : rc = ethtool_get_coalesce(dev, useraddr);
2699 0 : break;
2700 0 : case ETHTOOL_SCOALESCE:
2701 0 : rc = ethtool_set_coalesce(dev, useraddr);
2702 0 : break;
2703 0 : case ETHTOOL_GRINGPARAM:
2704 0 : rc = ethtool_get_ringparam(dev, useraddr);
2705 0 : break;
2706 0 : case ETHTOOL_SRINGPARAM:
2707 0 : rc = ethtool_set_ringparam(dev, useraddr);
2708 0 : break;
2709 0 : case ETHTOOL_GPAUSEPARAM:
2710 0 : rc = ethtool_get_pauseparam(dev, useraddr);
2711 0 : break;
2712 0 : case ETHTOOL_SPAUSEPARAM:
2713 0 : rc = ethtool_set_pauseparam(dev, useraddr);
2714 0 : break;
2715 0 : case ETHTOOL_TEST:
2716 0 : rc = ethtool_self_test(dev, useraddr);
2717 0 : break;
2718 2 : case ETHTOOL_GSTRINGS:
2719 2 : rc = ethtool_get_strings(dev, useraddr);
2720 2 : break;
2721 0 : case ETHTOOL_PHYS_ID:
2722 0 : rc = ethtool_phys_id(dev, useraddr);
2723 0 : break;
2724 0 : case ETHTOOL_GSTATS:
2725 0 : rc = ethtool_get_stats(dev, useraddr);
2726 0 : break;
2727 0 : case ETHTOOL_GPERMADDR:
2728 0 : rc = ethtool_get_perm_addr(dev, useraddr);
2729 0 : break;
2730 0 : case ETHTOOL_GFLAGS:
2731 0 : rc = ethtool_get_value(dev, useraddr, ethcmd,
2732 : __ethtool_get_flags);
2733 0 : break;
2734 0 : case ETHTOOL_SFLAGS:
2735 0 : rc = ethtool_set_value(dev, useraddr, __ethtool_set_flags);
2736 0 : break;
2737 0 : case ETHTOOL_GPFLAGS:
2738 0 : rc = ethtool_get_value(dev, useraddr, ethcmd,
2739 0 : dev->ethtool_ops->get_priv_flags);
2740 0 : if (!rc)
2741 8 : ethtool_notify(dev, ETHTOOL_MSG_PRIVFLAGS_NTF, NULL);
2742 : break;
2743 0 : case ETHTOOL_SPFLAGS:
2744 0 : rc = ethtool_set_value(dev, useraddr,
2745 0 : dev->ethtool_ops->set_priv_flags);
2746 0 : break;
2747 0 : case ETHTOOL_GRXFH:
2748 : case ETHTOOL_GRXRINGS:
2749 : case ETHTOOL_GRXCLSRLCNT:
2750 : case ETHTOOL_GRXCLSRULE:
2751 : case ETHTOOL_GRXCLSRLALL:
2752 0 : rc = ethtool_get_rxnfc(dev, ethcmd, useraddr);
2753 0 : break;
2754 0 : case ETHTOOL_SRXFH:
2755 : case ETHTOOL_SRXCLSRLDEL:
2756 : case ETHTOOL_SRXCLSRLINS:
2757 0 : rc = ethtool_set_rxnfc(dev, ethcmd, useraddr);
2758 0 : break;
2759 0 : case ETHTOOL_FLASHDEV:
2760 0 : rc = ethtool_flash_device(dev, useraddr);
2761 0 : break;
2762 0 : case ETHTOOL_RESET:
2763 0 : rc = ethtool_reset(dev, useraddr);
2764 0 : break;
2765 2 : case ETHTOOL_GSSET_INFO:
2766 2 : rc = ethtool_get_sset_info(dev, useraddr);
2767 2 : break;
2768 0 : case ETHTOOL_GRXFHINDIR:
2769 0 : rc = ethtool_get_rxfh_indir(dev, useraddr);
2770 0 : break;
2771 0 : case ETHTOOL_SRXFHINDIR:
2772 0 : rc = ethtool_set_rxfh_indir(dev, useraddr);
2773 0 : break;
2774 0 : case ETHTOOL_GRSSH:
2775 0 : rc = ethtool_get_rxfh(dev, useraddr);
2776 0 : break;
2777 0 : case ETHTOOL_SRSSH:
2778 0 : rc = ethtool_set_rxfh(dev, useraddr);
2779 0 : break;
2780 0 : case ETHTOOL_GFEATURES:
2781 0 : rc = ethtool_get_features(dev, useraddr);
2782 0 : break;
2783 2 : case ETHTOOL_SFEATURES:
2784 2 : rc = ethtool_set_features(dev, useraddr);
2785 2 : break;
2786 0 : case ETHTOOL_GTXCSUM:
2787 : case ETHTOOL_GRXCSUM:
2788 : case ETHTOOL_GSG:
2789 : case ETHTOOL_GTSO:
2790 : case ETHTOOL_GGSO:
2791 : case ETHTOOL_GGRO:
2792 0 : rc = ethtool_get_one_feature(dev, useraddr, ethcmd);
2793 0 : break;
2794 0 : case ETHTOOL_STXCSUM:
2795 : case ETHTOOL_SRXCSUM:
2796 : case ETHTOOL_SSG:
2797 : case ETHTOOL_STSO:
2798 : case ETHTOOL_SGSO:
2799 : case ETHTOOL_SGRO:
2800 0 : rc = ethtool_set_one_feature(dev, useraddr, ethcmd);
2801 0 : break;
2802 0 : case ETHTOOL_GCHANNELS:
2803 0 : rc = ethtool_get_channels(dev, useraddr);
2804 0 : break;
2805 0 : case ETHTOOL_SCHANNELS:
2806 0 : rc = ethtool_set_channels(dev, useraddr);
2807 0 : break;
2808 0 : case ETHTOOL_SET_DUMP:
2809 0 : rc = ethtool_set_dump(dev, useraddr);
2810 0 : break;
2811 0 : case ETHTOOL_GET_DUMP_FLAG:
2812 0 : rc = ethtool_get_dump_flag(dev, useraddr);
2813 0 : break;
2814 0 : case ETHTOOL_GET_DUMP_DATA:
2815 0 : rc = ethtool_get_dump_data(dev, useraddr);
2816 0 : break;
2817 0 : case ETHTOOL_GET_TS_INFO:
2818 0 : rc = ethtool_get_ts_info(dev, useraddr);
2819 0 : break;
2820 0 : case ETHTOOL_GMODULEINFO:
2821 0 : rc = ethtool_get_module_info(dev, useraddr);
2822 0 : break;
2823 0 : case ETHTOOL_GMODULEEEPROM:
2824 0 : rc = ethtool_get_module_eeprom(dev, useraddr);
2825 0 : break;
2826 0 : case ETHTOOL_GTUNABLE:
2827 0 : rc = ethtool_get_tunable(dev, useraddr);
2828 0 : break;
2829 0 : case ETHTOOL_STUNABLE:
2830 0 : rc = ethtool_set_tunable(dev, useraddr);
2831 0 : break;
2832 0 : case ETHTOOL_GPHYSTATS:
2833 0 : rc = ethtool_get_phy_stats(dev, useraddr);
2834 0 : break;
2835 0 : case ETHTOOL_PERQUEUE:
2836 0 : rc = ethtool_set_per_queue(dev, useraddr, sub_cmd);
2837 0 : break;
2838 0 : case ETHTOOL_GLINKSETTINGS:
2839 0 : rc = ethtool_get_link_ksettings(dev, useraddr);
2840 0 : break;
2841 0 : case ETHTOOL_SLINKSETTINGS:
2842 0 : rc = ethtool_set_link_ksettings(dev, useraddr);
2843 0 : break;
2844 0 : case ETHTOOL_PHY_GTUNABLE:
2845 0 : rc = get_phy_tunable(dev, useraddr);
2846 0 : break;
2847 0 : case ETHTOOL_PHY_STUNABLE:
2848 0 : rc = set_phy_tunable(dev, useraddr);
2849 0 : break;
2850 0 : case ETHTOOL_GFECPARAM:
2851 0 : rc = ethtool_get_fecparam(dev, useraddr);
2852 0 : break;
2853 0 : case ETHTOOL_SFECPARAM:
2854 0 : rc = ethtool_set_fecparam(dev, useraddr);
2855 0 : break;
2856 : default:
2857 : rc = -EOPNOTSUPP;
2858 : }
2859 :
2860 8 : if (dev->ethtool_ops->complete)
2861 0 : dev->ethtool_ops->complete(dev);
2862 :
2863 8 : if (old_features != dev->features)
2864 0 : netdev_features_change(dev);
2865 :
2866 : return rc;
2867 : }
2868 :
2869 : struct ethtool_rx_flow_key {
2870 : struct flow_dissector_key_basic basic;
2871 : union {
2872 : struct flow_dissector_key_ipv4_addrs ipv4;
2873 : struct flow_dissector_key_ipv6_addrs ipv6;
2874 : };
2875 : struct flow_dissector_key_ports tp;
2876 : struct flow_dissector_key_ip ip;
2877 : struct flow_dissector_key_vlan vlan;
2878 : struct flow_dissector_key_eth_addrs eth_addrs;
2879 : } __aligned(BITS_PER_LONG / 8); /* Ensure that we can do comparisons as longs. */
2880 :
2881 : struct ethtool_rx_flow_match {
2882 : struct flow_dissector dissector;
2883 : struct ethtool_rx_flow_key key;
2884 : struct ethtool_rx_flow_key mask;
2885 : };
2886 :
2887 : struct ethtool_rx_flow_rule *
2888 0 : ethtool_rx_flow_rule_create(const struct ethtool_rx_flow_spec_input *input)
2889 : {
2890 0 : const struct ethtool_rx_flow_spec *fs = input->fs;
2891 0 : static struct in6_addr zero_addr = {};
2892 0 : struct ethtool_rx_flow_match *match;
2893 0 : struct ethtool_rx_flow_rule *flow;
2894 0 : struct flow_action_entry *act;
2895 :
2896 0 : flow = kzalloc(sizeof(struct ethtool_rx_flow_rule) +
2897 : sizeof(struct ethtool_rx_flow_match), GFP_KERNEL);
2898 0 : if (!flow)
2899 0 : return ERR_PTR(-ENOMEM);
2900 :
2901 : /* ethtool_rx supports only one single action per rule. */
2902 0 : flow->rule = flow_rule_alloc(1);
2903 0 : if (!flow->rule) {
2904 0 : kfree(flow);
2905 0 : return ERR_PTR(-ENOMEM);
2906 : }
2907 :
2908 0 : match = (struct ethtool_rx_flow_match *)flow->priv;
2909 0 : flow->rule->match.dissector = &match->dissector;
2910 0 : flow->rule->match.mask = &match->mask;
2911 0 : flow->rule->match.key = &match->key;
2912 :
2913 0 : match->mask.basic.n_proto = htons(0xffff);
2914 :
2915 0 : switch (fs->flow_type & ~(FLOW_EXT | FLOW_MAC_EXT | FLOW_RSS)) {
2916 0 : case ETHER_FLOW: {
2917 0 : const struct ethhdr *ether_spec, *ether_m_spec;
2918 :
2919 0 : ether_spec = &fs->h_u.ether_spec;
2920 0 : ether_m_spec = &fs->m_u.ether_spec;
2921 :
2922 0 : if (!is_zero_ether_addr(ether_m_spec->h_source)) {
2923 0 : ether_addr_copy(match->key.eth_addrs.src,
2924 0 : ether_spec->h_source);
2925 0 : ether_addr_copy(match->mask.eth_addrs.src,
2926 0 : ether_m_spec->h_source);
2927 : }
2928 0 : if (!is_zero_ether_addr(ether_m_spec->h_dest)) {
2929 0 : ether_addr_copy(match->key.eth_addrs.dst,
2930 0 : ether_spec->h_dest);
2931 0 : ether_addr_copy(match->mask.eth_addrs.dst,
2932 0 : ether_m_spec->h_dest);
2933 : }
2934 0 : if (ether_m_spec->h_proto) {
2935 0 : match->key.basic.n_proto = ether_spec->h_proto;
2936 0 : match->mask.basic.n_proto = ether_m_spec->h_proto;
2937 : }
2938 : }
2939 : break;
2940 0 : case TCP_V4_FLOW:
2941 : case UDP_V4_FLOW: {
2942 0 : const struct ethtool_tcpip4_spec *v4_spec, *v4_m_spec;
2943 :
2944 0 : match->key.basic.n_proto = htons(ETH_P_IP);
2945 :
2946 0 : v4_spec = &fs->h_u.tcp_ip4_spec;
2947 0 : v4_m_spec = &fs->m_u.tcp_ip4_spec;
2948 :
2949 0 : if (v4_m_spec->ip4src) {
2950 0 : match->key.ipv4.src = v4_spec->ip4src;
2951 0 : match->mask.ipv4.src = v4_m_spec->ip4src;
2952 : }
2953 0 : if (v4_m_spec->ip4dst) {
2954 0 : match->key.ipv4.dst = v4_spec->ip4dst;
2955 0 : match->mask.ipv4.dst = v4_m_spec->ip4dst;
2956 : }
2957 0 : if (v4_m_spec->ip4src ||
2958 0 : v4_m_spec->ip4dst) {
2959 0 : match->dissector.used_keys |=
2960 : BIT(FLOW_DISSECTOR_KEY_IPV4_ADDRS);
2961 0 : match->dissector.offset[FLOW_DISSECTOR_KEY_IPV4_ADDRS] =
2962 : offsetof(struct ethtool_rx_flow_key, ipv4);
2963 : }
2964 0 : if (v4_m_spec->psrc) {
2965 0 : match->key.tp.src = v4_spec->psrc;
2966 0 : match->mask.tp.src = v4_m_spec->psrc;
2967 : }
2968 0 : if (v4_m_spec->pdst) {
2969 0 : match->key.tp.dst = v4_spec->pdst;
2970 0 : match->mask.tp.dst = v4_m_spec->pdst;
2971 : }
2972 0 : if (v4_m_spec->psrc ||
2973 : v4_m_spec->pdst) {
2974 0 : match->dissector.used_keys |=
2975 : BIT(FLOW_DISSECTOR_KEY_PORTS);
2976 0 : match->dissector.offset[FLOW_DISSECTOR_KEY_PORTS] =
2977 : offsetof(struct ethtool_rx_flow_key, tp);
2978 : }
2979 0 : if (v4_m_spec->tos) {
2980 0 : match->key.ip.tos = v4_spec->tos;
2981 0 : match->mask.ip.tos = v4_m_spec->tos;
2982 0 : match->dissector.used_keys |=
2983 : BIT(FLOW_DISSECTOR_KEY_IP);
2984 0 : match->dissector.offset[FLOW_DISSECTOR_KEY_IP] =
2985 : offsetof(struct ethtool_rx_flow_key, ip);
2986 : }
2987 : }
2988 : break;
2989 0 : case TCP_V6_FLOW:
2990 : case UDP_V6_FLOW: {
2991 0 : const struct ethtool_tcpip6_spec *v6_spec, *v6_m_spec;
2992 :
2993 0 : match->key.basic.n_proto = htons(ETH_P_IPV6);
2994 :
2995 0 : v6_spec = &fs->h_u.tcp_ip6_spec;
2996 0 : v6_m_spec = &fs->m_u.tcp_ip6_spec;
2997 0 : if (memcmp(v6_m_spec->ip6src, &zero_addr, sizeof(zero_addr))) {
2998 0 : memcpy(&match->key.ipv6.src, v6_spec->ip6src,
2999 : sizeof(match->key.ipv6.src));
3000 0 : memcpy(&match->mask.ipv6.src, v6_m_spec->ip6src,
3001 : sizeof(match->mask.ipv6.src));
3002 : }
3003 0 : if (memcmp(v6_m_spec->ip6dst, &zero_addr, sizeof(zero_addr))) {
3004 0 : memcpy(&match->key.ipv6.dst, v6_spec->ip6dst,
3005 : sizeof(match->key.ipv6.dst));
3006 0 : memcpy(&match->mask.ipv6.dst, v6_m_spec->ip6dst,
3007 : sizeof(match->mask.ipv6.dst));
3008 : }
3009 0 : if (memcmp(v6_m_spec->ip6src, &zero_addr, sizeof(zero_addr)) ||
3010 0 : memcmp(v6_m_spec->ip6dst, &zero_addr, sizeof(zero_addr))) {
3011 0 : match->dissector.used_keys |=
3012 : BIT(FLOW_DISSECTOR_KEY_IPV6_ADDRS);
3013 0 : match->dissector.offset[FLOW_DISSECTOR_KEY_IPV6_ADDRS] =
3014 : offsetof(struct ethtool_rx_flow_key, ipv6);
3015 : }
3016 0 : if (v6_m_spec->psrc) {
3017 0 : match->key.tp.src = v6_spec->psrc;
3018 0 : match->mask.tp.src = v6_m_spec->psrc;
3019 : }
3020 0 : if (v6_m_spec->pdst) {
3021 0 : match->key.tp.dst = v6_spec->pdst;
3022 0 : match->mask.tp.dst = v6_m_spec->pdst;
3023 : }
3024 0 : if (v6_m_spec->psrc ||
3025 : v6_m_spec->pdst) {
3026 0 : match->dissector.used_keys |=
3027 : BIT(FLOW_DISSECTOR_KEY_PORTS);
3028 0 : match->dissector.offset[FLOW_DISSECTOR_KEY_PORTS] =
3029 : offsetof(struct ethtool_rx_flow_key, tp);
3030 : }
3031 0 : if (v6_m_spec->tclass) {
3032 0 : match->key.ip.tos = v6_spec->tclass;
3033 0 : match->mask.ip.tos = v6_m_spec->tclass;
3034 0 : match->dissector.used_keys |=
3035 : BIT(FLOW_DISSECTOR_KEY_IP);
3036 0 : match->dissector.offset[FLOW_DISSECTOR_KEY_IP] =
3037 : offsetof(struct ethtool_rx_flow_key, ip);
3038 : }
3039 : }
3040 : break;
3041 0 : default:
3042 0 : ethtool_rx_flow_rule_destroy(flow);
3043 0 : return ERR_PTR(-EINVAL);
3044 : }
3045 :
3046 0 : switch (fs->flow_type & ~(FLOW_EXT | FLOW_MAC_EXT | FLOW_RSS)) {
3047 0 : case TCP_V4_FLOW:
3048 : case TCP_V6_FLOW:
3049 0 : match->key.basic.ip_proto = IPPROTO_TCP;
3050 0 : match->mask.basic.ip_proto = 0xff;
3051 0 : break;
3052 0 : case UDP_V4_FLOW:
3053 : case UDP_V6_FLOW:
3054 0 : match->key.basic.ip_proto = IPPROTO_UDP;
3055 0 : match->mask.basic.ip_proto = 0xff;
3056 0 : break;
3057 : }
3058 :
3059 0 : match->dissector.used_keys |= BIT(FLOW_DISSECTOR_KEY_BASIC);
3060 0 : match->dissector.offset[FLOW_DISSECTOR_KEY_BASIC] =
3061 : offsetof(struct ethtool_rx_flow_key, basic);
3062 :
3063 0 : if (fs->flow_type & FLOW_EXT) {
3064 0 : const struct ethtool_flow_ext *ext_h_spec = &fs->h_ext;
3065 0 : const struct ethtool_flow_ext *ext_m_spec = &fs->m_ext;
3066 :
3067 0 : if (ext_m_spec->vlan_etype) {
3068 0 : match->key.vlan.vlan_tpid = ext_h_spec->vlan_etype;
3069 0 : match->mask.vlan.vlan_tpid = ext_m_spec->vlan_etype;
3070 : }
3071 :
3072 0 : if (ext_m_spec->vlan_tci) {
3073 0 : match->key.vlan.vlan_id =
3074 0 : ntohs(ext_h_spec->vlan_tci) & 0x0fff;
3075 0 : match->mask.vlan.vlan_id =
3076 0 : ntohs(ext_m_spec->vlan_tci) & 0x0fff;
3077 :
3078 0 : match->key.vlan.vlan_dei =
3079 0 : !!(ext_h_spec->vlan_tci & htons(0x1000));
3080 0 : match->mask.vlan.vlan_dei =
3081 0 : !!(ext_m_spec->vlan_tci & htons(0x1000));
3082 :
3083 0 : match->key.vlan.vlan_priority =
3084 0 : (ntohs(ext_h_spec->vlan_tci) & 0xe000) >> 13;
3085 0 : match->mask.vlan.vlan_priority =
3086 0 : (ntohs(ext_m_spec->vlan_tci) & 0xe000) >> 13;
3087 : }
3088 :
3089 0 : if (ext_m_spec->vlan_etype ||
3090 : ext_m_spec->vlan_tci) {
3091 0 : match->dissector.used_keys |=
3092 : BIT(FLOW_DISSECTOR_KEY_VLAN);
3093 0 : match->dissector.offset[FLOW_DISSECTOR_KEY_VLAN] =
3094 : offsetof(struct ethtool_rx_flow_key, vlan);
3095 : }
3096 : }
3097 0 : if (fs->flow_type & FLOW_MAC_EXT) {
3098 0 : const struct ethtool_flow_ext *ext_h_spec = &fs->h_ext;
3099 0 : const struct ethtool_flow_ext *ext_m_spec = &fs->m_ext;
3100 :
3101 0 : memcpy(match->key.eth_addrs.dst, ext_h_spec->h_dest,
3102 : ETH_ALEN);
3103 0 : memcpy(match->mask.eth_addrs.dst, ext_m_spec->h_dest,
3104 : ETH_ALEN);
3105 :
3106 0 : match->dissector.used_keys |=
3107 : BIT(FLOW_DISSECTOR_KEY_ETH_ADDRS);
3108 0 : match->dissector.offset[FLOW_DISSECTOR_KEY_ETH_ADDRS] =
3109 : offsetof(struct ethtool_rx_flow_key, eth_addrs);
3110 : }
3111 :
3112 0 : act = &flow->rule->action.entries[0];
3113 0 : switch (fs->ring_cookie) {
3114 0 : case RX_CLS_FLOW_DISC:
3115 0 : act->id = FLOW_ACTION_DROP;
3116 0 : break;
3117 0 : case RX_CLS_FLOW_WAKE:
3118 0 : act->id = FLOW_ACTION_WAKE;
3119 0 : break;
3120 0 : default:
3121 0 : act->id = FLOW_ACTION_QUEUE;
3122 0 : if (fs->flow_type & FLOW_RSS)
3123 0 : act->queue.ctx = input->rss_ctx;
3124 :
3125 0 : act->queue.vf = ethtool_get_flow_spec_ring_vf(fs->ring_cookie);
3126 0 : act->queue.index = ethtool_get_flow_spec_ring(fs->ring_cookie);
3127 0 : break;
3128 : }
3129 :
3130 : return flow;
3131 : }
3132 : EXPORT_SYMBOL(ethtool_rx_flow_rule_create);
3133 :
3134 0 : void ethtool_rx_flow_rule_destroy(struct ethtool_rx_flow_rule *flow)
3135 : {
3136 0 : kfree(flow->rule);
3137 0 : kfree(flow);
3138 0 : }
3139 : EXPORT_SYMBOL(ethtool_rx_flow_rule_destroy);
|