diff options
| author | Jeff Garzik <jeff@garzik.org> | 2007-08-15 19:01:08 -0400 |
|---|---|---|
| committer | David S. Miller <davem@sunset.davemloft.net> | 2007-10-10 19:48:08 -0400 |
| commit | ff03d49f0ca1959246068b315d26e009da692ff2 (patch) | |
| tree | 210cf86efa9fd4430d0011c81956bef92c3d71a3 | |
| parent | 3ae7c0b2e3747b50c3a6c63ebb67469e0a6b3203 (diff) | |
[ETHTOOL]: Introduce get_sset_count. Obsolete get_stats_count, self_test_count
Signed-off-by: Jeff Garzik <jeff@garzik.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
| -rw-r--r-- | include/linux/ethtool.h | 7 | ||||
| -rw-r--r-- | net/core/ethtool.c | 95 |
2 files changed, 75 insertions, 27 deletions
diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h index 0e5de2fb960c..f617998b87f1 100644 --- a/include/linux/ethtool.h +++ b/include/linux/ethtool.h | |||
| @@ -376,11 +376,9 @@ struct ethtool_ops { | |||
| 376 | int (*set_sg)(struct net_device *, u32); | 376 | int (*set_sg)(struct net_device *, u32); |
| 377 | u32 (*get_tso)(struct net_device *); | 377 | u32 (*get_tso)(struct net_device *); |
| 378 | int (*set_tso)(struct net_device *, u32); | 378 | int (*set_tso)(struct net_device *, u32); |
| 379 | int (*self_test_count)(struct net_device *); | ||
| 380 | void (*self_test)(struct net_device *, struct ethtool_test *, u64 *); | 379 | void (*self_test)(struct net_device *, struct ethtool_test *, u64 *); |
| 381 | void (*get_strings)(struct net_device *, u32 stringset, u8 *); | 380 | void (*get_strings)(struct net_device *, u32 stringset, u8 *); |
| 382 | int (*phys_id)(struct net_device *, u32); | 381 | int (*phys_id)(struct net_device *, u32); |
| 383 | int (*get_stats_count)(struct net_device *); | ||
| 384 | void (*get_ethtool_stats)(struct net_device *, struct ethtool_stats *, u64 *); | 382 | void (*get_ethtool_stats)(struct net_device *, struct ethtool_stats *, u64 *); |
| 385 | int (*begin)(struct net_device *); | 383 | int (*begin)(struct net_device *); |
| 386 | void (*complete)(struct net_device *); | 384 | void (*complete)(struct net_device *); |
| @@ -388,6 +386,11 @@ struct ethtool_ops { | |||
| 388 | int (*set_ufo)(struct net_device *, u32); | 386 | int (*set_ufo)(struct net_device *, u32); |
| 389 | u32 (*get_flags)(struct net_device *); | 387 | u32 (*get_flags)(struct net_device *); |
| 390 | int (*set_flags)(struct net_device *, u32); | 388 | int (*set_flags)(struct net_device *, u32); |
| 389 | int (*get_sset_count)(struct net_device *, int); | ||
| 390 | |||
| 391 | /* the following hooks are obsolete */ | ||
| 392 | int (*self_test_count)(struct net_device *);/* use get_sset_count */ | ||
| 393 | int (*get_stats_count)(struct net_device *);/* use get_sset_count */ | ||
| 391 | }; | 394 | }; |
| 392 | #endif /* __KERNEL__ */ | 395 | #endif /* __KERNEL__ */ |
| 393 | 396 | ||
diff --git a/net/core/ethtool.c b/net/core/ethtool.c index 6f8b78bcfd84..1edae460d616 100644 --- a/net/core/ethtool.c +++ b/net/core/ethtool.c | |||
| @@ -179,10 +179,23 @@ static int ethtool_get_drvinfo(struct net_device *dev, void __user *useraddr) | |||
| 179 | info.cmd = ETHTOOL_GDRVINFO; | 179 | info.cmd = ETHTOOL_GDRVINFO; |
| 180 | ops->get_drvinfo(dev, &info); | 180 | ops->get_drvinfo(dev, &info); |
| 181 | 181 | ||
| 182 | if (ops->self_test_count) | 182 | if (ops->get_sset_count) { |
| 183 | info.testinfo_len = ops->self_test_count(dev); | 183 | int rc; |
| 184 | if (ops->get_stats_count) | 184 | |
| 185 | info.n_stats = ops->get_stats_count(dev); | 185 | rc = ops->get_sset_count(dev, ETH_SS_TEST); |
| 186 | if (rc >= 0) | ||
| 187 | info.testinfo_len = rc; | ||
| 188 | rc = ops->get_sset_count(dev, ETH_SS_STATS); | ||
| 189 | if (rc >= 0) | ||
| 190 | info.n_stats = rc; | ||
| 191 | } else { | ||
| 192 | /* code path for obsolete hooks */ | ||
| 193 | |||
| 194 | if (ops->self_test_count) | ||
| 195 | info.testinfo_len = ops->self_test_count(dev); | ||
| 196 | if (ops->get_stats_count) | ||
| 197 | info.n_stats = ops->get_stats_count(dev); | ||
| 198 | } | ||
| 186 | if (ops->get_regs_len) | 199 | if (ops->get_regs_len) |
| 187 | info.regdump_len = ops->get_regs_len(dev); | 200 | info.regdump_len = ops->get_regs_len(dev); |
| 188 | if (ops->get_eeprom_len) | 201 | if (ops->get_eeprom_len) |
| @@ -669,16 +682,27 @@ static int ethtool_self_test(struct net_device *dev, char __user *useraddr) | |||
| 669 | struct ethtool_test test; | 682 | struct ethtool_test test; |
| 670 | const struct ethtool_ops *ops = dev->ethtool_ops; | 683 | const struct ethtool_ops *ops = dev->ethtool_ops; |
| 671 | u64 *data; | 684 | u64 *data; |
| 672 | int ret; | 685 | int ret, test_len; |
| 673 | 686 | ||
| 674 | if (!ops->self_test || !ops->self_test_count) | 687 | if (!ops->self_test) |
| 688 | return -EOPNOTSUPP; | ||
| 689 | if (!ops->get_sset_count && !ops->self_test_count) | ||
| 675 | return -EOPNOTSUPP; | 690 | return -EOPNOTSUPP; |
| 676 | 691 | ||
| 692 | if (ops->get_sset_count) | ||
| 693 | test_len = ops->get_sset_count(dev, ETH_SS_TEST); | ||
| 694 | else | ||
| 695 | /* code path for obsolete hook */ | ||
| 696 | test_len = ops->self_test_count(dev); | ||
| 697 | if (test_len < 0) | ||
| 698 | return test_len; | ||
| 699 | WARN_ON(test_len == 0); | ||
| 700 | |||
| 677 | if (copy_from_user(&test, useraddr, sizeof(test))) | 701 | if (copy_from_user(&test, useraddr, sizeof(test))) |
| 678 | return -EFAULT; | 702 | return -EFAULT; |
| 679 | 703 | ||
| 680 | test.len = ops->self_test_count(dev); | 704 | test.len = test_len; |
| 681 | data = kmalloc(test.len * sizeof(u64), GFP_USER); | 705 | data = kmalloc(test_len * sizeof(u64), GFP_USER); |
| 682 | if (!data) | 706 | if (!data) |
| 683 | return -ENOMEM; | 707 | return -ENOMEM; |
| 684 | 708 | ||
| @@ -710,19 +734,29 @@ static int ethtool_get_strings(struct net_device *dev, void __user *useraddr) | |||
| 710 | if (copy_from_user(&gstrings, useraddr, sizeof(gstrings))) | 734 | if (copy_from_user(&gstrings, useraddr, sizeof(gstrings))) |
| 711 | return -EFAULT; | 735 | return -EFAULT; |
| 712 | 736 | ||
| 713 | switch (gstrings.string_set) { | 737 | if (ops->get_sset_count) { |
| 714 | case ETH_SS_TEST: | 738 | ret = ops->get_sset_count(dev, gstrings.string_set); |
| 715 | if (!ops->self_test_count) | 739 | if (ret < 0) |
| 716 | return -EOPNOTSUPP; | 740 | return ret; |
| 717 | gstrings.len = ops->self_test_count(dev); | 741 | |
| 718 | break; | 742 | gstrings.len = ret; |
| 719 | case ETH_SS_STATS: | 743 | } else { |
| 720 | if (!ops->get_stats_count) | 744 | /* code path for obsolete hooks */ |
| 721 | return -EOPNOTSUPP; | 745 | |
| 722 | gstrings.len = ops->get_stats_count(dev); | 746 | switch (gstrings.string_set) { |
| 723 | break; | 747 | case ETH_SS_TEST: |
| 724 | default: | 748 | if (!ops->self_test_count) |
| 725 | return -EINVAL; | 749 | return -EOPNOTSUPP; |
| 750 | gstrings.len = ops->self_test_count(dev); | ||
| 751 | break; | ||
| 752 | case ETH_SS_STATS: | ||
| 753 | if (!ops->get_stats_count) | ||
| 754 | return -EOPNOTSUPP; | ||
| 755 | gstrings.len = ops->get_stats_count(dev); | ||
| 756 | break; | ||
| 757 | default: | ||
| 758 | return -EINVAL; | ||
| 759 | } | ||
| 726 | } | 760 | } |
| 727 | 761 | ||
| 728 | data = kmalloc(gstrings.len * ETH_GSTRING_LEN, GFP_USER); | 762 | data = kmalloc(gstrings.len * ETH_GSTRING_LEN, GFP_USER); |
| @@ -762,16 +796,27 @@ static int ethtool_get_stats(struct net_device *dev, void __user *useraddr) | |||
| 762 | struct ethtool_stats stats; | 796 | struct ethtool_stats stats; |
| 763 | const struct ethtool_ops *ops = dev->ethtool_ops; | 797 | const struct ethtool_ops *ops = dev->ethtool_ops; |
| 764 | u64 *data; | 798 | u64 *data; |
| 765 | int ret; | 799 | int ret, n_stats; |
| 766 | 800 | ||
| 767 | if (!ops->get_ethtool_stats || !ops->get_stats_count) | 801 | if (!ops->get_ethtool_stats) |
| 768 | return -EOPNOTSUPP; | 802 | return -EOPNOTSUPP; |
| 803 | if (!ops->get_sset_count && !ops->get_stats_count) | ||
| 804 | return -EOPNOTSUPP; | ||
| 805 | |||
| 806 | if (ops->get_sset_count) | ||
| 807 | n_stats = ops->get_sset_count(dev, ETH_SS_STATS); | ||
| 808 | else | ||
| 809 | /* code path for obsolete hook */ | ||
| 810 | n_stats = ops->get_stats_count(dev); | ||
| 811 | if (n_stats < 0) | ||
| 812 | return n_stats; | ||
| 813 | WARN_ON(n_stats == 0); | ||
| 769 | 814 | ||
| 770 | if (copy_from_user(&stats, useraddr, sizeof(stats))) | 815 | if (copy_from_user(&stats, useraddr, sizeof(stats))) |
| 771 | return -EFAULT; | 816 | return -EFAULT; |
| 772 | 817 | ||
| 773 | stats.n_stats = ops->get_stats_count(dev); | 818 | stats.n_stats = n_stats; |
| 774 | data = kmalloc(stats.n_stats * sizeof(u64), GFP_USER); | 819 | data = kmalloc(n_stats * sizeof(u64), GFP_USER); |
| 775 | if (!data) | 820 | if (!data) |
| 776 | return -ENOMEM; | 821 | return -ENOMEM; |
| 777 | 822 | ||
