diff options
-rw-r--r-- | include/linux/ethtool.h | 8 | ||||
-rw-r--r-- | net/core/ethtool.c | 38 |
2 files changed, 45 insertions, 1 deletions
diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h index f617998b87f1..71d4ada6f315 100644 --- a/include/linux/ethtool.h +++ b/include/linux/ethtool.h | |||
@@ -39,7 +39,8 @@ struct ethtool_drvinfo { | |||
39 | char bus_info[ETHTOOL_BUSINFO_LEN]; /* Bus info for this IF. */ | 39 | char bus_info[ETHTOOL_BUSINFO_LEN]; /* Bus info for this IF. */ |
40 | /* For PCI devices, use pci_name(pci_dev). */ | 40 | /* For PCI devices, use pci_name(pci_dev). */ |
41 | char reserved1[32]; | 41 | char reserved1[32]; |
42 | char reserved2[16]; | 42 | char reserved2[12]; |
43 | __u32 n_priv_flags; /* number of flags valid in ETHTOOL_GPFLAGS */ | ||
43 | __u32 n_stats; /* number of u64's from ETHTOOL_GSTATS */ | 44 | __u32 n_stats; /* number of u64's from ETHTOOL_GSTATS */ |
44 | __u32 testinfo_len; | 45 | __u32 testinfo_len; |
45 | __u32 eedump_len; /* Size of data from ETHTOOL_GEEPROM (bytes) */ | 46 | __u32 eedump_len; /* Size of data from ETHTOOL_GEEPROM (bytes) */ |
@@ -219,6 +220,7 @@ struct ethtool_pauseparam { | |||
219 | enum ethtool_stringset { | 220 | enum ethtool_stringset { |
220 | ETH_SS_TEST = 0, | 221 | ETH_SS_TEST = 0, |
221 | ETH_SS_STATS, | 222 | ETH_SS_STATS, |
223 | ETH_SS_PRIV_FLAGS, | ||
222 | }; | 224 | }; |
223 | 225 | ||
224 | /* for passing string sets for data tagging */ | 226 | /* for passing string sets for data tagging */ |
@@ -386,6 +388,8 @@ struct ethtool_ops { | |||
386 | int (*set_ufo)(struct net_device *, u32); | 388 | int (*set_ufo)(struct net_device *, u32); |
387 | u32 (*get_flags)(struct net_device *); | 389 | u32 (*get_flags)(struct net_device *); |
388 | int (*set_flags)(struct net_device *, u32); | 390 | int (*set_flags)(struct net_device *, u32); |
391 | u32 (*get_priv_flags)(struct net_device *); | ||
392 | int (*set_priv_flags)(struct net_device *, u32); | ||
389 | int (*get_sset_count)(struct net_device *, int); | 393 | int (*get_sset_count)(struct net_device *, int); |
390 | 394 | ||
391 | /* the following hooks are obsolete */ | 395 | /* the following hooks are obsolete */ |
@@ -434,6 +438,8 @@ struct ethtool_ops { | |||
434 | #define ETHTOOL_SGSO 0x00000024 /* Set GSO enable (ethtool_value) */ | 438 | #define ETHTOOL_SGSO 0x00000024 /* Set GSO enable (ethtool_value) */ |
435 | #define ETHTOOL_GFLAGS 0x00000025 /* Get flags bitmap(ethtool_value) */ | 439 | #define ETHTOOL_GFLAGS 0x00000025 /* Get flags bitmap(ethtool_value) */ |
436 | #define ETHTOOL_SFLAGS 0x00000026 /* Set flags bitmap(ethtool_value) */ | 440 | #define ETHTOOL_SFLAGS 0x00000026 /* Set flags bitmap(ethtool_value) */ |
441 | #define ETHTOOL_GPFLAGS 0x00000027 /* Get driver-private flags bitmap */ | ||
442 | #define ETHTOOL_SPFLAGS 0x00000028 /* Set driver-private flags bitmap */ | ||
437 | 443 | ||
438 | /* compatibility with older code */ | 444 | /* compatibility with older code */ |
439 | #define SPARC_ETH_GSET ETHTOOL_GSET | 445 | #define SPARC_ETH_GSET ETHTOOL_GSET |
diff --git a/net/core/ethtool.c b/net/core/ethtool.c index 1edae460d616..d255209dc110 100644 --- a/net/core/ethtool.c +++ b/net/core/ethtool.c | |||
@@ -188,6 +188,9 @@ static int ethtool_get_drvinfo(struct net_device *dev, void __user *useraddr) | |||
188 | rc = ops->get_sset_count(dev, ETH_SS_STATS); | 188 | rc = ops->get_sset_count(dev, ETH_SS_STATS); |
189 | if (rc >= 0) | 189 | if (rc >= 0) |
190 | info.n_stats = rc; | 190 | info.n_stats = rc; |
191 | rc = ops->get_sset_count(dev, ETH_SS_PRIV_FLAGS); | ||
192 | if (rc >= 0) | ||
193 | info.n_priv_flags = rc; | ||
191 | } else { | 194 | } else { |
192 | /* code path for obsolete hooks */ | 195 | /* code path for obsolete hooks */ |
193 | 196 | ||
@@ -881,6 +884,33 @@ static int ethtool_set_flags(struct net_device *dev, char __user *useraddr) | |||
881 | return dev->ethtool_ops->set_flags(dev, edata.data); | 884 | return dev->ethtool_ops->set_flags(dev, edata.data); |
882 | } | 885 | } |
883 | 886 | ||
887 | static int ethtool_get_priv_flags(struct net_device *dev, char __user *useraddr) | ||
888 | { | ||
889 | struct ethtool_value edata = { ETHTOOL_GPFLAGS }; | ||
890 | |||
891 | if (!dev->ethtool_ops->get_priv_flags) | ||
892 | return -EOPNOTSUPP; | ||
893 | |||
894 | edata.data = dev->ethtool_ops->get_priv_flags(dev); | ||
895 | |||
896 | if (copy_to_user(useraddr, &edata, sizeof(edata))) | ||
897 | return -EFAULT; | ||
898 | return 0; | ||
899 | } | ||
900 | |||
901 | static int ethtool_set_priv_flags(struct net_device *dev, char __user *useraddr) | ||
902 | { | ||
903 | struct ethtool_value edata; | ||
904 | |||
905 | if (!dev->ethtool_ops->set_priv_flags) | ||
906 | return -EOPNOTSUPP; | ||
907 | |||
908 | if (copy_from_user(&edata, useraddr, sizeof(edata))) | ||
909 | return -EFAULT; | ||
910 | |||
911 | return dev->ethtool_ops->set_priv_flags(dev, edata.data); | ||
912 | } | ||
913 | |||
884 | /* The main entry point in this file. Called from net/core/dev.c */ | 914 | /* The main entry point in this file. Called from net/core/dev.c */ |
885 | 915 | ||
886 | int dev_ethtool(struct ifreq *ifr) | 916 | int dev_ethtool(struct ifreq *ifr) |
@@ -915,6 +945,8 @@ int dev_ethtool(struct ifreq *ifr) | |||
915 | case ETHTOOL_GPERMADDR: | 945 | case ETHTOOL_GPERMADDR: |
916 | case ETHTOOL_GUFO: | 946 | case ETHTOOL_GUFO: |
917 | case ETHTOOL_GGSO: | 947 | case ETHTOOL_GGSO: |
948 | case ETHTOOL_GFLAGS: | ||
949 | case ETHTOOL_GPFLAGS: | ||
918 | break; | 950 | break; |
919 | default: | 951 | default: |
920 | if (!capable(CAP_NET_ADMIN)) | 952 | if (!capable(CAP_NET_ADMIN)) |
@@ -1039,6 +1071,12 @@ int dev_ethtool(struct ifreq *ifr) | |||
1039 | case ETHTOOL_SFLAGS: | 1071 | case ETHTOOL_SFLAGS: |
1040 | rc = ethtool_set_flags(dev, useraddr); | 1072 | rc = ethtool_set_flags(dev, useraddr); |
1041 | break; | 1073 | break; |
1074 | case ETHTOOL_GPFLAGS: | ||
1075 | rc = ethtool_get_priv_flags(dev, useraddr); | ||
1076 | break; | ||
1077 | case ETHTOOL_SPFLAGS: | ||
1078 | rc = ethtool_set_priv_flags(dev, useraddr); | ||
1079 | break; | ||
1042 | default: | 1080 | default: |
1043 | rc = -EOPNOTSUPP; | 1081 | rc = -EOPNOTSUPP; |
1044 | } | 1082 | } |