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.c433
1 files changed, 419 insertions, 14 deletions
diff --git a/net/core/ethtool.c b/net/core/ethtool.c
index 236a9988ea91..f4cb6b6299d9 100644
--- a/net/core/ethtool.c
+++ b/net/core/ethtool.c
@@ -17,6 +17,7 @@
17#include <linux/errno.h> 17#include <linux/errno.h>
18#include <linux/ethtool.h> 18#include <linux/ethtool.h>
19#include <linux/netdevice.h> 19#include <linux/netdevice.h>
20#include <linux/bitops.h>
20#include <asm/uaccess.h> 21#include <asm/uaccess.h>
21 22
22/* 23/*
@@ -120,7 +121,7 @@ int ethtool_op_set_ufo(struct net_device *dev, u32 data)
120 * NETIF_F_xxx values in include/linux/netdevice.h 121 * NETIF_F_xxx values in include/linux/netdevice.h
121 */ 122 */
122static const u32 flags_dup_features = 123static const u32 flags_dup_features =
123 ETH_FLAG_LRO; 124 (ETH_FLAG_LRO | ETH_FLAG_NTUPLE);
124 125
125u32 ethtool_op_get_flags(struct net_device *dev) 126u32 ethtool_op_get_flags(struct net_device *dev)
126{ 127{
@@ -134,19 +135,44 @@ u32 ethtool_op_get_flags(struct net_device *dev)
134 135
135int ethtool_op_set_flags(struct net_device *dev, u32 data) 136int ethtool_op_set_flags(struct net_device *dev, u32 data)
136{ 137{
138 const struct ethtool_ops *ops = dev->ethtool_ops;
139 unsigned long features = dev->features;
140
137 if (data & ETH_FLAG_LRO) 141 if (data & ETH_FLAG_LRO)
138 dev->features |= NETIF_F_LRO; 142 features |= NETIF_F_LRO;
139 else 143 else
140 dev->features &= ~NETIF_F_LRO; 144 features &= ~NETIF_F_LRO;
145
146 if (data & ETH_FLAG_NTUPLE) {
147 if (!ops->set_rx_ntuple)
148 return -EOPNOTSUPP;
149 features |= NETIF_F_NTUPLE;
150 } else {
151 /* safe to clear regardless */
152 features &= ~NETIF_F_NTUPLE;
153 }
141 154
155 dev->features = features;
142 return 0; 156 return 0;
143} 157}
144 158
159void ethtool_ntuple_flush(struct net_device *dev)
160{
161 struct ethtool_rx_ntuple_flow_spec_container *fsc, *f;
162
163 list_for_each_entry_safe(fsc, f, &dev->ethtool_ntuple_list.list, list) {
164 list_del(&fsc->list);
165 kfree(fsc);
166 }
167 dev->ethtool_ntuple_list.count = 0;
168}
169EXPORT_SYMBOL(ethtool_ntuple_flush);
170
145/* Handlers for each ethtool command */ 171/* Handlers for each ethtool command */
146 172
147static int ethtool_get_settings(struct net_device *dev, void __user *useraddr) 173static int ethtool_get_settings(struct net_device *dev, void __user *useraddr)
148{ 174{
149 struct ethtool_cmd cmd = { ETHTOOL_GSET }; 175 struct ethtool_cmd cmd = { .cmd = ETHTOOL_GSET };
150 int err; 176 int err;
151 177
152 if (!dev->ethtool_ops->get_settings) 178 if (!dev->ethtool_ops->get_settings)
@@ -174,7 +200,7 @@ static int ethtool_set_settings(struct net_device *dev, void __user *useraddr)
174 return dev->ethtool_ops->set_settings(dev, &cmd); 200 return dev->ethtool_ops->set_settings(dev, &cmd);
175} 201}
176 202
177static int ethtool_get_drvinfo(struct net_device *dev, void __user *useraddr) 203static noinline_for_stack int ethtool_get_drvinfo(struct net_device *dev, void __user *useraddr)
178{ 204{
179 struct ethtool_drvinfo info; 205 struct ethtool_drvinfo info;
180 const struct ethtool_ops *ops = dev->ethtool_ops; 206 const struct ethtool_ops *ops = dev->ethtool_ops;
@@ -186,6 +212,10 @@ static int ethtool_get_drvinfo(struct net_device *dev, void __user *useraddr)
186 info.cmd = ETHTOOL_GDRVINFO; 212 info.cmd = ETHTOOL_GDRVINFO;
187 ops->get_drvinfo(dev, &info); 213 ops->get_drvinfo(dev, &info);
188 214
215 /*
216 * this method of obtaining string set info is deprecated;
217 * Use ETHTOOL_GSSET_INFO instead.
218 */
189 if (ops->get_sset_count) { 219 if (ops->get_sset_count) {
190 int rc; 220 int rc;
191 221
@@ -209,7 +239,67 @@ static int ethtool_get_drvinfo(struct net_device *dev, void __user *useraddr)
209 return 0; 239 return 0;
210} 240}
211 241
212static int ethtool_set_rxnfc(struct net_device *dev, void __user *useraddr) 242static noinline_for_stack int ethtool_get_sset_info(struct net_device *dev,
243 void __user *useraddr)
244{
245 struct ethtool_sset_info info;
246 const struct ethtool_ops *ops = dev->ethtool_ops;
247 u64 sset_mask;
248 int i, idx = 0, n_bits = 0, ret, rc;
249 u32 *info_buf = NULL;
250
251 if (!ops->get_sset_count)
252 return -EOPNOTSUPP;
253
254 if (copy_from_user(&info, useraddr, sizeof(info)))
255 return -EFAULT;
256
257 /* store copy of mask, because we zero struct later on */
258 sset_mask = info.sset_mask;
259 if (!sset_mask)
260 return 0;
261
262 /* calculate size of return buffer */
263 n_bits = hweight64(sset_mask);
264
265 memset(&info, 0, sizeof(info));
266 info.cmd = ETHTOOL_GSSET_INFO;
267
268 info_buf = kzalloc(n_bits * sizeof(u32), GFP_USER);
269 if (!info_buf)
270 return -ENOMEM;
271
272 /*
273 * fill return buffer based on input bitmask and successful
274 * get_sset_count return
275 */
276 for (i = 0; i < 64; i++) {
277 if (!(sset_mask & (1ULL << i)))
278 continue;
279
280 rc = ops->get_sset_count(dev, i);
281 if (rc >= 0) {
282 info.sset_mask |= (1ULL << i);
283 info_buf[idx++] = rc;
284 }
285 }
286
287 ret = -EFAULT;
288 if (copy_to_user(useraddr, &info, sizeof(info)))
289 goto out;
290
291 useraddr += offsetof(struct ethtool_sset_info, data);
292 if (copy_to_user(useraddr, info_buf, idx * sizeof(u32)))
293 goto out;
294
295 ret = 0;
296
297out:
298 kfree(info_buf);
299 return ret;
300}
301
302static noinline_for_stack int ethtool_set_rxnfc(struct net_device *dev, void __user *useraddr)
213{ 303{
214 struct ethtool_rxnfc cmd; 304 struct ethtool_rxnfc cmd;
215 305
@@ -222,7 +312,7 @@ static int ethtool_set_rxnfc(struct net_device *dev, void __user *useraddr)
222 return dev->ethtool_ops->set_rxnfc(dev, &cmd); 312 return dev->ethtool_ops->set_rxnfc(dev, &cmd);
223} 313}
224 314
225static int ethtool_get_rxnfc(struct net_device *dev, void __user *useraddr) 315static noinline_for_stack int ethtool_get_rxnfc(struct net_device *dev, void __user *useraddr)
226{ 316{
227 struct ethtool_rxnfc info; 317 struct ethtool_rxnfc info;
228 const struct ethtool_ops *ops = dev->ethtool_ops; 318 const struct ethtool_ops *ops = dev->ethtool_ops;
@@ -266,6 +356,312 @@ err_out:
266 return ret; 356 return ret;
267} 357}
268 358
359static void __rx_ntuple_filter_add(struct ethtool_rx_ntuple_list *list,
360 struct ethtool_rx_ntuple_flow_spec *spec,
361 struct ethtool_rx_ntuple_flow_spec_container *fsc)
362{
363
364 /* don't add filters forever */
365 if (list->count >= ETHTOOL_MAX_NTUPLE_LIST_ENTRY) {
366 /* free the container */
367 kfree(fsc);
368 return;
369 }
370
371 /* Copy the whole filter over */
372 fsc->fs.flow_type = spec->flow_type;
373 memcpy(&fsc->fs.h_u, &spec->h_u, sizeof(spec->h_u));
374 memcpy(&fsc->fs.m_u, &spec->m_u, sizeof(spec->m_u));
375
376 fsc->fs.vlan_tag = spec->vlan_tag;
377 fsc->fs.vlan_tag_mask = spec->vlan_tag_mask;
378 fsc->fs.data = spec->data;
379 fsc->fs.data_mask = spec->data_mask;
380 fsc->fs.action = spec->action;
381
382 /* add to the list */
383 list_add_tail_rcu(&fsc->list, &list->list);
384 list->count++;
385}
386
387static noinline_for_stack int ethtool_set_rx_ntuple(struct net_device *dev, void __user *useraddr)
388{
389 struct ethtool_rx_ntuple cmd;
390 const struct ethtool_ops *ops = dev->ethtool_ops;
391 struct ethtool_rx_ntuple_flow_spec_container *fsc = NULL;
392 int ret;
393
394 if (!(dev->features & NETIF_F_NTUPLE))
395 return -EINVAL;
396
397 if (copy_from_user(&cmd, useraddr, sizeof(cmd)))
398 return -EFAULT;
399
400 /*
401 * Cache filter in dev struct for GET operation only if
402 * the underlying driver doesn't have its own GET operation, and
403 * only if the filter was added successfully. First make sure we
404 * can allocate the filter, then continue if successful.
405 */
406 if (!ops->get_rx_ntuple) {
407 fsc = kmalloc(sizeof(*fsc), GFP_ATOMIC);
408 if (!fsc)
409 return -ENOMEM;
410 }
411
412 ret = ops->set_rx_ntuple(dev, &cmd);
413 if (ret) {
414 kfree(fsc);
415 return ret;
416 }
417
418 if (!ops->get_rx_ntuple)
419 __rx_ntuple_filter_add(&dev->ethtool_ntuple_list, &cmd.fs, fsc);
420
421 return ret;
422}
423
424static int ethtool_get_rx_ntuple(struct net_device *dev, void __user *useraddr)
425{
426 struct ethtool_gstrings gstrings;
427 const struct ethtool_ops *ops = dev->ethtool_ops;
428 struct ethtool_rx_ntuple_flow_spec_container *fsc;
429 u8 *data;
430 char *p;
431 int ret, i, num_strings = 0;
432
433 if (!ops->get_sset_count)
434 return -EOPNOTSUPP;
435
436 if (copy_from_user(&gstrings, useraddr, sizeof(gstrings)))
437 return -EFAULT;
438
439 ret = ops->get_sset_count(dev, gstrings.string_set);
440 if (ret < 0)
441 return ret;
442
443 gstrings.len = ret;
444
445 data = kmalloc(gstrings.len * ETH_GSTRING_LEN, GFP_USER);
446 if (!data)
447 return -ENOMEM;
448
449 if (ops->get_rx_ntuple) {
450 /* driver-specific filter grab */
451 ret = ops->get_rx_ntuple(dev, gstrings.string_set, data);
452 goto copy;
453 }
454
455 /* default ethtool filter grab */
456 i = 0;
457 p = (char *)data;
458 list_for_each_entry(fsc, &dev->ethtool_ntuple_list.list, list) {
459 sprintf(p, "Filter %d:\n", i);
460 p += ETH_GSTRING_LEN;
461 num_strings++;
462
463 switch (fsc->fs.flow_type) {
464 case TCP_V4_FLOW:
465 sprintf(p, "\tFlow Type: TCP\n");
466 p += ETH_GSTRING_LEN;
467 num_strings++;
468 break;
469 case UDP_V4_FLOW:
470 sprintf(p, "\tFlow Type: UDP\n");
471 p += ETH_GSTRING_LEN;
472 num_strings++;
473 break;
474 case SCTP_V4_FLOW:
475 sprintf(p, "\tFlow Type: SCTP\n");
476 p += ETH_GSTRING_LEN;
477 num_strings++;
478 break;
479 case AH_ESP_V4_FLOW:
480 sprintf(p, "\tFlow Type: AH ESP\n");
481 p += ETH_GSTRING_LEN;
482 num_strings++;
483 break;
484 case ESP_V4_FLOW:
485 sprintf(p, "\tFlow Type: ESP\n");
486 p += ETH_GSTRING_LEN;
487 num_strings++;
488 break;
489 case IP_USER_FLOW:
490 sprintf(p, "\tFlow Type: Raw IP\n");
491 p += ETH_GSTRING_LEN;
492 num_strings++;
493 break;
494 case IPV4_FLOW:
495 sprintf(p, "\tFlow Type: IPv4\n");
496 p += ETH_GSTRING_LEN;
497 num_strings++;
498 break;
499 default:
500 sprintf(p, "\tFlow Type: Unknown\n");
501 p += ETH_GSTRING_LEN;
502 num_strings++;
503 goto unknown_filter;
504 };
505
506 /* now the rest of the filters */
507 switch (fsc->fs.flow_type) {
508 case TCP_V4_FLOW:
509 case UDP_V4_FLOW:
510 case SCTP_V4_FLOW:
511 sprintf(p, "\tSrc IP addr: 0x%x\n",
512 fsc->fs.h_u.tcp_ip4_spec.ip4src);
513 p += ETH_GSTRING_LEN;
514 num_strings++;
515 sprintf(p, "\tSrc IP mask: 0x%x\n",
516 fsc->fs.m_u.tcp_ip4_spec.ip4src);
517 p += ETH_GSTRING_LEN;
518 num_strings++;
519 sprintf(p, "\tDest IP addr: 0x%x\n",
520 fsc->fs.h_u.tcp_ip4_spec.ip4dst);
521 p += ETH_GSTRING_LEN;
522 num_strings++;
523 sprintf(p, "\tDest IP mask: 0x%x\n",
524 fsc->fs.m_u.tcp_ip4_spec.ip4dst);
525 p += ETH_GSTRING_LEN;
526 num_strings++;
527 sprintf(p, "\tSrc Port: %d, mask: 0x%x\n",
528 fsc->fs.h_u.tcp_ip4_spec.psrc,
529 fsc->fs.m_u.tcp_ip4_spec.psrc);
530 p += ETH_GSTRING_LEN;
531 num_strings++;
532 sprintf(p, "\tDest Port: %d, mask: 0x%x\n",
533 fsc->fs.h_u.tcp_ip4_spec.pdst,
534 fsc->fs.m_u.tcp_ip4_spec.pdst);
535 p += ETH_GSTRING_LEN;
536 num_strings++;
537 sprintf(p, "\tTOS: %d, mask: 0x%x\n",
538 fsc->fs.h_u.tcp_ip4_spec.tos,
539 fsc->fs.m_u.tcp_ip4_spec.tos);
540 p += ETH_GSTRING_LEN;
541 num_strings++;
542 break;
543 case AH_ESP_V4_FLOW:
544 case ESP_V4_FLOW:
545 sprintf(p, "\tSrc IP addr: 0x%x\n",
546 fsc->fs.h_u.ah_ip4_spec.ip4src);
547 p += ETH_GSTRING_LEN;
548 num_strings++;
549 sprintf(p, "\tSrc IP mask: 0x%x\n",
550 fsc->fs.m_u.ah_ip4_spec.ip4src);
551 p += ETH_GSTRING_LEN;
552 num_strings++;
553 sprintf(p, "\tDest IP addr: 0x%x\n",
554 fsc->fs.h_u.ah_ip4_spec.ip4dst);
555 p += ETH_GSTRING_LEN;
556 num_strings++;
557 sprintf(p, "\tDest IP mask: 0x%x\n",
558 fsc->fs.m_u.ah_ip4_spec.ip4dst);
559 p += ETH_GSTRING_LEN;
560 num_strings++;
561 sprintf(p, "\tSPI: %d, mask: 0x%x\n",
562 fsc->fs.h_u.ah_ip4_spec.spi,
563 fsc->fs.m_u.ah_ip4_spec.spi);
564 p += ETH_GSTRING_LEN;
565 num_strings++;
566 sprintf(p, "\tTOS: %d, mask: 0x%x\n",
567 fsc->fs.h_u.ah_ip4_spec.tos,
568 fsc->fs.m_u.ah_ip4_spec.tos);
569 p += ETH_GSTRING_LEN;
570 num_strings++;
571 break;
572 case IP_USER_FLOW:
573 sprintf(p, "\tSrc IP addr: 0x%x\n",
574 fsc->fs.h_u.raw_ip4_spec.ip4src);
575 p += ETH_GSTRING_LEN;
576 num_strings++;
577 sprintf(p, "\tSrc IP mask: 0x%x\n",
578 fsc->fs.m_u.raw_ip4_spec.ip4src);
579 p += ETH_GSTRING_LEN;
580 num_strings++;
581 sprintf(p, "\tDest IP addr: 0x%x\n",
582 fsc->fs.h_u.raw_ip4_spec.ip4dst);
583 p += ETH_GSTRING_LEN;
584 num_strings++;
585 sprintf(p, "\tDest IP mask: 0x%x\n",
586 fsc->fs.m_u.raw_ip4_spec.ip4dst);
587 p += ETH_GSTRING_LEN;
588 num_strings++;
589 break;
590 case IPV4_FLOW:
591 sprintf(p, "\tSrc IP addr: 0x%x\n",
592 fsc->fs.h_u.usr_ip4_spec.ip4src);
593 p += ETH_GSTRING_LEN;
594 num_strings++;
595 sprintf(p, "\tSrc IP mask: 0x%x\n",
596 fsc->fs.m_u.usr_ip4_spec.ip4src);
597 p += ETH_GSTRING_LEN;
598 num_strings++;
599 sprintf(p, "\tDest IP addr: 0x%x\n",
600 fsc->fs.h_u.usr_ip4_spec.ip4dst);
601 p += ETH_GSTRING_LEN;
602 num_strings++;
603 sprintf(p, "\tDest IP mask: 0x%x\n",
604 fsc->fs.m_u.usr_ip4_spec.ip4dst);
605 p += ETH_GSTRING_LEN;
606 num_strings++;
607 sprintf(p, "\tL4 bytes: 0x%x, mask: 0x%x\n",
608 fsc->fs.h_u.usr_ip4_spec.l4_4_bytes,
609 fsc->fs.m_u.usr_ip4_spec.l4_4_bytes);
610 p += ETH_GSTRING_LEN;
611 num_strings++;
612 sprintf(p, "\tTOS: %d, mask: 0x%x\n",
613 fsc->fs.h_u.usr_ip4_spec.tos,
614 fsc->fs.m_u.usr_ip4_spec.tos);
615 p += ETH_GSTRING_LEN;
616 num_strings++;
617 sprintf(p, "\tIP Version: %d, mask: 0x%x\n",
618 fsc->fs.h_u.usr_ip4_spec.ip_ver,
619 fsc->fs.m_u.usr_ip4_spec.ip_ver);
620 p += ETH_GSTRING_LEN;
621 num_strings++;
622 sprintf(p, "\tProtocol: %d, mask: 0x%x\n",
623 fsc->fs.h_u.usr_ip4_spec.proto,
624 fsc->fs.m_u.usr_ip4_spec.proto);
625 p += ETH_GSTRING_LEN;
626 num_strings++;
627 break;
628 };
629 sprintf(p, "\tVLAN: %d, mask: 0x%x\n",
630 fsc->fs.vlan_tag, fsc->fs.vlan_tag_mask);
631 p += ETH_GSTRING_LEN;
632 num_strings++;
633 sprintf(p, "\tUser-defined: 0x%Lx\n", fsc->fs.data);
634 p += ETH_GSTRING_LEN;
635 num_strings++;
636 sprintf(p, "\tUser-defined mask: 0x%Lx\n", fsc->fs.data_mask);
637 p += ETH_GSTRING_LEN;
638 num_strings++;
639 if (fsc->fs.action == ETHTOOL_RXNTUPLE_ACTION_DROP)
640 sprintf(p, "\tAction: Drop\n");
641 else
642 sprintf(p, "\tAction: Direct to queue %d\n",
643 fsc->fs.action);
644 p += ETH_GSTRING_LEN;
645 num_strings++;
646unknown_filter:
647 i++;
648 }
649copy:
650 /* indicate to userspace how many strings we actually have */
651 gstrings.len = num_strings;
652 ret = -EFAULT;
653 if (copy_to_user(useraddr, &gstrings, sizeof(gstrings)))
654 goto out;
655 useraddr += sizeof(gstrings);
656 if (copy_to_user(useraddr, data, gstrings.len * ETH_GSTRING_LEN))
657 goto out;
658 ret = 0;
659
660out:
661 kfree(data);
662 return ret;
663}
664
269static int ethtool_get_regs(struct net_device *dev, char __user *useraddr) 665static int ethtool_get_regs(struct net_device *dev, char __user *useraddr)
270{ 666{
271 struct ethtool_regs regs; 667 struct ethtool_regs regs;
@@ -324,7 +720,7 @@ static int ethtool_reset(struct net_device *dev, char __user *useraddr)
324 720
325static int ethtool_get_wol(struct net_device *dev, char __user *useraddr) 721static int ethtool_get_wol(struct net_device *dev, char __user *useraddr)
326{ 722{
327 struct ethtool_wolinfo wol = { ETHTOOL_GWOL }; 723 struct ethtool_wolinfo wol = { .cmd = ETHTOOL_GWOL };
328 724
329 if (!dev->ethtool_ops->get_wol) 725 if (!dev->ethtool_ops->get_wol)
330 return -EOPNOTSUPP; 726 return -EOPNOTSUPP;
@@ -456,9 +852,9 @@ static int ethtool_set_eeprom(struct net_device *dev, void __user *useraddr)
456 return ret; 852 return ret;
457} 853}
458 854
459static int ethtool_get_coalesce(struct net_device *dev, void __user *useraddr) 855static noinline_for_stack int ethtool_get_coalesce(struct net_device *dev, void __user *useraddr)
460{ 856{
461 struct ethtool_coalesce coalesce = { ETHTOOL_GCOALESCE }; 857 struct ethtool_coalesce coalesce = { .cmd = ETHTOOL_GCOALESCE };
462 858
463 if (!dev->ethtool_ops->get_coalesce) 859 if (!dev->ethtool_ops->get_coalesce)
464 return -EOPNOTSUPP; 860 return -EOPNOTSUPP;
@@ -470,7 +866,7 @@ static int ethtool_get_coalesce(struct net_device *dev, void __user *useraddr)
470 return 0; 866 return 0;
471} 867}
472 868
473static int ethtool_set_coalesce(struct net_device *dev, void __user *useraddr) 869static noinline_for_stack int ethtool_set_coalesce(struct net_device *dev, void __user *useraddr)
474{ 870{
475 struct ethtool_coalesce coalesce; 871 struct ethtool_coalesce coalesce;
476 872
@@ -485,7 +881,7 @@ static int ethtool_set_coalesce(struct net_device *dev, void __user *useraddr)
485 881
486static int ethtool_get_ringparam(struct net_device *dev, void __user *useraddr) 882static int ethtool_get_ringparam(struct net_device *dev, void __user *useraddr)
487{ 883{
488 struct ethtool_ringparam ringparam = { ETHTOOL_GRINGPARAM }; 884 struct ethtool_ringparam ringparam = { .cmd = ETHTOOL_GRINGPARAM };
489 885
490 if (!dev->ethtool_ops->get_ringparam) 886 if (!dev->ethtool_ops->get_ringparam)
491 return -EOPNOTSUPP; 887 return -EOPNOTSUPP;
@@ -839,7 +1235,7 @@ static int ethtool_get_perm_addr(struct net_device *dev, void __user *useraddr)
839static int ethtool_get_value(struct net_device *dev, char __user *useraddr, 1235static int ethtool_get_value(struct net_device *dev, char __user *useraddr,
840 u32 cmd, u32 (*actor)(struct net_device *)) 1236 u32 cmd, u32 (*actor)(struct net_device *))
841{ 1237{
842 struct ethtool_value edata = { cmd }; 1238 struct ethtool_value edata = { .cmd = cmd };
843 1239
844 if (!actor) 1240 if (!actor)
845 return -EOPNOTSUPP; 1241 return -EOPNOTSUPP;
@@ -880,7 +1276,7 @@ static int ethtool_set_value(struct net_device *dev, char __user *useraddr,
880 return actor(dev, edata.data); 1276 return actor(dev, edata.data);
881} 1277}
882 1278
883static int ethtool_flash_device(struct net_device *dev, char __user *useraddr) 1279static noinline_for_stack int ethtool_flash_device(struct net_device *dev, char __user *useraddr)
884{ 1280{
885 struct ethtool_flash efl; 1281 struct ethtool_flash efl;
886 1282
@@ -1113,6 +1509,15 @@ int dev_ethtool(struct net *net, struct ifreq *ifr)
1113 case ETHTOOL_RESET: 1509 case ETHTOOL_RESET:
1114 rc = ethtool_reset(dev, useraddr); 1510 rc = ethtool_reset(dev, useraddr);
1115 break; 1511 break;
1512 case ETHTOOL_SRXNTUPLE:
1513 rc = ethtool_set_rx_ntuple(dev, useraddr);
1514 break;
1515 case ETHTOOL_GRXNTUPLE:
1516 rc = ethtool_get_rx_ntuple(dev, useraddr);
1517 break;
1518 case ETHTOOL_GSSET_INFO:
1519 rc = ethtool_get_sset_info(dev, useraddr);
1520 break;
1116 default: 1521 default:
1117 rc = -EOPNOTSUPP; 1522 rc = -EOPNOTSUPP;
1118 } 1523 }