Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/net/core/ethtool.c
15109 views
1
/*
2
* net/core/ethtool.c - Ethtool ioctl handler
3
* Copyright (c) 2003 Matthew Wilcox <[email protected]>
4
*
5
* This file is where we call all the ethtool_ops commands to get
6
* the information ethtool needs.
7
*
8
* This program is free software; you can redistribute it and/or modify
9
* it under the terms of the GNU General Public License as published by
10
* the Free Software Foundation; either version 2 of the License, or
11
* (at your option) any later version.
12
*/
13
14
#include <linux/module.h>
15
#include <linux/types.h>
16
#include <linux/capability.h>
17
#include <linux/errno.h>
18
#include <linux/ethtool.h>
19
#include <linux/netdevice.h>
20
#include <linux/bitops.h>
21
#include <linux/uaccess.h>
22
#include <linux/vmalloc.h>
23
#include <linux/slab.h>
24
#include <linux/rtnetlink.h>
25
#include <linux/sched.h>
26
27
/*
28
* Some useful ethtool_ops methods that're device independent.
29
* If we find that all drivers want to do the same thing here,
30
* we can turn these into dev_() function calls.
31
*/
32
33
u32 ethtool_op_get_link(struct net_device *dev)
34
{
35
return netif_carrier_ok(dev) ? 1 : 0;
36
}
37
EXPORT_SYMBOL(ethtool_op_get_link);
38
39
u32 ethtool_op_get_tx_csum(struct net_device *dev)
40
{
41
return (dev->features & NETIF_F_ALL_CSUM) != 0;
42
}
43
EXPORT_SYMBOL(ethtool_op_get_tx_csum);
44
45
int ethtool_op_set_tx_csum(struct net_device *dev, u32 data)
46
{
47
if (data)
48
dev->features |= NETIF_F_IP_CSUM;
49
else
50
dev->features &= ~NETIF_F_IP_CSUM;
51
52
return 0;
53
}
54
EXPORT_SYMBOL(ethtool_op_set_tx_csum);
55
56
int ethtool_op_set_tx_hw_csum(struct net_device *dev, u32 data)
57
{
58
if (data)
59
dev->features |= NETIF_F_HW_CSUM;
60
else
61
dev->features &= ~NETIF_F_HW_CSUM;
62
63
return 0;
64
}
65
EXPORT_SYMBOL(ethtool_op_set_tx_hw_csum);
66
67
int ethtool_op_set_tx_ipv6_csum(struct net_device *dev, u32 data)
68
{
69
if (data)
70
dev->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
71
else
72
dev->features &= ~(NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM);
73
74
return 0;
75
}
76
EXPORT_SYMBOL(ethtool_op_set_tx_ipv6_csum);
77
78
u32 ethtool_op_get_sg(struct net_device *dev)
79
{
80
return (dev->features & NETIF_F_SG) != 0;
81
}
82
EXPORT_SYMBOL(ethtool_op_get_sg);
83
84
int ethtool_op_set_sg(struct net_device *dev, u32 data)
85
{
86
if (data)
87
dev->features |= NETIF_F_SG;
88
else
89
dev->features &= ~NETIF_F_SG;
90
91
return 0;
92
}
93
EXPORT_SYMBOL(ethtool_op_set_sg);
94
95
u32 ethtool_op_get_tso(struct net_device *dev)
96
{
97
return (dev->features & NETIF_F_TSO) != 0;
98
}
99
EXPORT_SYMBOL(ethtool_op_get_tso);
100
101
int ethtool_op_set_tso(struct net_device *dev, u32 data)
102
{
103
if (data)
104
dev->features |= NETIF_F_TSO;
105
else
106
dev->features &= ~NETIF_F_TSO;
107
108
return 0;
109
}
110
EXPORT_SYMBOL(ethtool_op_set_tso);
111
112
u32 ethtool_op_get_ufo(struct net_device *dev)
113
{
114
return (dev->features & NETIF_F_UFO) != 0;
115
}
116
EXPORT_SYMBOL(ethtool_op_get_ufo);
117
118
int ethtool_op_set_ufo(struct net_device *dev, u32 data)
119
{
120
if (data)
121
dev->features |= NETIF_F_UFO;
122
else
123
dev->features &= ~NETIF_F_UFO;
124
return 0;
125
}
126
EXPORT_SYMBOL(ethtool_op_set_ufo);
127
128
/* the following list of flags are the same as their associated
129
* NETIF_F_xxx values in include/linux/netdevice.h
130
*/
131
static const u32 flags_dup_features =
132
(ETH_FLAG_LRO | ETH_FLAG_RXVLAN | ETH_FLAG_TXVLAN | ETH_FLAG_NTUPLE |
133
ETH_FLAG_RXHASH);
134
135
u32 ethtool_op_get_flags(struct net_device *dev)
136
{
137
/* in the future, this function will probably contain additional
138
* handling for flags which are not so easily handled
139
* by a simple masking operation
140
*/
141
142
return dev->features & flags_dup_features;
143
}
144
EXPORT_SYMBOL(ethtool_op_get_flags);
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
*/
151
bool 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
}
159
EXPORT_SYMBOL(ethtool_invalid_flags);
160
161
int ethtool_op_set_flags(struct net_device *dev, u32 data, u32 supported)
162
{
163
if (ethtool_invalid_flags(dev, data, supported))
164
return -EINVAL;
165
166
dev->features = ((dev->features & ~flags_dup_features) |
167
(data & flags_dup_features));
168
return 0;
169
}
170
EXPORT_SYMBOL(ethtool_op_set_flags);
171
172
void ethtool_ntuple_flush(struct net_device *dev)
173
{
174
struct ethtool_rx_ntuple_flow_spec_container *fsc, *f;
175
176
list_for_each_entry_safe(fsc, f, &dev->ethtool_ntuple_list.list, list) {
177
list_del(&fsc->list);
178
kfree(fsc);
179
}
180
dev->ethtool_ntuple_list.count = 0;
181
}
182
EXPORT_SYMBOL(ethtool_ntuple_flush);
183
184
/* Handlers for each ethtool command */
185
186
#define ETHTOOL_DEV_FEATURE_WORDS 1
187
188
static 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
212
static 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
236
static 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
259
static 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
281
static 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
316
static 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
353
static 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
391
static 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
404
static 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
417
static 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
448
static 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
471
static u32 __ethtool_get_rx_csum_oldbug(struct net_device *dev)
472
{
473
return !!(dev->features & NETIF_F_ALL_CSUM);
474
}
475
476
static 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
504
static int __ethtool_set_tx_csum(struct net_device *dev, u32 data);
505
static int __ethtool_set_rx_csum(struct net_device *dev, u32 data);
506
static int __ethtool_set_sg(struct net_device *dev, u32 data);
507
static int __ethtool_set_tso(struct net_device *dev, u32 data);
508
static int __ethtool_set_ufo(struct net_device *dev, u32 data);
509
510
static 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
556
int __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
584
static int ethtool_get_settings(struct net_device *dev, void __user *useraddr)
585
{
586
struct ethtool_cmd cmd = { .cmd = ETHTOOL_GSET };
587
int err;
588
589
if (!dev->ethtool_ops->get_settings)
590
return -EOPNOTSUPP;
591
592
err = dev->ethtool_ops->get_settings(dev, &cmd);
593
if (err < 0)
594
return err;
595
596
if (copy_to_user(useraddr, &cmd, sizeof(cmd)))
597
return -EFAULT;
598
return 0;
599
}
600
601
static int ethtool_set_settings(struct net_device *dev, void __user *useraddr)
602
{
603
struct ethtool_cmd cmd;
604
605
if (!dev->ethtool_ops->set_settings)
606
return -EOPNOTSUPP;
607
608
if (copy_from_user(&cmd, useraddr, sizeof(cmd)))
609
return -EFAULT;
610
611
return dev->ethtool_ops->set_settings(dev, &cmd);
612
}
613
614
static noinline_for_stack int ethtool_get_drvinfo(struct net_device *dev,
615
void __user *useraddr)
616
{
617
struct ethtool_drvinfo info;
618
const struct ethtool_ops *ops = dev->ethtool_ops;
619
620
memset(&info, 0, sizeof(info));
621
info.cmd = ETHTOOL_GDRVINFO;
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
}
632
633
/*
634
* this method of obtaining string set info is deprecated;
635
* Use ETHTOOL_GSSET_INFO instead.
636
*/
637
if (ops && ops->get_sset_count) {
638
int rc;
639
640
rc = ops->get_sset_count(dev, ETH_SS_TEST);
641
if (rc >= 0)
642
info.testinfo_len = rc;
643
rc = ops->get_sset_count(dev, ETH_SS_STATS);
644
if (rc >= 0)
645
info.n_stats = rc;
646
rc = ops->get_sset_count(dev, ETH_SS_PRIV_FLAGS);
647
if (rc >= 0)
648
info.n_priv_flags = rc;
649
}
650
if (ops && ops->get_regs_len)
651
info.regdump_len = ops->get_regs_len(dev);
652
if (ops && ops->get_eeprom_len)
653
info.eedump_len = ops->get_eeprom_len(dev);
654
655
if (copy_to_user(useraddr, &info, sizeof(info)))
656
return -EFAULT;
657
return 0;
658
}
659
660
static noinline_for_stack int ethtool_get_sset_info(struct net_device *dev,
661
void __user *useraddr)
662
{
663
struct ethtool_sset_info info;
664
u64 sset_mask;
665
int i, idx = 0, n_bits = 0, ret, rc;
666
u32 *info_buf = NULL;
667
668
if (copy_from_user(&info, useraddr, sizeof(info)))
669
return -EFAULT;
670
671
/* store copy of mask, because we zero struct later on */
672
sset_mask = info.sset_mask;
673
if (!sset_mask)
674
return 0;
675
676
/* calculate size of return buffer */
677
n_bits = hweight64(sset_mask);
678
679
memset(&info, 0, sizeof(info));
680
info.cmd = ETHTOOL_GSSET_INFO;
681
682
info_buf = kzalloc(n_bits * sizeof(u32), GFP_USER);
683
if (!info_buf)
684
return -ENOMEM;
685
686
/*
687
* fill return buffer based on input bitmask and successful
688
* get_sset_count return
689
*/
690
for (i = 0; i < 64; i++) {
691
if (!(sset_mask & (1ULL << i)))
692
continue;
693
694
rc = __ethtool_get_sset_count(dev, i);
695
if (rc >= 0) {
696
info.sset_mask |= (1ULL << i);
697
info_buf[idx++] = rc;
698
}
699
}
700
701
ret = -EFAULT;
702
if (copy_to_user(useraddr, &info, sizeof(info)))
703
goto out;
704
705
useraddr += offsetof(struct ethtool_sset_info, data);
706
if (copy_to_user(useraddr, info_buf, idx * sizeof(u32)))
707
goto out;
708
709
ret = 0;
710
711
out:
712
kfree(info_buf);
713
return ret;
714
}
715
716
static noinline_for_stack int ethtool_set_rxnfc(struct net_device *dev,
717
u32 cmd, void __user *useraddr)
718
{
719
struct ethtool_rxnfc info;
720
size_t info_size = sizeof(info);
721
722
if (!dev->ethtool_ops->set_rxnfc)
723
return -EOPNOTSUPP;
724
725
/* struct ethtool_rxnfc was originally defined for
726
* ETHTOOL_{G,S}RXFH with only the cmd, flow_type and data
727
* members. User-space might still be using that
728
* definition. */
729
if (cmd == ETHTOOL_SRXFH)
730
info_size = (offsetof(struct ethtool_rxnfc, data) +
731
sizeof(info.data));
732
733
if (copy_from_user(&info, useraddr, info_size))
734
return -EFAULT;
735
736
return dev->ethtool_ops->set_rxnfc(dev, &info);
737
}
738
739
static noinline_for_stack int ethtool_get_rxnfc(struct net_device *dev,
740
u32 cmd, void __user *useraddr)
741
{
742
struct ethtool_rxnfc info;
743
size_t info_size = sizeof(info);
744
const struct ethtool_ops *ops = dev->ethtool_ops;
745
int ret;
746
void *rule_buf = NULL;
747
748
if (!ops->get_rxnfc)
749
return -EOPNOTSUPP;
750
751
/* struct ethtool_rxnfc was originally defined for
752
* ETHTOOL_{G,S}RXFH with only the cmd, flow_type and data
753
* members. User-space might still be using that
754
* definition. */
755
if (cmd == ETHTOOL_GRXFH)
756
info_size = (offsetof(struct ethtool_rxnfc, data) +
757
sizeof(info.data));
758
759
if (copy_from_user(&info, useraddr, info_size))
760
return -EFAULT;
761
762
if (info.cmd == ETHTOOL_GRXCLSRLALL) {
763
if (info.rule_cnt > 0) {
764
if (info.rule_cnt <= KMALLOC_MAX_SIZE / sizeof(u32))
765
rule_buf = kzalloc(info.rule_cnt * sizeof(u32),
766
GFP_USER);
767
if (!rule_buf)
768
return -ENOMEM;
769
}
770
}
771
772
ret = ops->get_rxnfc(dev, &info, rule_buf);
773
if (ret < 0)
774
goto err_out;
775
776
ret = -EFAULT;
777
if (copy_to_user(useraddr, &info, info_size))
778
goto err_out;
779
780
if (rule_buf) {
781
useraddr += offsetof(struct ethtool_rxnfc, rule_locs);
782
if (copy_to_user(useraddr, rule_buf,
783
info.rule_cnt * sizeof(u32)))
784
goto err_out;
785
}
786
ret = 0;
787
788
err_out:
789
kfree(rule_buf);
790
791
return ret;
792
}
793
794
static noinline_for_stack int ethtool_get_rxfh_indir(struct net_device *dev,
795
void __user *useraddr)
796
{
797
struct ethtool_rxfh_indir *indir;
798
u32 table_size;
799
size_t full_size;
800
int ret;
801
802
if (!dev->ethtool_ops->get_rxfh_indir)
803
return -EOPNOTSUPP;
804
805
if (copy_from_user(&table_size,
806
useraddr + offsetof(struct ethtool_rxfh_indir, size),
807
sizeof(table_size)))
808
return -EFAULT;
809
810
if (table_size >
811
(KMALLOC_MAX_SIZE - sizeof(*indir)) / sizeof(*indir->ring_index))
812
return -ENOMEM;
813
full_size = sizeof(*indir) + sizeof(*indir->ring_index) * table_size;
814
indir = kzalloc(full_size, GFP_USER);
815
if (!indir)
816
return -ENOMEM;
817
818
indir->cmd = ETHTOOL_GRXFHINDIR;
819
indir->size = table_size;
820
ret = dev->ethtool_ops->get_rxfh_indir(dev, indir);
821
if (ret)
822
goto out;
823
824
if (copy_to_user(useraddr, indir, full_size))
825
ret = -EFAULT;
826
827
out:
828
kfree(indir);
829
return ret;
830
}
831
832
static noinline_for_stack int ethtool_set_rxfh_indir(struct net_device *dev,
833
void __user *useraddr)
834
{
835
struct ethtool_rxfh_indir *indir;
836
u32 table_size;
837
size_t full_size;
838
int ret;
839
840
if (!dev->ethtool_ops->set_rxfh_indir)
841
return -EOPNOTSUPP;
842
843
if (copy_from_user(&table_size,
844
useraddr + offsetof(struct ethtool_rxfh_indir, size),
845
sizeof(table_size)))
846
return -EFAULT;
847
848
if (table_size >
849
(KMALLOC_MAX_SIZE - sizeof(*indir)) / sizeof(*indir->ring_index))
850
return -ENOMEM;
851
full_size = sizeof(*indir) + sizeof(*indir->ring_index) * table_size;
852
indir = kmalloc(full_size, GFP_USER);
853
if (!indir)
854
return -ENOMEM;
855
856
if (copy_from_user(indir, useraddr, full_size)) {
857
ret = -EFAULT;
858
goto out;
859
}
860
861
ret = dev->ethtool_ops->set_rxfh_indir(dev, indir);
862
863
out:
864
kfree(indir);
865
return ret;
866
}
867
868
static void __rx_ntuple_filter_add(struct ethtool_rx_ntuple_list *list,
869
struct ethtool_rx_ntuple_flow_spec *spec,
870
struct ethtool_rx_ntuple_flow_spec_container *fsc)
871
{
872
873
/* don't add filters forever */
874
if (list->count >= ETHTOOL_MAX_NTUPLE_LIST_ENTRY) {
875
/* free the container */
876
kfree(fsc);
877
return;
878
}
879
880
/* Copy the whole filter over */
881
fsc->fs.flow_type = spec->flow_type;
882
memcpy(&fsc->fs.h_u, &spec->h_u, sizeof(spec->h_u));
883
memcpy(&fsc->fs.m_u, &spec->m_u, sizeof(spec->m_u));
884
885
fsc->fs.vlan_tag = spec->vlan_tag;
886
fsc->fs.vlan_tag_mask = spec->vlan_tag_mask;
887
fsc->fs.data = spec->data;
888
fsc->fs.data_mask = spec->data_mask;
889
fsc->fs.action = spec->action;
890
891
/* add to the list */
892
list_add_tail_rcu(&fsc->list, &list->list);
893
list->count++;
894
}
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
*/
902
static 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
928
static noinline_for_stack int ethtool_set_rx_ntuple(struct net_device *dev,
929
void __user *useraddr)
930
{
931
struct ethtool_rx_ntuple cmd;
932
const struct ethtool_ops *ops = dev->ethtool_ops;
933
struct ethtool_rx_ntuple_flow_spec_container *fsc = NULL;
934
int ret;
935
936
if (!ops->set_rx_ntuple)
937
return -EOPNOTSUPP;
938
939
if (!(dev->features & NETIF_F_NTUPLE))
940
return -EINVAL;
941
942
if (copy_from_user(&cmd, useraddr, sizeof(cmd)))
943
return -EFAULT;
944
945
rx_ntuple_fix_masks(&cmd.fs);
946
947
/*
948
* Cache filter in dev struct for GET operation only if
949
* the underlying driver doesn't have its own GET operation, and
950
* only if the filter was added successfully. First make sure we
951
* can allocate the filter, then continue if successful.
952
*/
953
if (!ops->get_rx_ntuple) {
954
fsc = kmalloc(sizeof(*fsc), GFP_ATOMIC);
955
if (!fsc)
956
return -ENOMEM;
957
}
958
959
ret = ops->set_rx_ntuple(dev, &cmd);
960
if (ret) {
961
kfree(fsc);
962
return ret;
963
}
964
965
if (!ops->get_rx_ntuple)
966
__rx_ntuple_filter_add(&dev->ethtool_ntuple_list, &cmd.fs, fsc);
967
968
return ret;
969
}
970
971
static int ethtool_get_rx_ntuple(struct net_device *dev, void __user *useraddr)
972
{
973
struct ethtool_gstrings gstrings;
974
const struct ethtool_ops *ops = dev->ethtool_ops;
975
struct ethtool_rx_ntuple_flow_spec_container *fsc;
976
u8 *data;
977
char *p;
978
int ret, i, num_strings = 0;
979
980
if (!ops->get_sset_count)
981
return -EOPNOTSUPP;
982
983
if (copy_from_user(&gstrings, useraddr, sizeof(gstrings)))
984
return -EFAULT;
985
986
ret = ops->get_sset_count(dev, gstrings.string_set);
987
if (ret < 0)
988
return ret;
989
990
gstrings.len = ret;
991
992
data = kzalloc(gstrings.len * ETH_GSTRING_LEN, GFP_USER);
993
if (!data)
994
return -ENOMEM;
995
996
if (ops->get_rx_ntuple) {
997
/* driver-specific filter grab */
998
ret = ops->get_rx_ntuple(dev, gstrings.string_set, data);
999
goto copy;
1000
}
1001
1002
/* default ethtool filter grab */
1003
i = 0;
1004
p = (char *)data;
1005
list_for_each_entry(fsc, &dev->ethtool_ntuple_list.list, list) {
1006
sprintf(p, "Filter %d:\n", i);
1007
p += ETH_GSTRING_LEN;
1008
num_strings++;
1009
1010
switch (fsc->fs.flow_type) {
1011
case TCP_V4_FLOW:
1012
sprintf(p, "\tFlow Type: TCP\n");
1013
p += ETH_GSTRING_LEN;
1014
num_strings++;
1015
break;
1016
case UDP_V4_FLOW:
1017
sprintf(p, "\tFlow Type: UDP\n");
1018
p += ETH_GSTRING_LEN;
1019
num_strings++;
1020
break;
1021
case SCTP_V4_FLOW:
1022
sprintf(p, "\tFlow Type: SCTP\n");
1023
p += ETH_GSTRING_LEN;
1024
num_strings++;
1025
break;
1026
case AH_ESP_V4_FLOW:
1027
sprintf(p, "\tFlow Type: AH ESP\n");
1028
p += ETH_GSTRING_LEN;
1029
num_strings++;
1030
break;
1031
case ESP_V4_FLOW:
1032
sprintf(p, "\tFlow Type: ESP\n");
1033
p += ETH_GSTRING_LEN;
1034
num_strings++;
1035
break;
1036
case IP_USER_FLOW:
1037
sprintf(p, "\tFlow Type: Raw IP\n");
1038
p += ETH_GSTRING_LEN;
1039
num_strings++;
1040
break;
1041
case IPV4_FLOW:
1042
sprintf(p, "\tFlow Type: IPv4\n");
1043
p += ETH_GSTRING_LEN;
1044
num_strings++;
1045
break;
1046
default:
1047
sprintf(p, "\tFlow Type: Unknown\n");
1048
p += ETH_GSTRING_LEN;
1049
num_strings++;
1050
goto unknown_filter;
1051
}
1052
1053
/* now the rest of the filters */
1054
switch (fsc->fs.flow_type) {
1055
case TCP_V4_FLOW:
1056
case UDP_V4_FLOW:
1057
case SCTP_V4_FLOW:
1058
sprintf(p, "\tSrc IP addr: 0x%x\n",
1059
fsc->fs.h_u.tcp_ip4_spec.ip4src);
1060
p += ETH_GSTRING_LEN;
1061
num_strings++;
1062
sprintf(p, "\tSrc IP mask: 0x%x\n",
1063
fsc->fs.m_u.tcp_ip4_spec.ip4src);
1064
p += ETH_GSTRING_LEN;
1065
num_strings++;
1066
sprintf(p, "\tDest IP addr: 0x%x\n",
1067
fsc->fs.h_u.tcp_ip4_spec.ip4dst);
1068
p += ETH_GSTRING_LEN;
1069
num_strings++;
1070
sprintf(p, "\tDest IP mask: 0x%x\n",
1071
fsc->fs.m_u.tcp_ip4_spec.ip4dst);
1072
p += ETH_GSTRING_LEN;
1073
num_strings++;
1074
sprintf(p, "\tSrc Port: %d, mask: 0x%x\n",
1075
fsc->fs.h_u.tcp_ip4_spec.psrc,
1076
fsc->fs.m_u.tcp_ip4_spec.psrc);
1077
p += ETH_GSTRING_LEN;
1078
num_strings++;
1079
sprintf(p, "\tDest Port: %d, mask: 0x%x\n",
1080
fsc->fs.h_u.tcp_ip4_spec.pdst,
1081
fsc->fs.m_u.tcp_ip4_spec.pdst);
1082
p += ETH_GSTRING_LEN;
1083
num_strings++;
1084
sprintf(p, "\tTOS: %d, mask: 0x%x\n",
1085
fsc->fs.h_u.tcp_ip4_spec.tos,
1086
fsc->fs.m_u.tcp_ip4_spec.tos);
1087
p += ETH_GSTRING_LEN;
1088
num_strings++;
1089
break;
1090
case AH_ESP_V4_FLOW:
1091
case ESP_V4_FLOW:
1092
sprintf(p, "\tSrc IP addr: 0x%x\n",
1093
fsc->fs.h_u.ah_ip4_spec.ip4src);
1094
p += ETH_GSTRING_LEN;
1095
num_strings++;
1096
sprintf(p, "\tSrc IP mask: 0x%x\n",
1097
fsc->fs.m_u.ah_ip4_spec.ip4src);
1098
p += ETH_GSTRING_LEN;
1099
num_strings++;
1100
sprintf(p, "\tDest IP addr: 0x%x\n",
1101
fsc->fs.h_u.ah_ip4_spec.ip4dst);
1102
p += ETH_GSTRING_LEN;
1103
num_strings++;
1104
sprintf(p, "\tDest IP mask: 0x%x\n",
1105
fsc->fs.m_u.ah_ip4_spec.ip4dst);
1106
p += ETH_GSTRING_LEN;
1107
num_strings++;
1108
sprintf(p, "\tSPI: %d, mask: 0x%x\n",
1109
fsc->fs.h_u.ah_ip4_spec.spi,
1110
fsc->fs.m_u.ah_ip4_spec.spi);
1111
p += ETH_GSTRING_LEN;
1112
num_strings++;
1113
sprintf(p, "\tTOS: %d, mask: 0x%x\n",
1114
fsc->fs.h_u.ah_ip4_spec.tos,
1115
fsc->fs.m_u.ah_ip4_spec.tos);
1116
p += ETH_GSTRING_LEN;
1117
num_strings++;
1118
break;
1119
case IP_USER_FLOW:
1120
sprintf(p, "\tSrc IP addr: 0x%x\n",
1121
fsc->fs.h_u.usr_ip4_spec.ip4src);
1122
p += ETH_GSTRING_LEN;
1123
num_strings++;
1124
sprintf(p, "\tSrc IP mask: 0x%x\n",
1125
fsc->fs.m_u.usr_ip4_spec.ip4src);
1126
p += ETH_GSTRING_LEN;
1127
num_strings++;
1128
sprintf(p, "\tDest IP addr: 0x%x\n",
1129
fsc->fs.h_u.usr_ip4_spec.ip4dst);
1130
p += ETH_GSTRING_LEN;
1131
num_strings++;
1132
sprintf(p, "\tDest IP mask: 0x%x\n",
1133
fsc->fs.m_u.usr_ip4_spec.ip4dst);
1134
p += ETH_GSTRING_LEN;
1135
num_strings++;
1136
break;
1137
case IPV4_FLOW:
1138
sprintf(p, "\tSrc IP addr: 0x%x\n",
1139
fsc->fs.h_u.usr_ip4_spec.ip4src);
1140
p += ETH_GSTRING_LEN;
1141
num_strings++;
1142
sprintf(p, "\tSrc IP mask: 0x%x\n",
1143
fsc->fs.m_u.usr_ip4_spec.ip4src);
1144
p += ETH_GSTRING_LEN;
1145
num_strings++;
1146
sprintf(p, "\tDest IP addr: 0x%x\n",
1147
fsc->fs.h_u.usr_ip4_spec.ip4dst);
1148
p += ETH_GSTRING_LEN;
1149
num_strings++;
1150
sprintf(p, "\tDest IP mask: 0x%x\n",
1151
fsc->fs.m_u.usr_ip4_spec.ip4dst);
1152
p += ETH_GSTRING_LEN;
1153
num_strings++;
1154
sprintf(p, "\tL4 bytes: 0x%x, mask: 0x%x\n",
1155
fsc->fs.h_u.usr_ip4_spec.l4_4_bytes,
1156
fsc->fs.m_u.usr_ip4_spec.l4_4_bytes);
1157
p += ETH_GSTRING_LEN;
1158
num_strings++;
1159
sprintf(p, "\tTOS: %d, mask: 0x%x\n",
1160
fsc->fs.h_u.usr_ip4_spec.tos,
1161
fsc->fs.m_u.usr_ip4_spec.tos);
1162
p += ETH_GSTRING_LEN;
1163
num_strings++;
1164
sprintf(p, "\tIP Version: %d, mask: 0x%x\n",
1165
fsc->fs.h_u.usr_ip4_spec.ip_ver,
1166
fsc->fs.m_u.usr_ip4_spec.ip_ver);
1167
p += ETH_GSTRING_LEN;
1168
num_strings++;
1169
sprintf(p, "\tProtocol: %d, mask: 0x%x\n",
1170
fsc->fs.h_u.usr_ip4_spec.proto,
1171
fsc->fs.m_u.usr_ip4_spec.proto);
1172
p += ETH_GSTRING_LEN;
1173
num_strings++;
1174
break;
1175
}
1176
sprintf(p, "\tVLAN: %d, mask: 0x%x\n",
1177
fsc->fs.vlan_tag, fsc->fs.vlan_tag_mask);
1178
p += ETH_GSTRING_LEN;
1179
num_strings++;
1180
sprintf(p, "\tUser-defined: 0x%Lx\n", fsc->fs.data);
1181
p += ETH_GSTRING_LEN;
1182
num_strings++;
1183
sprintf(p, "\tUser-defined mask: 0x%Lx\n", fsc->fs.data_mask);
1184
p += ETH_GSTRING_LEN;
1185
num_strings++;
1186
if (fsc->fs.action == ETHTOOL_RXNTUPLE_ACTION_DROP)
1187
sprintf(p, "\tAction: Drop\n");
1188
else
1189
sprintf(p, "\tAction: Direct to queue %d\n",
1190
fsc->fs.action);
1191
p += ETH_GSTRING_LEN;
1192
num_strings++;
1193
unknown_filter:
1194
i++;
1195
}
1196
copy:
1197
/* indicate to userspace how many strings we actually have */
1198
gstrings.len = num_strings;
1199
ret = -EFAULT;
1200
if (copy_to_user(useraddr, &gstrings, sizeof(gstrings)))
1201
goto out;
1202
useraddr += sizeof(gstrings);
1203
if (copy_to_user(useraddr, data, gstrings.len * ETH_GSTRING_LEN))
1204
goto out;
1205
ret = 0;
1206
1207
out:
1208
kfree(data);
1209
return ret;
1210
}
1211
1212
static int ethtool_get_regs(struct net_device *dev, char __user *useraddr)
1213
{
1214
struct ethtool_regs regs;
1215
const struct ethtool_ops *ops = dev->ethtool_ops;
1216
void *regbuf;
1217
int reglen, ret;
1218
1219
if (!ops->get_regs || !ops->get_regs_len)
1220
return -EOPNOTSUPP;
1221
1222
if (copy_from_user(&regs, useraddr, sizeof(regs)))
1223
return -EFAULT;
1224
1225
reglen = ops->get_regs_len(dev);
1226
if (regs.len > reglen)
1227
regs.len = reglen;
1228
1229
regbuf = vzalloc(reglen);
1230
if (!regbuf)
1231
return -ENOMEM;
1232
1233
ops->get_regs(dev, &regs, regbuf);
1234
1235
ret = -EFAULT;
1236
if (copy_to_user(useraddr, &regs, sizeof(regs)))
1237
goto out;
1238
useraddr += offsetof(struct ethtool_regs, data);
1239
if (copy_to_user(useraddr, regbuf, regs.len))
1240
goto out;
1241
ret = 0;
1242
1243
out:
1244
vfree(regbuf);
1245
return ret;
1246
}
1247
1248
static int ethtool_reset(struct net_device *dev, char __user *useraddr)
1249
{
1250
struct ethtool_value reset;
1251
int ret;
1252
1253
if (!dev->ethtool_ops->reset)
1254
return -EOPNOTSUPP;
1255
1256
if (copy_from_user(&reset, useraddr, sizeof(reset)))
1257
return -EFAULT;
1258
1259
ret = dev->ethtool_ops->reset(dev, &reset.data);
1260
if (ret)
1261
return ret;
1262
1263
if (copy_to_user(useraddr, &reset, sizeof(reset)))
1264
return -EFAULT;
1265
return 0;
1266
}
1267
1268
static int ethtool_get_wol(struct net_device *dev, char __user *useraddr)
1269
{
1270
struct ethtool_wolinfo wol = { .cmd = ETHTOOL_GWOL };
1271
1272
if (!dev->ethtool_ops->get_wol)
1273
return -EOPNOTSUPP;
1274
1275
dev->ethtool_ops->get_wol(dev, &wol);
1276
1277
if (copy_to_user(useraddr, &wol, sizeof(wol)))
1278
return -EFAULT;
1279
return 0;
1280
}
1281
1282
static int ethtool_set_wol(struct net_device *dev, char __user *useraddr)
1283
{
1284
struct ethtool_wolinfo wol;
1285
1286
if (!dev->ethtool_ops->set_wol)
1287
return -EOPNOTSUPP;
1288
1289
if (copy_from_user(&wol, useraddr, sizeof(wol)))
1290
return -EFAULT;
1291
1292
return dev->ethtool_ops->set_wol(dev, &wol);
1293
}
1294
1295
static int ethtool_nway_reset(struct net_device *dev)
1296
{
1297
if (!dev->ethtool_ops->nway_reset)
1298
return -EOPNOTSUPP;
1299
1300
return dev->ethtool_ops->nway_reset(dev);
1301
}
1302
1303
static 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
1317
static int ethtool_get_eeprom(struct net_device *dev, void __user *useraddr)
1318
{
1319
struct ethtool_eeprom eeprom;
1320
const struct ethtool_ops *ops = dev->ethtool_ops;
1321
void __user *userbuf = useraddr + sizeof(eeprom);
1322
u32 bytes_remaining;
1323
u8 *data;
1324
int ret = 0;
1325
1326
if (!ops->get_eeprom || !ops->get_eeprom_len)
1327
return -EOPNOTSUPP;
1328
1329
if (copy_from_user(&eeprom, useraddr, sizeof(eeprom)))
1330
return -EFAULT;
1331
1332
/* Check for wrap and zero */
1333
if (eeprom.offset + eeprom.len <= eeprom.offset)
1334
return -EINVAL;
1335
1336
/* Check for exceeding total eeprom len */
1337
if (eeprom.offset + eeprom.len > ops->get_eeprom_len(dev))
1338
return -EINVAL;
1339
1340
data = kmalloc(PAGE_SIZE, GFP_USER);
1341
if (!data)
1342
return -ENOMEM;
1343
1344
bytes_remaining = eeprom.len;
1345
while (bytes_remaining > 0) {
1346
eeprom.len = min(bytes_remaining, (u32)PAGE_SIZE);
1347
1348
ret = ops->get_eeprom(dev, &eeprom, data);
1349
if (ret)
1350
break;
1351
if (copy_to_user(userbuf, data, eeprom.len)) {
1352
ret = -EFAULT;
1353
break;
1354
}
1355
userbuf += eeprom.len;
1356
eeprom.offset += eeprom.len;
1357
bytes_remaining -= eeprom.len;
1358
}
1359
1360
eeprom.len = userbuf - (useraddr + sizeof(eeprom));
1361
eeprom.offset -= eeprom.len;
1362
if (copy_to_user(useraddr, &eeprom, sizeof(eeprom)))
1363
ret = -EFAULT;
1364
1365
kfree(data);
1366
return ret;
1367
}
1368
1369
static int ethtool_set_eeprom(struct net_device *dev, void __user *useraddr)
1370
{
1371
struct ethtool_eeprom eeprom;
1372
const struct ethtool_ops *ops = dev->ethtool_ops;
1373
void __user *userbuf = useraddr + sizeof(eeprom);
1374
u32 bytes_remaining;
1375
u8 *data;
1376
int ret = 0;
1377
1378
if (!ops->set_eeprom || !ops->get_eeprom_len)
1379
return -EOPNOTSUPP;
1380
1381
if (copy_from_user(&eeprom, useraddr, sizeof(eeprom)))
1382
return -EFAULT;
1383
1384
/* Check for wrap and zero */
1385
if (eeprom.offset + eeprom.len <= eeprom.offset)
1386
return -EINVAL;
1387
1388
/* Check for exceeding total eeprom len */
1389
if (eeprom.offset + eeprom.len > ops->get_eeprom_len(dev))
1390
return -EINVAL;
1391
1392
data = kmalloc(PAGE_SIZE, GFP_USER);
1393
if (!data)
1394
return -ENOMEM;
1395
1396
bytes_remaining = eeprom.len;
1397
while (bytes_remaining > 0) {
1398
eeprom.len = min(bytes_remaining, (u32)PAGE_SIZE);
1399
1400
if (copy_from_user(data, userbuf, eeprom.len)) {
1401
ret = -EFAULT;
1402
break;
1403
}
1404
ret = ops->set_eeprom(dev, &eeprom, data);
1405
if (ret)
1406
break;
1407
userbuf += eeprom.len;
1408
eeprom.offset += eeprom.len;
1409
bytes_remaining -= eeprom.len;
1410
}
1411
1412
kfree(data);
1413
return ret;
1414
}
1415
1416
static noinline_for_stack int ethtool_get_coalesce(struct net_device *dev,
1417
void __user *useraddr)
1418
{
1419
struct ethtool_coalesce coalesce = { .cmd = ETHTOOL_GCOALESCE };
1420
1421
if (!dev->ethtool_ops->get_coalesce)
1422
return -EOPNOTSUPP;
1423
1424
dev->ethtool_ops->get_coalesce(dev, &coalesce);
1425
1426
if (copy_to_user(useraddr, &coalesce, sizeof(coalesce)))
1427
return -EFAULT;
1428
return 0;
1429
}
1430
1431
static noinline_for_stack int ethtool_set_coalesce(struct net_device *dev,
1432
void __user *useraddr)
1433
{
1434
struct ethtool_coalesce coalesce;
1435
1436
if (!dev->ethtool_ops->set_coalesce)
1437
return -EOPNOTSUPP;
1438
1439
if (copy_from_user(&coalesce, useraddr, sizeof(coalesce)))
1440
return -EFAULT;
1441
1442
return dev->ethtool_ops->set_coalesce(dev, &coalesce);
1443
}
1444
1445
static int ethtool_get_ringparam(struct net_device *dev, void __user *useraddr)
1446
{
1447
struct ethtool_ringparam ringparam = { .cmd = ETHTOOL_GRINGPARAM };
1448
1449
if (!dev->ethtool_ops->get_ringparam)
1450
return -EOPNOTSUPP;
1451
1452
dev->ethtool_ops->get_ringparam(dev, &ringparam);
1453
1454
if (copy_to_user(useraddr, &ringparam, sizeof(ringparam)))
1455
return -EFAULT;
1456
return 0;
1457
}
1458
1459
static int ethtool_set_ringparam(struct net_device *dev, void __user *useraddr)
1460
{
1461
struct ethtool_ringparam ringparam;
1462
1463
if (!dev->ethtool_ops->set_ringparam)
1464
return -EOPNOTSUPP;
1465
1466
if (copy_from_user(&ringparam, useraddr, sizeof(ringparam)))
1467
return -EFAULT;
1468
1469
return dev->ethtool_ops->set_ringparam(dev, &ringparam);
1470
}
1471
1472
static 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
1487
static 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
1501
static int ethtool_get_pauseparam(struct net_device *dev, void __user *useraddr)
1502
{
1503
struct ethtool_pauseparam pauseparam = { ETHTOOL_GPAUSEPARAM };
1504
1505
if (!dev->ethtool_ops->get_pauseparam)
1506
return -EOPNOTSUPP;
1507
1508
dev->ethtool_ops->get_pauseparam(dev, &pauseparam);
1509
1510
if (copy_to_user(useraddr, &pauseparam, sizeof(pauseparam)))
1511
return -EFAULT;
1512
return 0;
1513
}
1514
1515
static int ethtool_set_pauseparam(struct net_device *dev, void __user *useraddr)
1516
{
1517
struct ethtool_pauseparam pauseparam;
1518
1519
if (!dev->ethtool_ops->set_pauseparam)
1520
return -EOPNOTSUPP;
1521
1522
if (copy_from_user(&pauseparam, useraddr, sizeof(pauseparam)))
1523
return -EFAULT;
1524
1525
return dev->ethtool_ops->set_pauseparam(dev, &pauseparam);
1526
}
1527
1528
static int __ethtool_set_sg(struct net_device *dev, u32 data)
1529
{
1530
int err;
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
1538
if (!data && dev->ethtool_ops->set_tso) {
1539
err = dev->ethtool_ops->set_tso(dev, 0);
1540
if (err)
1541
return err;
1542
}
1543
1544
if (!data && dev->ethtool_ops->set_ufo) {
1545
err = dev->ethtool_ops->set_ufo(dev, 0);
1546
if (err)
1547
return err;
1548
}
1549
return dev->ethtool_ops->set_sg(dev, data);
1550
}
1551
1552
static int __ethtool_set_tx_csum(struct net_device *dev, u32 data)
1553
{
1554
int err;
1555
1556
if (!dev->ethtool_ops->set_tx_csum)
1557
return -EOPNOTSUPP;
1558
1559
if (!data && dev->ethtool_ops->set_sg) {
1560
err = __ethtool_set_sg(dev, 0);
1561
if (err)
1562
return err;
1563
}
1564
1565
return dev->ethtool_ops->set_tx_csum(dev, data);
1566
}
1567
1568
static int __ethtool_set_rx_csum(struct net_device *dev, u32 data)
1569
{
1570
if (!dev->ethtool_ops->set_rx_csum)
1571
return -EOPNOTSUPP;
1572
1573
if (!data)
1574
dev->features &= ~NETIF_F_GRO;
1575
1576
return dev->ethtool_ops->set_rx_csum(dev, data);
1577
}
1578
1579
static int __ethtool_set_tso(struct net_device *dev, u32 data)
1580
{
1581
if (!dev->ethtool_ops->set_tso)
1582
return -EOPNOTSUPP;
1583
1584
if (data && !(dev->features & NETIF_F_SG))
1585
return -EINVAL;
1586
1587
return dev->ethtool_ops->set_tso(dev, data);
1588
}
1589
1590
static int __ethtool_set_ufo(struct net_device *dev, u32 data)
1591
{
1592
if (!dev->ethtool_ops->set_ufo)
1593
return -EOPNOTSUPP;
1594
if (data && !(dev->features & NETIF_F_SG))
1595
return -EINVAL;
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)))
1599
return -EINVAL;
1600
return dev->ethtool_ops->set_ufo(dev, data);
1601
}
1602
1603
static int ethtool_self_test(struct net_device *dev, char __user *useraddr)
1604
{
1605
struct ethtool_test test;
1606
const struct ethtool_ops *ops = dev->ethtool_ops;
1607
u64 *data;
1608
int ret, test_len;
1609
1610
if (!ops->self_test || !ops->get_sset_count)
1611
return -EOPNOTSUPP;
1612
1613
test_len = ops->get_sset_count(dev, ETH_SS_TEST);
1614
if (test_len < 0)
1615
return test_len;
1616
WARN_ON(test_len == 0);
1617
1618
if (copy_from_user(&test, useraddr, sizeof(test)))
1619
return -EFAULT;
1620
1621
test.len = test_len;
1622
data = kmalloc(test_len * sizeof(u64), GFP_USER);
1623
if (!data)
1624
return -ENOMEM;
1625
1626
ops->self_test(dev, &test, data);
1627
1628
ret = -EFAULT;
1629
if (copy_to_user(useraddr, &test, sizeof(test)))
1630
goto out;
1631
useraddr += sizeof(test);
1632
if (copy_to_user(useraddr, data, test.len * sizeof(u64)))
1633
goto out;
1634
ret = 0;
1635
1636
out:
1637
kfree(data);
1638
return ret;
1639
}
1640
1641
static int ethtool_get_strings(struct net_device *dev, void __user *useraddr)
1642
{
1643
struct ethtool_gstrings gstrings;
1644
u8 *data;
1645
int ret;
1646
1647
if (copy_from_user(&gstrings, useraddr, sizeof(gstrings)))
1648
return -EFAULT;
1649
1650
ret = __ethtool_get_sset_count(dev, gstrings.string_set);
1651
if (ret < 0)
1652
return ret;
1653
1654
gstrings.len = ret;
1655
1656
data = kmalloc(gstrings.len * ETH_GSTRING_LEN, GFP_USER);
1657
if (!data)
1658
return -ENOMEM;
1659
1660
__ethtool_get_strings(dev, gstrings.string_set, data);
1661
1662
ret = -EFAULT;
1663
if (copy_to_user(useraddr, &gstrings, sizeof(gstrings)))
1664
goto out;
1665
useraddr += sizeof(gstrings);
1666
if (copy_to_user(useraddr, data, gstrings.len * ETH_GSTRING_LEN))
1667
goto out;
1668
ret = 0;
1669
1670
out:
1671
kfree(data);
1672
return ret;
1673
}
1674
1675
static int ethtool_phys_id(struct net_device *dev, void __user *useraddr)
1676
{
1677
struct ethtool_value id;
1678
static bool busy;
1679
int rc;
1680
1681
if (!dev->ethtool_ops->set_phys_id)
1682
return -EOPNOTSUPP;
1683
1684
if (busy)
1685
return -EBUSY;
1686
1687
if (copy_from_user(&id, useraddr, sizeof(id)))
1688
return -EFAULT;
1689
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;
1732
}
1733
1734
static int ethtool_get_stats(struct net_device *dev, void __user *useraddr)
1735
{
1736
struct ethtool_stats stats;
1737
const struct ethtool_ops *ops = dev->ethtool_ops;
1738
u64 *data;
1739
int ret, n_stats;
1740
1741
if (!ops->get_ethtool_stats || !ops->get_sset_count)
1742
return -EOPNOTSUPP;
1743
1744
n_stats = ops->get_sset_count(dev, ETH_SS_STATS);
1745
if (n_stats < 0)
1746
return n_stats;
1747
WARN_ON(n_stats == 0);
1748
1749
if (copy_from_user(&stats, useraddr, sizeof(stats)))
1750
return -EFAULT;
1751
1752
stats.n_stats = n_stats;
1753
data = kmalloc(n_stats * sizeof(u64), GFP_USER);
1754
if (!data)
1755
return -ENOMEM;
1756
1757
ops->get_ethtool_stats(dev, &stats, data);
1758
1759
ret = -EFAULT;
1760
if (copy_to_user(useraddr, &stats, sizeof(stats)))
1761
goto out;
1762
useraddr += sizeof(stats);
1763
if (copy_to_user(useraddr, data, stats.n_stats * sizeof(u64)))
1764
goto out;
1765
ret = 0;
1766
1767
out:
1768
kfree(data);
1769
return ret;
1770
}
1771
1772
static int ethtool_get_perm_addr(struct net_device *dev, void __user *useraddr)
1773
{
1774
struct ethtool_perm_addr epaddr;
1775
1776
if (copy_from_user(&epaddr, useraddr, sizeof(epaddr)))
1777
return -EFAULT;
1778
1779
if (epaddr.size < dev->addr_len)
1780
return -ETOOSMALL;
1781
epaddr.size = dev->addr_len;
1782
1783
if (copy_to_user(useraddr, &epaddr, sizeof(epaddr)))
1784
return -EFAULT;
1785
useraddr += sizeof(epaddr);
1786
if (copy_to_user(useraddr, dev->perm_addr, epaddr.size))
1787
return -EFAULT;
1788
return 0;
1789
}
1790
1791
static int ethtool_get_value(struct net_device *dev, char __user *useraddr,
1792
u32 cmd, u32 (*actor)(struct net_device *))
1793
{
1794
struct ethtool_value edata = { .cmd = cmd };
1795
1796
if (!actor)
1797
return -EOPNOTSUPP;
1798
1799
edata.data = actor(dev);
1800
1801
if (copy_to_user(useraddr, &edata, sizeof(edata)))
1802
return -EFAULT;
1803
return 0;
1804
}
1805
1806
static int ethtool_set_value_void(struct net_device *dev, char __user *useraddr,
1807
void (*actor)(struct net_device *, u32))
1808
{
1809
struct ethtool_value edata;
1810
1811
if (!actor)
1812
return -EOPNOTSUPP;
1813
1814
if (copy_from_user(&edata, useraddr, sizeof(edata)))
1815
return -EFAULT;
1816
1817
actor(dev, edata.data);
1818
return 0;
1819
}
1820
1821
static int ethtool_set_value(struct net_device *dev, char __user *useraddr,
1822
int (*actor)(struct net_device *, u32))
1823
{
1824
struct ethtool_value edata;
1825
1826
if (!actor)
1827
return -EOPNOTSUPP;
1828
1829
if (copy_from_user(&edata, useraddr, sizeof(edata)))
1830
return -EFAULT;
1831
1832
return actor(dev, edata.data);
1833
}
1834
1835
static noinline_for_stack int ethtool_flash_device(struct net_device *dev,
1836
char __user *useraddr)
1837
{
1838
struct ethtool_flash efl;
1839
1840
if (copy_from_user(&efl, useraddr, sizeof(efl)))
1841
return -EFAULT;
1842
1843
if (!dev->ethtool_ops->flash_device)
1844
return -EOPNOTSUPP;
1845
1846
return dev->ethtool_ops->flash_device(dev, &efl);
1847
}
1848
1849
static 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
1863
static 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
1885
static 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;
1925
out:
1926
vfree(data);
1927
return ret;
1928
}
1929
1930
/* The main entry point in this file. Called from net/core/dev.c */
1931
1932
int dev_ethtool(struct net *net, struct ifreq *ifr)
1933
{
1934
struct net_device *dev = __dev_get_by_name(net, ifr->ifr_name);
1935
void __user *useraddr = ifr->ifr_data;
1936
u32 ethcmd;
1937
int rc;
1938
u32 old_features;
1939
1940
if (!dev || !netif_device_present(dev))
1941
return -ENODEV;
1942
1943
if (copy_from_user(&ethcmd, useraddr, sizeof(ethcmd)))
1944
return -EFAULT;
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
1956
/* Allow some commands to be done by anyone */
1957
switch (ethcmd) {
1958
case ETHTOOL_GSET:
1959
case ETHTOOL_GDRVINFO:
1960
case ETHTOOL_GMSGLVL:
1961
case ETHTOOL_GCOALESCE:
1962
case ETHTOOL_GRINGPARAM:
1963
case ETHTOOL_GPAUSEPARAM:
1964
case ETHTOOL_GRXCSUM:
1965
case ETHTOOL_GTXCSUM:
1966
case ETHTOOL_GSG:
1967
case ETHTOOL_GSTRINGS:
1968
case ETHTOOL_GTSO:
1969
case ETHTOOL_GPERMADDR:
1970
case ETHTOOL_GUFO:
1971
case ETHTOOL_GGSO:
1972
case ETHTOOL_GGRO:
1973
case ETHTOOL_GFLAGS:
1974
case ETHTOOL_GPFLAGS:
1975
case ETHTOOL_GRXFH:
1976
case ETHTOOL_GRXRINGS:
1977
case ETHTOOL_GRXCLSRLCNT:
1978
case ETHTOOL_GRXCLSRULE:
1979
case ETHTOOL_GRXCLSRLALL:
1980
case ETHTOOL_GFEATURES:
1981
break;
1982
default:
1983
if (!capable(CAP_NET_ADMIN))
1984
return -EPERM;
1985
}
1986
1987
if (dev->ethtool_ops->begin) {
1988
rc = dev->ethtool_ops->begin(dev);
1989
if (rc < 0)
1990
return rc;
1991
}
1992
old_features = dev->features;
1993
1994
switch (ethcmd) {
1995
case ETHTOOL_GSET:
1996
rc = ethtool_get_settings(dev, useraddr);
1997
break;
1998
case ETHTOOL_SSET:
1999
rc = ethtool_set_settings(dev, useraddr);
2000
break;
2001
case ETHTOOL_GDRVINFO:
2002
rc = ethtool_get_drvinfo(dev, useraddr);
2003
break;
2004
case ETHTOOL_GREGS:
2005
rc = ethtool_get_regs(dev, useraddr);
2006
break;
2007
case ETHTOOL_GWOL:
2008
rc = ethtool_get_wol(dev, useraddr);
2009
break;
2010
case ETHTOOL_SWOL:
2011
rc = ethtool_set_wol(dev, useraddr);
2012
break;
2013
case ETHTOOL_GMSGLVL:
2014
rc = ethtool_get_value(dev, useraddr, ethcmd,
2015
dev->ethtool_ops->get_msglevel);
2016
break;
2017
case ETHTOOL_SMSGLVL:
2018
rc = ethtool_set_value_void(dev, useraddr,
2019
dev->ethtool_ops->set_msglevel);
2020
break;
2021
case ETHTOOL_NWAY_RST:
2022
rc = ethtool_nway_reset(dev);
2023
break;
2024
case ETHTOOL_GLINK:
2025
rc = ethtool_get_link(dev, useraddr);
2026
break;
2027
case ETHTOOL_GEEPROM:
2028
rc = ethtool_get_eeprom(dev, useraddr);
2029
break;
2030
case ETHTOOL_SEEPROM:
2031
rc = ethtool_set_eeprom(dev, useraddr);
2032
break;
2033
case ETHTOOL_GCOALESCE:
2034
rc = ethtool_get_coalesce(dev, useraddr);
2035
break;
2036
case ETHTOOL_SCOALESCE:
2037
rc = ethtool_set_coalesce(dev, useraddr);
2038
break;
2039
case ETHTOOL_GRINGPARAM:
2040
rc = ethtool_get_ringparam(dev, useraddr);
2041
break;
2042
case ETHTOOL_SRINGPARAM:
2043
rc = ethtool_set_ringparam(dev, useraddr);
2044
break;
2045
case ETHTOOL_GPAUSEPARAM:
2046
rc = ethtool_get_pauseparam(dev, useraddr);
2047
break;
2048
case ETHTOOL_SPAUSEPARAM:
2049
rc = ethtool_set_pauseparam(dev, useraddr);
2050
break;
2051
case ETHTOOL_TEST:
2052
rc = ethtool_self_test(dev, useraddr);
2053
break;
2054
case ETHTOOL_GSTRINGS:
2055
rc = ethtool_get_strings(dev, useraddr);
2056
break;
2057
case ETHTOOL_PHYS_ID:
2058
rc = ethtool_phys_id(dev, useraddr);
2059
break;
2060
case ETHTOOL_GSTATS:
2061
rc = ethtool_get_stats(dev, useraddr);
2062
break;
2063
case ETHTOOL_GPERMADDR:
2064
rc = ethtool_get_perm_addr(dev, useraddr);
2065
break;
2066
case ETHTOOL_GFLAGS:
2067
rc = ethtool_get_value(dev, useraddr, ethcmd,
2068
(dev->ethtool_ops->get_flags ?
2069
dev->ethtool_ops->get_flags :
2070
ethtool_op_get_flags));
2071
break;
2072
case ETHTOOL_SFLAGS:
2073
rc = ethtool_set_value(dev, useraddr, __ethtool_set_flags);
2074
break;
2075
case ETHTOOL_GPFLAGS:
2076
rc = ethtool_get_value(dev, useraddr, ethcmd,
2077
dev->ethtool_ops->get_priv_flags);
2078
break;
2079
case ETHTOOL_SPFLAGS:
2080
rc = ethtool_set_value(dev, useraddr,
2081
dev->ethtool_ops->set_priv_flags);
2082
break;
2083
case ETHTOOL_GRXFH:
2084
case ETHTOOL_GRXRINGS:
2085
case ETHTOOL_GRXCLSRLCNT:
2086
case ETHTOOL_GRXCLSRULE:
2087
case ETHTOOL_GRXCLSRLALL:
2088
rc = ethtool_get_rxnfc(dev, ethcmd, useraddr);
2089
break;
2090
case ETHTOOL_SRXFH:
2091
case ETHTOOL_SRXCLSRLDEL:
2092
case ETHTOOL_SRXCLSRLINS:
2093
rc = ethtool_set_rxnfc(dev, ethcmd, useraddr);
2094
break;
2095
case ETHTOOL_FLASHDEV:
2096
rc = ethtool_flash_device(dev, useraddr);
2097
break;
2098
case ETHTOOL_RESET:
2099
rc = ethtool_reset(dev, useraddr);
2100
break;
2101
case ETHTOOL_SRXNTUPLE:
2102
rc = ethtool_set_rx_ntuple(dev, useraddr);
2103
break;
2104
case ETHTOOL_GRXNTUPLE:
2105
rc = ethtool_get_rx_ntuple(dev, useraddr);
2106
break;
2107
case ETHTOOL_GSSET_INFO:
2108
rc = ethtool_get_sset_info(dev, useraddr);
2109
break;
2110
case ETHTOOL_GRXFHINDIR:
2111
rc = ethtool_get_rxfh_indir(dev, useraddr);
2112
break;
2113
case ETHTOOL_SRXFHINDIR:
2114
rc = ethtool_set_rxfh_indir(dev, useraddr);
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;
2155
default:
2156
rc = -EOPNOTSUPP;
2157
}
2158
2159
if (dev->ethtool_ops->complete)
2160
dev->ethtool_ops->complete(dev);
2161
2162
if (old_features != dev->features)
2163
netdev_features_change(dev);
2164
2165
return rc;
2166
}
2167
2168