aboutsummaryrefslogtreecommitdiffstats
path: root/net/core/ethtool.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/core/ethtool.c')
-rw-r--r--net/core/ethtool.c927
1 files changed, 727 insertions, 200 deletions
diff --git a/net/core/ethtool.c b/net/core/ethtool.c
index 8451ab481095..fd14116ad7f0 100644
--- a/net/core/ethtool.c
+++ b/net/core/ethtool.c
@@ -19,7 +19,10 @@
19#include <linux/netdevice.h> 19#include <linux/netdevice.h>
20#include <linux/bitops.h> 20#include <linux/bitops.h>
21#include <linux/uaccess.h> 21#include <linux/uaccess.h>
22#include <linux/vmalloc.h>
22#include <linux/slab.h> 23#include <linux/slab.h>
24#include <linux/rtnetlink.h>
25#include <linux/sched.h>
23 26
24/* 27/*
25 * Some useful ethtool_ops methods that're device independent. 28 * Some useful ethtool_ops methods that're device independent.
@@ -33,12 +36,6 @@ u32 ethtool_op_get_link(struct net_device *dev)
33} 36}
34EXPORT_SYMBOL(ethtool_op_get_link); 37EXPORT_SYMBOL(ethtool_op_get_link);
35 38
36u32 ethtool_op_get_rx_csum(struct net_device *dev)
37{
38 return (dev->features & NETIF_F_ALL_CSUM) != 0;
39}
40EXPORT_SYMBOL(ethtool_op_get_rx_csum);
41
42u32 ethtool_op_get_tx_csum(struct net_device *dev) 39u32 ethtool_op_get_tx_csum(struct net_device *dev)
43{ 40{
44 return (dev->features & NETIF_F_ALL_CSUM) != 0; 41 return (dev->features & NETIF_F_ALL_CSUM) != 0;
@@ -54,6 +51,7 @@ int ethtool_op_set_tx_csum(struct net_device *dev, u32 data)
54 51
55 return 0; 52 return 0;
56} 53}
54EXPORT_SYMBOL(ethtool_op_set_tx_csum);
57 55
58int ethtool_op_set_tx_hw_csum(struct net_device *dev, u32 data) 56int ethtool_op_set_tx_hw_csum(struct net_device *dev, u32 data)
59{ 57{
@@ -131,7 +129,8 @@ EXPORT_SYMBOL(ethtool_op_set_ufo);
131 * NETIF_F_xxx values in include/linux/netdevice.h 129 * NETIF_F_xxx values in include/linux/netdevice.h
132 */ 130 */
133static const u32 flags_dup_features = 131static const u32 flags_dup_features =
134 (ETH_FLAG_LRO | ETH_FLAG_NTUPLE | ETH_FLAG_RXHASH); 132 (ETH_FLAG_LRO | ETH_FLAG_RXVLAN | ETH_FLAG_TXVLAN | ETH_FLAG_NTUPLE |
133 ETH_FLAG_RXHASH);
135 134
136u32 ethtool_op_get_flags(struct net_device *dev) 135u32 ethtool_op_get_flags(struct net_device *dev)
137{ 136{
@@ -144,9 +143,24 @@ u32 ethtool_op_get_flags(struct net_device *dev)
144} 143}
145EXPORT_SYMBOL(ethtool_op_get_flags); 144EXPORT_SYMBOL(ethtool_op_get_flags);
146 145
146/* Check if device can enable (or disable) particular feature coded in "data"
147 * argument. Flags "supported" describe features that can be toggled by device.
148 * If feature can not be toggled, it state (enabled or disabled) must match
149 * hardcoded device features state, otherwise flags are marked as invalid.
150 */
151bool ethtool_invalid_flags(struct net_device *dev, u32 data, u32 supported)
152{
153 u32 features = dev->features & flags_dup_features;
154 /* "data" can contain only flags_dup_features bits,
155 * see __ethtool_set_flags */
156
157 return (features & ~supported) != (data & ~supported);
158}
159EXPORT_SYMBOL(ethtool_invalid_flags);
160
147int ethtool_op_set_flags(struct net_device *dev, u32 data, u32 supported) 161int ethtool_op_set_flags(struct net_device *dev, u32 data, u32 supported)
148{ 162{
149 if (data & ~supported) 163 if (ethtool_invalid_flags(dev, data, supported))
150 return -EINVAL; 164 return -EINVAL;
151 165
152 dev->features = ((dev->features & ~flags_dup_features) | 166 dev->features = ((dev->features & ~flags_dup_features) |
@@ -169,6 +183,404 @@ EXPORT_SYMBOL(ethtool_ntuple_flush);
169 183
170/* Handlers for each ethtool command */ 184/* Handlers for each ethtool command */
171 185
186#define ETHTOOL_DEV_FEATURE_WORDS 1
187
188static void ethtool_get_features_compat(struct net_device *dev,
189 struct ethtool_get_features_block *features)
190{
191 if (!dev->ethtool_ops)
192 return;
193
194 /* getting RX checksum */
195 if (dev->ethtool_ops->get_rx_csum)
196 if (dev->ethtool_ops->get_rx_csum(dev))
197 features[0].active |= NETIF_F_RXCSUM;
198
199 /* mark legacy-changeable features */
200 if (dev->ethtool_ops->set_sg)
201 features[0].available |= NETIF_F_SG;
202 if (dev->ethtool_ops->set_tx_csum)
203 features[0].available |= NETIF_F_ALL_CSUM;
204 if (dev->ethtool_ops->set_tso)
205 features[0].available |= NETIF_F_ALL_TSO;
206 if (dev->ethtool_ops->set_rx_csum)
207 features[0].available |= NETIF_F_RXCSUM;
208 if (dev->ethtool_ops->set_flags)
209 features[0].available |= flags_dup_features;
210}
211
212static int ethtool_set_feature_compat(struct net_device *dev,
213 int (*legacy_set)(struct net_device *, u32),
214 struct ethtool_set_features_block *features, u32 mask)
215{
216 u32 do_set;
217
218 if (!legacy_set)
219 return 0;
220
221 if (!(features[0].valid & mask))
222 return 0;
223
224 features[0].valid &= ~mask;
225
226 do_set = !!(features[0].requested & mask);
227
228 if (legacy_set(dev, do_set) < 0)
229 netdev_info(dev,
230 "Legacy feature change (%s) failed for 0x%08x\n",
231 do_set ? "set" : "clear", mask);
232
233 return 1;
234}
235
236static int ethtool_set_flags_compat(struct net_device *dev,
237 int (*legacy_set)(struct net_device *, u32),
238 struct ethtool_set_features_block *features, u32 mask)
239{
240 u32 value;
241
242 if (!legacy_set)
243 return 0;
244
245 if (!(features[0].valid & mask))
246 return 0;
247
248 value = dev->features & ~features[0].valid;
249 value |= features[0].requested;
250
251 features[0].valid &= ~mask;
252
253 if (legacy_set(dev, value & mask) < 0)
254 netdev_info(dev, "Legacy flags change failed\n");
255
256 return 1;
257}
258
259static int ethtool_set_features_compat(struct net_device *dev,
260 struct ethtool_set_features_block *features)
261{
262 int compat;
263
264 if (!dev->ethtool_ops)
265 return 0;
266
267 compat = ethtool_set_feature_compat(dev, dev->ethtool_ops->set_sg,
268 features, NETIF_F_SG);
269 compat |= ethtool_set_feature_compat(dev, dev->ethtool_ops->set_tx_csum,
270 features, NETIF_F_ALL_CSUM);
271 compat |= ethtool_set_feature_compat(dev, dev->ethtool_ops->set_tso,
272 features, NETIF_F_ALL_TSO);
273 compat |= ethtool_set_feature_compat(dev, dev->ethtool_ops->set_rx_csum,
274 features, NETIF_F_RXCSUM);
275 compat |= ethtool_set_flags_compat(dev, dev->ethtool_ops->set_flags,
276 features, flags_dup_features);
277
278 return compat;
279}
280
281static int ethtool_get_features(struct net_device *dev, void __user *useraddr)
282{
283 struct ethtool_gfeatures cmd = {
284 .cmd = ETHTOOL_GFEATURES,
285 .size = ETHTOOL_DEV_FEATURE_WORDS,
286 };
287 struct ethtool_get_features_block features[ETHTOOL_DEV_FEATURE_WORDS] = {
288 {
289 .available = dev->hw_features,
290 .requested = dev->wanted_features,
291 .active = dev->features,
292 .never_changed = NETIF_F_NEVER_CHANGE,
293 },
294 };
295 u32 __user *sizeaddr;
296 u32 copy_size;
297
298 ethtool_get_features_compat(dev, features);
299
300 sizeaddr = useraddr + offsetof(struct ethtool_gfeatures, size);
301 if (get_user(copy_size, sizeaddr))
302 return -EFAULT;
303
304 if (copy_size > ETHTOOL_DEV_FEATURE_WORDS)
305 copy_size = ETHTOOL_DEV_FEATURE_WORDS;
306
307 if (copy_to_user(useraddr, &cmd, sizeof(cmd)))
308 return -EFAULT;
309 useraddr += sizeof(cmd);
310 if (copy_to_user(useraddr, features, copy_size * sizeof(*features)))
311 return -EFAULT;
312
313 return 0;
314}
315
316static int ethtool_set_features(struct net_device *dev, void __user *useraddr)
317{
318 struct ethtool_sfeatures cmd;
319 struct ethtool_set_features_block features[ETHTOOL_DEV_FEATURE_WORDS];
320 int ret = 0;
321
322 if (copy_from_user(&cmd, useraddr, sizeof(cmd)))
323 return -EFAULT;
324 useraddr += sizeof(cmd);
325
326 if (cmd.size != ETHTOOL_DEV_FEATURE_WORDS)
327 return -EINVAL;
328
329 if (copy_from_user(features, useraddr, sizeof(features)))
330 return -EFAULT;
331
332 if (features[0].valid & ~NETIF_F_ETHTOOL_BITS)
333 return -EINVAL;
334
335 if (ethtool_set_features_compat(dev, features))
336 ret |= ETHTOOL_F_COMPAT;
337
338 if (features[0].valid & ~dev->hw_features) {
339 features[0].valid &= dev->hw_features;
340 ret |= ETHTOOL_F_UNSUPPORTED;
341 }
342
343 dev->wanted_features &= ~features[0].valid;
344 dev->wanted_features |= features[0].valid & features[0].requested;
345 __netdev_update_features(dev);
346
347 if ((dev->wanted_features ^ dev->features) & features[0].valid)
348 ret |= ETHTOOL_F_WISH;
349
350 return ret;
351}
352
353static const char netdev_features_strings[ETHTOOL_DEV_FEATURE_WORDS * 32][ETH_GSTRING_LEN] = {
354 /* NETIF_F_SG */ "tx-scatter-gather",
355 /* NETIF_F_IP_CSUM */ "tx-checksum-ipv4",
356 /* NETIF_F_NO_CSUM */ "tx-checksum-unneeded",
357 /* NETIF_F_HW_CSUM */ "tx-checksum-ip-generic",
358 /* NETIF_F_IPV6_CSUM */ "tx-checksum-ipv6",
359 /* NETIF_F_HIGHDMA */ "highdma",
360 /* NETIF_F_FRAGLIST */ "tx-scatter-gather-fraglist",
361 /* NETIF_F_HW_VLAN_TX */ "tx-vlan-hw-insert",
362
363 /* NETIF_F_HW_VLAN_RX */ "rx-vlan-hw-parse",
364 /* NETIF_F_HW_VLAN_FILTER */ "rx-vlan-filter",
365 /* NETIF_F_VLAN_CHALLENGED */ "vlan-challenged",
366 /* NETIF_F_GSO */ "tx-generic-segmentation",
367 /* NETIF_F_LLTX */ "tx-lockless",
368 /* NETIF_F_NETNS_LOCAL */ "netns-local",
369 /* NETIF_F_GRO */ "rx-gro",
370 /* NETIF_F_LRO */ "rx-lro",
371
372 /* NETIF_F_TSO */ "tx-tcp-segmentation",
373 /* NETIF_F_UFO */ "tx-udp-fragmentation",
374 /* NETIF_F_GSO_ROBUST */ "tx-gso-robust",
375 /* NETIF_F_TSO_ECN */ "tx-tcp-ecn-segmentation",
376 /* NETIF_F_TSO6 */ "tx-tcp6-segmentation",
377 /* NETIF_F_FSO */ "tx-fcoe-segmentation",
378 "",
379 "",
380
381 /* NETIF_F_FCOE_CRC */ "tx-checksum-fcoe-crc",
382 /* NETIF_F_SCTP_CSUM */ "tx-checksum-sctp",
383 /* NETIF_F_FCOE_MTU */ "fcoe-mtu",
384 /* NETIF_F_NTUPLE */ "rx-ntuple-filter",
385 /* NETIF_F_RXHASH */ "rx-hashing",
386 /* NETIF_F_RXCSUM */ "rx-checksum",
387 /* NETIF_F_NOCACHE_COPY */ "tx-nocache-copy",
388 /* NETIF_F_LOOPBACK */ "loopback",
389};
390
391static int __ethtool_get_sset_count(struct net_device *dev, int sset)
392{
393 const struct ethtool_ops *ops = dev->ethtool_ops;
394
395 if (sset == ETH_SS_FEATURES)
396 return ARRAY_SIZE(netdev_features_strings);
397
398 if (ops && ops->get_sset_count && ops->get_strings)
399 return ops->get_sset_count(dev, sset);
400 else
401 return -EOPNOTSUPP;
402}
403
404static void __ethtool_get_strings(struct net_device *dev,
405 u32 stringset, u8 *data)
406{
407 const struct ethtool_ops *ops = dev->ethtool_ops;
408
409 if (stringset == ETH_SS_FEATURES)
410 memcpy(data, netdev_features_strings,
411 sizeof(netdev_features_strings));
412 else
413 /* ops->get_strings is valid because checked earlier */
414 ops->get_strings(dev, stringset, data);
415}
416
417static u32 ethtool_get_feature_mask(u32 eth_cmd)
418{
419 /* feature masks of legacy discrete ethtool ops */
420
421 switch (eth_cmd) {
422 case ETHTOOL_GTXCSUM:
423 case ETHTOOL_STXCSUM:
424 return NETIF_F_ALL_CSUM | NETIF_F_SCTP_CSUM;
425 case ETHTOOL_GRXCSUM:
426 case ETHTOOL_SRXCSUM:
427 return NETIF_F_RXCSUM;
428 case ETHTOOL_GSG:
429 case ETHTOOL_SSG:
430 return NETIF_F_SG;
431 case ETHTOOL_GTSO:
432 case ETHTOOL_STSO:
433 return NETIF_F_ALL_TSO;
434 case ETHTOOL_GUFO:
435 case ETHTOOL_SUFO:
436 return NETIF_F_UFO;
437 case ETHTOOL_GGSO:
438 case ETHTOOL_SGSO:
439 return NETIF_F_GSO;
440 case ETHTOOL_GGRO:
441 case ETHTOOL_SGRO:
442 return NETIF_F_GRO;
443 default:
444 BUG();
445 }
446}
447
448static void *__ethtool_get_one_feature_actor(struct net_device *dev, u32 ethcmd)
449{
450 const struct ethtool_ops *ops = dev->ethtool_ops;
451
452 if (!ops)
453 return NULL;
454
455 switch (ethcmd) {
456 case ETHTOOL_GTXCSUM:
457 return ops->get_tx_csum;
458 case ETHTOOL_GRXCSUM:
459 return ops->get_rx_csum;
460 case ETHTOOL_SSG:
461 return ops->get_sg;
462 case ETHTOOL_STSO:
463 return ops->get_tso;
464 case ETHTOOL_SUFO:
465 return ops->get_ufo;
466 default:
467 return NULL;
468 }
469}
470
471static u32 __ethtool_get_rx_csum_oldbug(struct net_device *dev)
472{
473 return !!(dev->features & NETIF_F_ALL_CSUM);
474}
475
476static int ethtool_get_one_feature(struct net_device *dev,
477 char __user *useraddr, u32 ethcmd)
478{
479 u32 mask = ethtool_get_feature_mask(ethcmd);
480 struct ethtool_value edata = {
481 .cmd = ethcmd,
482 .data = !!(dev->features & mask),
483 };
484
485 /* compatibility with discrete get_ ops */
486 if (!(dev->hw_features & mask)) {
487 u32 (*actor)(struct net_device *);
488
489 actor = __ethtool_get_one_feature_actor(dev, ethcmd);
490
491 /* bug compatibility with old get_rx_csum */
492 if (ethcmd == ETHTOOL_GRXCSUM && !actor)
493 actor = __ethtool_get_rx_csum_oldbug;
494
495 if (actor)
496 edata.data = actor(dev);
497 }
498
499 if (copy_to_user(useraddr, &edata, sizeof(edata)))
500 return -EFAULT;
501 return 0;
502}
503
504static int __ethtool_set_tx_csum(struct net_device *dev, u32 data);
505static int __ethtool_set_rx_csum(struct net_device *dev, u32 data);
506static int __ethtool_set_sg(struct net_device *dev, u32 data);
507static int __ethtool_set_tso(struct net_device *dev, u32 data);
508static int __ethtool_set_ufo(struct net_device *dev, u32 data);
509
510static int ethtool_set_one_feature(struct net_device *dev,
511 void __user *useraddr, u32 ethcmd)
512{
513 struct ethtool_value edata;
514 u32 mask;
515
516 if (copy_from_user(&edata, useraddr, sizeof(edata)))
517 return -EFAULT;
518
519 mask = ethtool_get_feature_mask(ethcmd);
520 mask &= dev->hw_features;
521 if (mask) {
522 if (edata.data)
523 dev->wanted_features |= mask;
524 else
525 dev->wanted_features &= ~mask;
526
527 __netdev_update_features(dev);
528 return 0;
529 }
530
531 /* Driver is not converted to ndo_fix_features or does not
532 * support changing this offload. In the latter case it won't
533 * have corresponding ethtool_ops field set.
534 *
535 * Following part is to be removed after all drivers advertise
536 * their changeable features in netdev->hw_features and stop
537 * using discrete offload setting ops.
538 */
539
540 switch (ethcmd) {
541 case ETHTOOL_STXCSUM:
542 return __ethtool_set_tx_csum(dev, edata.data);
543 case ETHTOOL_SRXCSUM:
544 return __ethtool_set_rx_csum(dev, edata.data);
545 case ETHTOOL_SSG:
546 return __ethtool_set_sg(dev, edata.data);
547 case ETHTOOL_STSO:
548 return __ethtool_set_tso(dev, edata.data);
549 case ETHTOOL_SUFO:
550 return __ethtool_set_ufo(dev, edata.data);
551 default:
552 return -EOPNOTSUPP;
553 }
554}
555
556int __ethtool_set_flags(struct net_device *dev, u32 data)
557{
558 u32 changed;
559
560 if (data & ~flags_dup_features)
561 return -EINVAL;
562
563 /* legacy set_flags() op */
564 if (dev->ethtool_ops->set_flags) {
565 if (unlikely(dev->hw_features & flags_dup_features))
566 netdev_warn(dev,
567 "driver BUG: mixed hw_features and set_flags()\n");
568 return dev->ethtool_ops->set_flags(dev, data);
569 }
570
571 /* allow changing only bits set in hw_features */
572 changed = (data ^ dev->features) & flags_dup_features;
573 if (changed & ~dev->hw_features)
574 return (changed & dev->hw_features) ? -EINVAL : -EOPNOTSUPP;
575
576 dev->wanted_features =
577 (dev->wanted_features & ~changed) | (data & dev->hw_features);
578
579 __netdev_update_features(dev);
580
581 return 0;
582}
583
172static int ethtool_get_settings(struct net_device *dev, void __user *useraddr) 584static int ethtool_get_settings(struct net_device *dev, void __user *useraddr)
173{ 585{
174 struct ethtool_cmd cmd = { .cmd = ETHTOOL_GSET }; 586 struct ethtool_cmd cmd = { .cmd = ETHTOOL_GSET };
@@ -205,18 +617,24 @@ static noinline_for_stack int ethtool_get_drvinfo(struct net_device *dev,
205 struct ethtool_drvinfo info; 617 struct ethtool_drvinfo info;
206 const struct ethtool_ops *ops = dev->ethtool_ops; 618 const struct ethtool_ops *ops = dev->ethtool_ops;
207 619
208 if (!ops->get_drvinfo)
209 return -EOPNOTSUPP;
210
211 memset(&info, 0, sizeof(info)); 620 memset(&info, 0, sizeof(info));
212 info.cmd = ETHTOOL_GDRVINFO; 621 info.cmd = ETHTOOL_GDRVINFO;
213 ops->get_drvinfo(dev, &info); 622 if (ops && ops->get_drvinfo) {
623 ops->get_drvinfo(dev, &info);
624 } else if (dev->dev.parent && dev->dev.parent->driver) {
625 strlcpy(info.bus_info, dev_name(dev->dev.parent),
626 sizeof(info.bus_info));
627 strlcpy(info.driver, dev->dev.parent->driver->name,
628 sizeof(info.driver));
629 } else {
630 return -EOPNOTSUPP;
631 }
214 632
215 /* 633 /*
216 * this method of obtaining string set info is deprecated; 634 * this method of obtaining string set info is deprecated;
217 * Use ETHTOOL_GSSET_INFO instead. 635 * Use ETHTOOL_GSSET_INFO instead.
218 */ 636 */
219 if (ops->get_sset_count) { 637 if (ops && ops->get_sset_count) {
220 int rc; 638 int rc;
221 639
222 rc = ops->get_sset_count(dev, ETH_SS_TEST); 640 rc = ops->get_sset_count(dev, ETH_SS_TEST);
@@ -229,9 +647,9 @@ static noinline_for_stack int ethtool_get_drvinfo(struct net_device *dev,
229 if (rc >= 0) 647 if (rc >= 0)
230 info.n_priv_flags = rc; 648 info.n_priv_flags = rc;
231 } 649 }
232 if (ops->get_regs_len) 650 if (ops && ops->get_regs_len)
233 info.regdump_len = ops->get_regs_len(dev); 651 info.regdump_len = ops->get_regs_len(dev);
234 if (ops->get_eeprom_len) 652 if (ops && ops->get_eeprom_len)
235 info.eedump_len = ops->get_eeprom_len(dev); 653 info.eedump_len = ops->get_eeprom_len(dev);
236 654
237 if (copy_to_user(useraddr, &info, sizeof(info))) 655 if (copy_to_user(useraddr, &info, sizeof(info)))
@@ -243,14 +661,10 @@ static noinline_for_stack int ethtool_get_sset_info(struct net_device *dev,
243 void __user *useraddr) 661 void __user *useraddr)
244{ 662{
245 struct ethtool_sset_info info; 663 struct ethtool_sset_info info;
246 const struct ethtool_ops *ops = dev->ethtool_ops;
247 u64 sset_mask; 664 u64 sset_mask;
248 int i, idx = 0, n_bits = 0, ret, rc; 665 int i, idx = 0, n_bits = 0, ret, rc;
249 u32 *info_buf = NULL; 666 u32 *info_buf = NULL;
250 667
251 if (!ops->get_sset_count)
252 return -EOPNOTSUPP;
253
254 if (copy_from_user(&info, useraddr, sizeof(info))) 668 if (copy_from_user(&info, useraddr, sizeof(info)))
255 return -EFAULT; 669 return -EFAULT;
256 670
@@ -277,7 +691,7 @@ static noinline_for_stack int ethtool_get_sset_info(struct net_device *dev,
277 if (!(sset_mask & (1ULL << i))) 691 if (!(sset_mask & (1ULL << i)))
278 continue; 692 continue;
279 693
280 rc = ops->get_sset_count(dev, i); 694 rc = __ethtool_get_sset_count(dev, i);
281 if (rc >= 0) { 695 if (rc >= 0) {
282 info.sset_mask |= (1ULL << i); 696 info.sset_mask |= (1ULL << i);
283 info_buf[idx++] = rc; 697 info_buf[idx++] = rc;
@@ -479,6 +893,38 @@ static void __rx_ntuple_filter_add(struct ethtool_rx_ntuple_list *list,
479 list->count++; 893 list->count++;
480} 894}
481 895
896/*
897 * ethtool does not (or did not) set masks for flow parameters that are
898 * not specified, so if both value and mask are 0 then this must be
899 * treated as equivalent to a mask with all bits set. Implement that
900 * here rather than in drivers.
901 */
902static void rx_ntuple_fix_masks(struct ethtool_rx_ntuple_flow_spec *fs)
903{
904 struct ethtool_tcpip4_spec *entry = &fs->h_u.tcp_ip4_spec;
905 struct ethtool_tcpip4_spec *mask = &fs->m_u.tcp_ip4_spec;
906
907 if (fs->flow_type != TCP_V4_FLOW &&
908 fs->flow_type != UDP_V4_FLOW &&
909 fs->flow_type != SCTP_V4_FLOW)
910 return;
911
912 if (!(entry->ip4src | mask->ip4src))
913 mask->ip4src = htonl(0xffffffff);
914 if (!(entry->ip4dst | mask->ip4dst))
915 mask->ip4dst = htonl(0xffffffff);
916 if (!(entry->psrc | mask->psrc))
917 mask->psrc = htons(0xffff);
918 if (!(entry->pdst | mask->pdst))
919 mask->pdst = htons(0xffff);
920 if (!(entry->tos | mask->tos))
921 mask->tos = 0xff;
922 if (!(fs->vlan_tag | fs->vlan_tag_mask))
923 fs->vlan_tag_mask = 0xffff;
924 if (!(fs->data | fs->data_mask))
925 fs->data_mask = 0xffffffffffffffffULL;
926}
927
482static noinline_for_stack int ethtool_set_rx_ntuple(struct net_device *dev, 928static noinline_for_stack int ethtool_set_rx_ntuple(struct net_device *dev,
483 void __user *useraddr) 929 void __user *useraddr)
484{ 930{
@@ -487,12 +933,17 @@ static noinline_for_stack int ethtool_set_rx_ntuple(struct net_device *dev,
487 struct ethtool_rx_ntuple_flow_spec_container *fsc = NULL; 933 struct ethtool_rx_ntuple_flow_spec_container *fsc = NULL;
488 int ret; 934 int ret;
489 935
936 if (!ops->set_rx_ntuple)
937 return -EOPNOTSUPP;
938
490 if (!(dev->features & NETIF_F_NTUPLE)) 939 if (!(dev->features & NETIF_F_NTUPLE))
491 return -EINVAL; 940 return -EINVAL;
492 941
493 if (copy_from_user(&cmd, useraddr, sizeof(cmd))) 942 if (copy_from_user(&cmd, useraddr, sizeof(cmd)))
494 return -EFAULT; 943 return -EFAULT;
495 944
945 rx_ntuple_fix_masks(&cmd.fs);
946
496 /* 947 /*
497 * Cache filter in dev struct for GET operation only if 948 * Cache filter in dev struct for GET operation only if
498 * the underlying driver doesn't have its own GET operation, and 949 * the underlying driver doesn't have its own GET operation, and
@@ -667,19 +1118,19 @@ static int ethtool_get_rx_ntuple(struct net_device *dev, void __user *useraddr)
667 break; 1118 break;
668 case IP_USER_FLOW: 1119 case IP_USER_FLOW:
669 sprintf(p, "\tSrc IP addr: 0x%x\n", 1120 sprintf(p, "\tSrc IP addr: 0x%x\n",
670 fsc->fs.h_u.raw_ip4_spec.ip4src); 1121 fsc->fs.h_u.usr_ip4_spec.ip4src);
671 p += ETH_GSTRING_LEN; 1122 p += ETH_GSTRING_LEN;
672 num_strings++; 1123 num_strings++;
673 sprintf(p, "\tSrc IP mask: 0x%x\n", 1124 sprintf(p, "\tSrc IP mask: 0x%x\n",
674 fsc->fs.m_u.raw_ip4_spec.ip4src); 1125 fsc->fs.m_u.usr_ip4_spec.ip4src);
675 p += ETH_GSTRING_LEN; 1126 p += ETH_GSTRING_LEN;
676 num_strings++; 1127 num_strings++;
677 sprintf(p, "\tDest IP addr: 0x%x\n", 1128 sprintf(p, "\tDest IP addr: 0x%x\n",
678 fsc->fs.h_u.raw_ip4_spec.ip4dst); 1129 fsc->fs.h_u.usr_ip4_spec.ip4dst);
679 p += ETH_GSTRING_LEN; 1130 p += ETH_GSTRING_LEN;
680 num_strings++; 1131 num_strings++;
681 sprintf(p, "\tDest IP mask: 0x%x\n", 1132 sprintf(p, "\tDest IP mask: 0x%x\n",
682 fsc->fs.m_u.raw_ip4_spec.ip4dst); 1133 fsc->fs.m_u.usr_ip4_spec.ip4dst);
683 p += ETH_GSTRING_LEN; 1134 p += ETH_GSTRING_LEN;
684 num_strings++; 1135 num_strings++;
685 break; 1136 break;
@@ -775,7 +1226,7 @@ static int ethtool_get_regs(struct net_device *dev, char __user *useraddr)
775 if (regs.len > reglen) 1226 if (regs.len > reglen)
776 regs.len = reglen; 1227 regs.len = reglen;
777 1228
778 regbuf = kzalloc(reglen, GFP_USER); 1229 regbuf = vzalloc(reglen);
779 if (!regbuf) 1230 if (!regbuf)
780 return -ENOMEM; 1231 return -ENOMEM;
781 1232
@@ -790,7 +1241,7 @@ static int ethtool_get_regs(struct net_device *dev, char __user *useraddr)
790 ret = 0; 1241 ret = 0;
791 1242
792 out: 1243 out:
793 kfree(regbuf); 1244 vfree(regbuf);
794 return ret; 1245 return ret;
795} 1246}
796 1247
@@ -849,6 +1300,20 @@ static int ethtool_nway_reset(struct net_device *dev)
849 return dev->ethtool_ops->nway_reset(dev); 1300 return dev->ethtool_ops->nway_reset(dev);
850} 1301}
851 1302
1303static int ethtool_get_link(struct net_device *dev, char __user *useraddr)
1304{
1305 struct ethtool_value edata = { .cmd = ETHTOOL_GLINK };
1306
1307 if (!dev->ethtool_ops->get_link)
1308 return -EOPNOTSUPP;
1309
1310 edata.data = netif_running(dev) && dev->ethtool_ops->get_link(dev);
1311
1312 if (copy_to_user(useraddr, &edata, sizeof(edata)))
1313 return -EFAULT;
1314 return 0;
1315}
1316
852static int ethtool_get_eeprom(struct net_device *dev, void __user *useraddr) 1317static int ethtool_get_eeprom(struct net_device *dev, void __user *useraddr)
853{ 1318{
854 struct ethtool_eeprom eeprom; 1319 struct ethtool_eeprom eeprom;
@@ -1004,6 +1469,35 @@ static int ethtool_set_ringparam(struct net_device *dev, void __user *useraddr)
1004 return dev->ethtool_ops->set_ringparam(dev, &ringparam); 1469 return dev->ethtool_ops->set_ringparam(dev, &ringparam);
1005} 1470}
1006 1471
1472static noinline_for_stack int ethtool_get_channels(struct net_device *dev,
1473 void __user *useraddr)
1474{
1475 struct ethtool_channels channels = { .cmd = ETHTOOL_GCHANNELS };
1476
1477 if (!dev->ethtool_ops->get_channels)
1478 return -EOPNOTSUPP;
1479
1480 dev->ethtool_ops->get_channels(dev, &channels);
1481
1482 if (copy_to_user(useraddr, &channels, sizeof(channels)))
1483 return -EFAULT;
1484 return 0;
1485}
1486
1487static noinline_for_stack int ethtool_set_channels(struct net_device *dev,
1488 void __user *useraddr)
1489{
1490 struct ethtool_channels channels;
1491
1492 if (!dev->ethtool_ops->set_channels)
1493 return -EOPNOTSUPP;
1494
1495 if (copy_from_user(&channels, useraddr, sizeof(channels)))
1496 return -EFAULT;
1497
1498 return dev->ethtool_ops->set_channels(dev, &channels);
1499}
1500
1007static int ethtool_get_pauseparam(struct net_device *dev, void __user *useraddr) 1501static int ethtool_get_pauseparam(struct net_device *dev, void __user *useraddr)
1008{ 1502{
1009 struct ethtool_pauseparam pauseparam = { ETHTOOL_GPAUSEPARAM }; 1503 struct ethtool_pauseparam pauseparam = { ETHTOOL_GPAUSEPARAM };
@@ -1035,6 +1529,12 @@ static int __ethtool_set_sg(struct net_device *dev, u32 data)
1035{ 1529{
1036 int err; 1530 int err;
1037 1531
1532 if (!dev->ethtool_ops->set_sg)
1533 return -EOPNOTSUPP;
1534
1535 if (data && !(dev->features & NETIF_F_ALL_CSUM))
1536 return -EINVAL;
1537
1038 if (!data && dev->ethtool_ops->set_tso) { 1538 if (!data && dev->ethtool_ops->set_tso) {
1039 err = dev->ethtool_ops->set_tso(dev, 0); 1539 err = dev->ethtool_ops->set_tso(dev, 0);
1040 if (err) 1540 if (err)
@@ -1049,140 +1549,55 @@ static int __ethtool_set_sg(struct net_device *dev, u32 data)
1049 return dev->ethtool_ops->set_sg(dev, data); 1549 return dev->ethtool_ops->set_sg(dev, data);
1050} 1550}
1051 1551
1052static int ethtool_set_tx_csum(struct net_device *dev, char __user *useraddr) 1552static int __ethtool_set_tx_csum(struct net_device *dev, u32 data)
1053{ 1553{
1054 struct ethtool_value edata;
1055 int err; 1554 int err;
1056 1555
1057 if (!dev->ethtool_ops->set_tx_csum) 1556 if (!dev->ethtool_ops->set_tx_csum)
1058 return -EOPNOTSUPP; 1557 return -EOPNOTSUPP;
1059 1558
1060 if (copy_from_user(&edata, useraddr, sizeof(edata))) 1559 if (!data && dev->ethtool_ops->set_sg) {
1061 return -EFAULT;
1062
1063 if (!edata.data && dev->ethtool_ops->set_sg) {
1064 err = __ethtool_set_sg(dev, 0); 1560 err = __ethtool_set_sg(dev, 0);
1065 if (err) 1561 if (err)
1066 return err; 1562 return err;
1067 } 1563 }
1068 1564
1069 return dev->ethtool_ops->set_tx_csum(dev, edata.data); 1565 return dev->ethtool_ops->set_tx_csum(dev, data);
1070} 1566}
1071EXPORT_SYMBOL(ethtool_op_set_tx_csum);
1072 1567
1073static int ethtool_set_rx_csum(struct net_device *dev, char __user *useraddr) 1568static int __ethtool_set_rx_csum(struct net_device *dev, u32 data)
1074{ 1569{
1075 struct ethtool_value edata;
1076
1077 if (!dev->ethtool_ops->set_rx_csum) 1570 if (!dev->ethtool_ops->set_rx_csum)
1078 return -EOPNOTSUPP; 1571 return -EOPNOTSUPP;
1079 1572
1080 if (copy_from_user(&edata, useraddr, sizeof(edata))) 1573 if (!data)
1081 return -EFAULT;
1082
1083 if (!edata.data && dev->ethtool_ops->set_sg)
1084 dev->features &= ~NETIF_F_GRO; 1574 dev->features &= ~NETIF_F_GRO;
1085 1575
1086 return dev->ethtool_ops->set_rx_csum(dev, edata.data); 1576 return dev->ethtool_ops->set_rx_csum(dev, data);
1087} 1577}
1088 1578
1089static int ethtool_set_sg(struct net_device *dev, char __user *useraddr) 1579static int __ethtool_set_tso(struct net_device *dev, u32 data)
1090{ 1580{
1091 struct ethtool_value edata;
1092
1093 if (!dev->ethtool_ops->set_sg)
1094 return -EOPNOTSUPP;
1095
1096 if (copy_from_user(&edata, useraddr, sizeof(edata)))
1097 return -EFAULT;
1098
1099 if (edata.data &&
1100 !(dev->features & NETIF_F_ALL_CSUM))
1101 return -EINVAL;
1102
1103 return __ethtool_set_sg(dev, edata.data);
1104}
1105
1106static int ethtool_set_tso(struct net_device *dev, char __user *useraddr)
1107{
1108 struct ethtool_value edata;
1109
1110 if (!dev->ethtool_ops->set_tso) 1581 if (!dev->ethtool_ops->set_tso)
1111 return -EOPNOTSUPP; 1582 return -EOPNOTSUPP;
1112 1583
1113 if (copy_from_user(&edata, useraddr, sizeof(edata))) 1584 if (data && !(dev->features & NETIF_F_SG))
1114 return -EFAULT;
1115
1116 if (edata.data && !(dev->features & NETIF_F_SG))
1117 return -EINVAL; 1585 return -EINVAL;
1118 1586
1119 return dev->ethtool_ops->set_tso(dev, edata.data); 1587 return dev->ethtool_ops->set_tso(dev, data);
1120} 1588}
1121 1589
1122static int ethtool_set_ufo(struct net_device *dev, char __user *useraddr) 1590static int __ethtool_set_ufo(struct net_device *dev, u32 data)
1123{ 1591{
1124 struct ethtool_value edata;
1125
1126 if (!dev->ethtool_ops->set_ufo) 1592 if (!dev->ethtool_ops->set_ufo)
1127 return -EOPNOTSUPP; 1593 return -EOPNOTSUPP;
1128 if (copy_from_user(&edata, useraddr, sizeof(edata))) 1594 if (data && !(dev->features & NETIF_F_SG))
1129 return -EFAULT;
1130 if (edata.data && !(dev->features & NETIF_F_SG))
1131 return -EINVAL; 1595 return -EINVAL;
1132 if (edata.data && !(dev->features & NETIF_F_HW_CSUM)) 1596 if (data && !((dev->features & NETIF_F_GEN_CSUM) ||
1597 (dev->features & (NETIF_F_IP_CSUM|NETIF_F_IPV6_CSUM))
1598 == (NETIF_F_IP_CSUM|NETIF_F_IPV6_CSUM)))
1133 return -EINVAL; 1599 return -EINVAL;
1134 return dev->ethtool_ops->set_ufo(dev, edata.data); 1600 return dev->ethtool_ops->set_ufo(dev, data);
1135}
1136
1137static int ethtool_get_gso(struct net_device *dev, char __user *useraddr)
1138{
1139 struct ethtool_value edata = { ETHTOOL_GGSO };
1140
1141 edata.data = dev->features & NETIF_F_GSO;
1142 if (copy_to_user(useraddr, &edata, sizeof(edata)))
1143 return -EFAULT;
1144 return 0;
1145}
1146
1147static int ethtool_set_gso(struct net_device *dev, char __user *useraddr)
1148{
1149 struct ethtool_value edata;
1150
1151 if (copy_from_user(&edata, useraddr, sizeof(edata)))
1152 return -EFAULT;
1153 if (edata.data)
1154 dev->features |= NETIF_F_GSO;
1155 else
1156 dev->features &= ~NETIF_F_GSO;
1157 return 0;
1158}
1159
1160static int ethtool_get_gro(struct net_device *dev, char __user *useraddr)
1161{
1162 struct ethtool_value edata = { ETHTOOL_GGRO };
1163
1164 edata.data = dev->features & NETIF_F_GRO;
1165 if (copy_to_user(useraddr, &edata, sizeof(edata)))
1166 return -EFAULT;
1167 return 0;
1168}
1169
1170static int ethtool_set_gro(struct net_device *dev, char __user *useraddr)
1171{
1172 struct ethtool_value edata;
1173
1174 if (copy_from_user(&edata, useraddr, sizeof(edata)))
1175 return -EFAULT;
1176
1177 if (edata.data) {
1178 if (!dev->ethtool_ops->get_rx_csum ||
1179 !dev->ethtool_ops->get_rx_csum(dev))
1180 return -EINVAL;
1181 dev->features |= NETIF_F_GRO;
1182 } else
1183 dev->features &= ~NETIF_F_GRO;
1184
1185 return 0;
1186} 1601}
1187 1602
1188static int ethtool_self_test(struct net_device *dev, char __user *useraddr) 1603static int ethtool_self_test(struct net_device *dev, char __user *useraddr)
@@ -1226,17 +1641,13 @@ static int ethtool_self_test(struct net_device *dev, char __user *useraddr)
1226static int ethtool_get_strings(struct net_device *dev, void __user *useraddr) 1641static int ethtool_get_strings(struct net_device *dev, void __user *useraddr)
1227{ 1642{
1228 struct ethtool_gstrings gstrings; 1643 struct ethtool_gstrings gstrings;
1229 const struct ethtool_ops *ops = dev->ethtool_ops;
1230 u8 *data; 1644 u8 *data;
1231 int ret; 1645 int ret;
1232 1646
1233 if (!ops->get_strings || !ops->get_sset_count)
1234 return -EOPNOTSUPP;
1235
1236 if (copy_from_user(&gstrings, useraddr, sizeof(gstrings))) 1647 if (copy_from_user(&gstrings, useraddr, sizeof(gstrings)))
1237 return -EFAULT; 1648 return -EFAULT;
1238 1649
1239 ret = ops->get_sset_count(dev, gstrings.string_set); 1650 ret = __ethtool_get_sset_count(dev, gstrings.string_set);
1240 if (ret < 0) 1651 if (ret < 0)
1241 return ret; 1652 return ret;
1242 1653
@@ -1246,7 +1657,7 @@ static int ethtool_get_strings(struct net_device *dev, void __user *useraddr)
1246 if (!data) 1657 if (!data)
1247 return -ENOMEM; 1658 return -ENOMEM;
1248 1659
1249 ops->get_strings(dev, gstrings.string_set, data); 1660 __ethtool_get_strings(dev, gstrings.string_set, data);
1250 1661
1251 ret = -EFAULT; 1662 ret = -EFAULT;
1252 if (copy_to_user(useraddr, &gstrings, sizeof(gstrings))) 1663 if (copy_to_user(useraddr, &gstrings, sizeof(gstrings)))
@@ -1256,7 +1667,7 @@ static int ethtool_get_strings(struct net_device *dev, void __user *useraddr)
1256 goto out; 1667 goto out;
1257 ret = 0; 1668 ret = 0;
1258 1669
1259 out: 1670out:
1260 kfree(data); 1671 kfree(data);
1261 return ret; 1672 return ret;
1262} 1673}
@@ -1264,14 +1675,60 @@ static int ethtool_get_strings(struct net_device *dev, void __user *useraddr)
1264static int ethtool_phys_id(struct net_device *dev, void __user *useraddr) 1675static int ethtool_phys_id(struct net_device *dev, void __user *useraddr)
1265{ 1676{
1266 struct ethtool_value id; 1677 struct ethtool_value id;
1678 static bool busy;
1679 int rc;
1267 1680
1268 if (!dev->ethtool_ops->phys_id) 1681 if (!dev->ethtool_ops->set_phys_id)
1269 return -EOPNOTSUPP; 1682 return -EOPNOTSUPP;
1270 1683
1684 if (busy)
1685 return -EBUSY;
1686
1271 if (copy_from_user(&id, useraddr, sizeof(id))) 1687 if (copy_from_user(&id, useraddr, sizeof(id)))
1272 return -EFAULT; 1688 return -EFAULT;
1273 1689
1274 return dev->ethtool_ops->phys_id(dev, id.data); 1690 rc = dev->ethtool_ops->set_phys_id(dev, ETHTOOL_ID_ACTIVE);
1691 if (rc < 0)
1692 return rc;
1693
1694 /* Drop the RTNL lock while waiting, but prevent reentry or
1695 * removal of the device.
1696 */
1697 busy = true;
1698 dev_hold(dev);
1699 rtnl_unlock();
1700
1701 if (rc == 0) {
1702 /* Driver will handle this itself */
1703 schedule_timeout_interruptible(
1704 id.data ? (id.data * HZ) : MAX_SCHEDULE_TIMEOUT);
1705 } else {
1706 /* Driver expects to be called at twice the frequency in rc */
1707 int n = rc * 2, i, interval = HZ / n;
1708
1709 /* Count down seconds */
1710 do {
1711 /* Count down iterations per second */
1712 i = n;
1713 do {
1714 rtnl_lock();
1715 rc = dev->ethtool_ops->set_phys_id(dev,
1716 (i & 1) ? ETHTOOL_ID_OFF : ETHTOOL_ID_ON);
1717 rtnl_unlock();
1718 if (rc)
1719 break;
1720 schedule_timeout_interruptible(interval);
1721 } while (!signal_pending(current) && --i != 0);
1722 } while (!signal_pending(current) &&
1723 (id.data == 0 || --id.data != 0));
1724 }
1725
1726 rtnl_lock();
1727 dev_put(dev);
1728 busy = false;
1729
1730 (void)dev->ethtool_ops->set_phys_id(dev, ETHTOOL_ID_INACTIVE);
1731 return rc;
1275} 1732}
1276 1733
1277static int ethtool_get_stats(struct net_device *dev, void __user *useraddr) 1734static int ethtool_get_stats(struct net_device *dev, void __user *useraddr)
@@ -1389,6 +1846,87 @@ static noinline_for_stack int ethtool_flash_device(struct net_device *dev,
1389 return dev->ethtool_ops->flash_device(dev, &efl); 1846 return dev->ethtool_ops->flash_device(dev, &efl);
1390} 1847}
1391 1848
1849static int ethtool_set_dump(struct net_device *dev,
1850 void __user *useraddr)
1851{
1852 struct ethtool_dump dump;
1853
1854 if (!dev->ethtool_ops->set_dump)
1855 return -EOPNOTSUPP;
1856
1857 if (copy_from_user(&dump, useraddr, sizeof(dump)))
1858 return -EFAULT;
1859
1860 return dev->ethtool_ops->set_dump(dev, &dump);
1861}
1862
1863static int ethtool_get_dump_flag(struct net_device *dev,
1864 void __user *useraddr)
1865{
1866 int ret;
1867 struct ethtool_dump dump;
1868 const struct ethtool_ops *ops = dev->ethtool_ops;
1869
1870 if (!dev->ethtool_ops->get_dump_flag)
1871 return -EOPNOTSUPP;
1872
1873 if (copy_from_user(&dump, useraddr, sizeof(dump)))
1874 return -EFAULT;
1875
1876 ret = ops->get_dump_flag(dev, &dump);
1877 if (ret)
1878 return ret;
1879
1880 if (copy_to_user(useraddr, &dump, sizeof(dump)))
1881 return -EFAULT;
1882 return 0;
1883}
1884
1885static int ethtool_get_dump_data(struct net_device *dev,
1886 void __user *useraddr)
1887{
1888 int ret;
1889 __u32 len;
1890 struct ethtool_dump dump, tmp;
1891 const struct ethtool_ops *ops = dev->ethtool_ops;
1892 void *data = NULL;
1893
1894 if (!dev->ethtool_ops->get_dump_data ||
1895 !dev->ethtool_ops->get_dump_flag)
1896 return -EOPNOTSUPP;
1897
1898 if (copy_from_user(&dump, useraddr, sizeof(dump)))
1899 return -EFAULT;
1900
1901 memset(&tmp, 0, sizeof(tmp));
1902 tmp.cmd = ETHTOOL_GET_DUMP_FLAG;
1903 ret = ops->get_dump_flag(dev, &tmp);
1904 if (ret)
1905 return ret;
1906
1907 len = (tmp.len > dump.len) ? dump.len : tmp.len;
1908 if (!len)
1909 return -EFAULT;
1910
1911 data = vzalloc(tmp.len);
1912 if (!data)
1913 return -ENOMEM;
1914 ret = ops->get_dump_data(dev, &dump, data);
1915 if (ret)
1916 goto out;
1917
1918 if (copy_to_user(useraddr, &dump, sizeof(dump))) {
1919 ret = -EFAULT;
1920 goto out;
1921 }
1922 useraddr += offsetof(struct ethtool_dump, data);
1923 if (copy_to_user(useraddr, data, len))
1924 ret = -EFAULT;
1925out:
1926 vfree(data);
1927 return ret;
1928}
1929
1392/* The main entry point in this file. Called from net/core/dev.c */ 1930/* The main entry point in this file. Called from net/core/dev.c */
1393 1931
1394int dev_ethtool(struct net *net, struct ifreq *ifr) 1932int dev_ethtool(struct net *net, struct ifreq *ifr)
@@ -1397,19 +1935,27 @@ int dev_ethtool(struct net *net, struct ifreq *ifr)
1397 void __user *useraddr = ifr->ifr_data; 1935 void __user *useraddr = ifr->ifr_data;
1398 u32 ethcmd; 1936 u32 ethcmd;
1399 int rc; 1937 int rc;
1400 unsigned long old_features; 1938 u32 old_features;
1401 1939
1402 if (!dev || !netif_device_present(dev)) 1940 if (!dev || !netif_device_present(dev))
1403 return -ENODEV; 1941 return -ENODEV;
1404 1942
1405 if (!dev->ethtool_ops)
1406 return -EOPNOTSUPP;
1407
1408 if (copy_from_user(&ethcmd, useraddr, sizeof(ethcmd))) 1943 if (copy_from_user(&ethcmd, useraddr, sizeof(ethcmd)))
1409 return -EFAULT; 1944 return -EFAULT;
1410 1945
1946 if (!dev->ethtool_ops) {
1947 /* ETHTOOL_GDRVINFO does not require any driver support.
1948 * It is also unprivileged and does not change anything,
1949 * so we can take a shortcut to it. */
1950 if (ethcmd == ETHTOOL_GDRVINFO)
1951 return ethtool_get_drvinfo(dev, useraddr);
1952 else
1953 return -EOPNOTSUPP;
1954 }
1955
1411 /* Allow some commands to be done by anyone */ 1956 /* Allow some commands to be done by anyone */
1412 switch (ethcmd) { 1957 switch (ethcmd) {
1958 case ETHTOOL_GSET:
1413 case ETHTOOL_GDRVINFO: 1959 case ETHTOOL_GDRVINFO:
1414 case ETHTOOL_GMSGLVL: 1960 case ETHTOOL_GMSGLVL:
1415 case ETHTOOL_GCOALESCE: 1961 case ETHTOOL_GCOALESCE:
@@ -1431,6 +1977,7 @@ int dev_ethtool(struct net *net, struct ifreq *ifr)
1431 case ETHTOOL_GRXCLSRLCNT: 1977 case ETHTOOL_GRXCLSRLCNT:
1432 case ETHTOOL_GRXCLSRULE: 1978 case ETHTOOL_GRXCLSRULE:
1433 case ETHTOOL_GRXCLSRLALL: 1979 case ETHTOOL_GRXCLSRLALL:
1980 case ETHTOOL_GFEATURES:
1434 break; 1981 break;
1435 default: 1982 default:
1436 if (!capable(CAP_NET_ADMIN)) 1983 if (!capable(CAP_NET_ADMIN))
@@ -1475,8 +2022,7 @@ int dev_ethtool(struct net *net, struct ifreq *ifr)
1475 rc = ethtool_nway_reset(dev); 2022 rc = ethtool_nway_reset(dev);
1476 break; 2023 break;
1477 case ETHTOOL_GLINK: 2024 case ETHTOOL_GLINK:
1478 rc = ethtool_get_value(dev, useraddr, ethcmd, 2025 rc = ethtool_get_link(dev, useraddr);
1479 dev->ethtool_ops->get_link);
1480 break; 2026 break;
1481 case ETHTOOL_GEEPROM: 2027 case ETHTOOL_GEEPROM:
1482 rc = ethtool_get_eeprom(dev, useraddr); 2028 rc = ethtool_get_eeprom(dev, useraddr);
@@ -1502,42 +2048,6 @@ int dev_ethtool(struct net *net, struct ifreq *ifr)
1502 case ETHTOOL_SPAUSEPARAM: 2048 case ETHTOOL_SPAUSEPARAM:
1503 rc = ethtool_set_pauseparam(dev, useraddr); 2049 rc = ethtool_set_pauseparam(dev, useraddr);
1504 break; 2050 break;
1505 case ETHTOOL_GRXCSUM:
1506 rc = ethtool_get_value(dev, useraddr, ethcmd,
1507 (dev->ethtool_ops->get_rx_csum ?
1508 dev->ethtool_ops->get_rx_csum :
1509 ethtool_op_get_rx_csum));
1510 break;
1511 case ETHTOOL_SRXCSUM:
1512 rc = ethtool_set_rx_csum(dev, useraddr);
1513 break;
1514 case ETHTOOL_GTXCSUM:
1515 rc = ethtool_get_value(dev, useraddr, ethcmd,
1516 (dev->ethtool_ops->get_tx_csum ?
1517 dev->ethtool_ops->get_tx_csum :
1518 ethtool_op_get_tx_csum));
1519 break;
1520 case ETHTOOL_STXCSUM:
1521 rc = ethtool_set_tx_csum(dev, useraddr);
1522 break;
1523 case ETHTOOL_GSG:
1524 rc = ethtool_get_value(dev, useraddr, ethcmd,
1525 (dev->ethtool_ops->get_sg ?
1526 dev->ethtool_ops->get_sg :
1527 ethtool_op_get_sg));
1528 break;
1529 case ETHTOOL_SSG:
1530 rc = ethtool_set_sg(dev, useraddr);
1531 break;
1532 case ETHTOOL_GTSO:
1533 rc = ethtool_get_value(dev, useraddr, ethcmd,
1534 (dev->ethtool_ops->get_tso ?
1535 dev->ethtool_ops->get_tso :
1536 ethtool_op_get_tso));
1537 break;
1538 case ETHTOOL_STSO:
1539 rc = ethtool_set_tso(dev, useraddr);
1540 break;
1541 case ETHTOOL_TEST: 2051 case ETHTOOL_TEST:
1542 rc = ethtool_self_test(dev, useraddr); 2052 rc = ethtool_self_test(dev, useraddr);
1543 break; 2053 break;
@@ -1553,21 +2063,6 @@ int dev_ethtool(struct net *net, struct ifreq *ifr)
1553 case ETHTOOL_GPERMADDR: 2063 case ETHTOOL_GPERMADDR:
1554 rc = ethtool_get_perm_addr(dev, useraddr); 2064 rc = ethtool_get_perm_addr(dev, useraddr);
1555 break; 2065 break;
1556 case ETHTOOL_GUFO:
1557 rc = ethtool_get_value(dev, useraddr, ethcmd,
1558 (dev->ethtool_ops->get_ufo ?
1559 dev->ethtool_ops->get_ufo :
1560 ethtool_op_get_ufo));
1561 break;
1562 case ETHTOOL_SUFO:
1563 rc = ethtool_set_ufo(dev, useraddr);
1564 break;
1565 case ETHTOOL_GGSO:
1566 rc = ethtool_get_gso(dev, useraddr);
1567 break;
1568 case ETHTOOL_SGSO:
1569 rc = ethtool_set_gso(dev, useraddr);
1570 break;
1571 case ETHTOOL_GFLAGS: 2066 case ETHTOOL_GFLAGS:
1572 rc = ethtool_get_value(dev, useraddr, ethcmd, 2067 rc = ethtool_get_value(dev, useraddr, ethcmd,
1573 (dev->ethtool_ops->get_flags ? 2068 (dev->ethtool_ops->get_flags ?
@@ -1575,8 +2070,7 @@ int dev_ethtool(struct net *net, struct ifreq *ifr)
1575 ethtool_op_get_flags)); 2070 ethtool_op_get_flags));
1576 break; 2071 break;
1577 case ETHTOOL_SFLAGS: 2072 case ETHTOOL_SFLAGS:
1578 rc = ethtool_set_value(dev, useraddr, 2073 rc = ethtool_set_value(dev, useraddr, __ethtool_set_flags);
1579 dev->ethtool_ops->set_flags);
1580 break; 2074 break;
1581 case ETHTOOL_GPFLAGS: 2075 case ETHTOOL_GPFLAGS:
1582 rc = ethtool_get_value(dev, useraddr, ethcmd, 2076 rc = ethtool_get_value(dev, useraddr, ethcmd,
@@ -1598,12 +2092,6 @@ int dev_ethtool(struct net *net, struct ifreq *ifr)
1598 case ETHTOOL_SRXCLSRLINS: 2092 case ETHTOOL_SRXCLSRLINS:
1599 rc = ethtool_set_rxnfc(dev, ethcmd, useraddr); 2093 rc = ethtool_set_rxnfc(dev, ethcmd, useraddr);
1600 break; 2094 break;
1601 case ETHTOOL_GGRO:
1602 rc = ethtool_get_gro(dev, useraddr);
1603 break;
1604 case ETHTOOL_SGRO:
1605 rc = ethtool_set_gro(dev, useraddr);
1606 break;
1607 case ETHTOOL_FLASHDEV: 2095 case ETHTOOL_FLASHDEV:
1608 rc = ethtool_flash_device(dev, useraddr); 2096 rc = ethtool_flash_device(dev, useraddr);
1609 break; 2097 break;
@@ -1625,6 +2113,45 @@ int dev_ethtool(struct net *net, struct ifreq *ifr)
1625 case ETHTOOL_SRXFHINDIR: 2113 case ETHTOOL_SRXFHINDIR:
1626 rc = ethtool_set_rxfh_indir(dev, useraddr); 2114 rc = ethtool_set_rxfh_indir(dev, useraddr);
1627 break; 2115 break;
2116 case ETHTOOL_GFEATURES:
2117 rc = ethtool_get_features(dev, useraddr);
2118 break;
2119 case ETHTOOL_SFEATURES:
2120 rc = ethtool_set_features(dev, useraddr);
2121 break;
2122 case ETHTOOL_GTXCSUM:
2123 case ETHTOOL_GRXCSUM:
2124 case ETHTOOL_GSG:
2125 case ETHTOOL_GTSO:
2126 case ETHTOOL_GUFO:
2127 case ETHTOOL_GGSO:
2128 case ETHTOOL_GGRO:
2129 rc = ethtool_get_one_feature(dev, useraddr, ethcmd);
2130 break;
2131 case ETHTOOL_STXCSUM:
2132 case ETHTOOL_SRXCSUM:
2133 case ETHTOOL_SSG:
2134 case ETHTOOL_STSO:
2135 case ETHTOOL_SUFO:
2136 case ETHTOOL_SGSO:
2137 case ETHTOOL_SGRO:
2138 rc = ethtool_set_one_feature(dev, useraddr, ethcmd);
2139 break;
2140 case ETHTOOL_GCHANNELS:
2141 rc = ethtool_get_channels(dev, useraddr);
2142 break;
2143 case ETHTOOL_SCHANNELS:
2144 rc = ethtool_set_channels(dev, useraddr);
2145 break;
2146 case ETHTOOL_SET_DUMP:
2147 rc = ethtool_set_dump(dev, useraddr);
2148 break;
2149 case ETHTOOL_GET_DUMP_FLAG:
2150 rc = ethtool_get_dump_flag(dev, useraddr);
2151 break;
2152 case ETHTOOL_GET_DUMP_DATA:
2153 rc = ethtool_get_dump_data(dev, useraddr);
2154 break;
1628 default: 2155 default:
1629 rc = -EOPNOTSUPP; 2156 rc = -EOPNOTSUPP;
1630 } 2157 }