From 1d3f3ddf7db3d5b0c370e6d576df1eec77af80cd Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Wed, 15 Aug 2007 16:01:32 -0700 Subject: [PATCH] --- yaml --- r: 66282 b: refs/heads/master c: 339bf024756690949f536777b921f34186eaa8b4 h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/include/linux/ethtool.h | 8 +++++++- trunk/net/core/ethtool.c | 38 +++++++++++++++++++++++++++++++++++ 3 files changed, 46 insertions(+), 2 deletions(-) diff --git a/[refs] b/[refs] index d44692c090b2..d3b06c1223a7 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: ff03d49f0ca1959246068b315d26e009da692ff2 +refs/heads/master: 339bf024756690949f536777b921f34186eaa8b4 diff --git a/trunk/include/linux/ethtool.h b/trunk/include/linux/ethtool.h index f617998b87f1..71d4ada6f315 100644 --- a/trunk/include/linux/ethtool.h +++ b/trunk/include/linux/ethtool.h @@ -39,7 +39,8 @@ struct ethtool_drvinfo { char bus_info[ETHTOOL_BUSINFO_LEN]; /* Bus info for this IF. */ /* For PCI devices, use pci_name(pci_dev). */ char reserved1[32]; - char reserved2[16]; + char reserved2[12]; + __u32 n_priv_flags; /* number of flags valid in ETHTOOL_GPFLAGS */ __u32 n_stats; /* number of u64's from ETHTOOL_GSTATS */ __u32 testinfo_len; __u32 eedump_len; /* Size of data from ETHTOOL_GEEPROM (bytes) */ @@ -219,6 +220,7 @@ struct ethtool_pauseparam { enum ethtool_stringset { ETH_SS_TEST = 0, ETH_SS_STATS, + ETH_SS_PRIV_FLAGS, }; /* for passing string sets for data tagging */ @@ -386,6 +388,8 @@ struct ethtool_ops { int (*set_ufo)(struct net_device *, u32); u32 (*get_flags)(struct net_device *); int (*set_flags)(struct net_device *, u32); + u32 (*get_priv_flags)(struct net_device *); + int (*set_priv_flags)(struct net_device *, u32); int (*get_sset_count)(struct net_device *, int); /* the following hooks are obsolete */ @@ -434,6 +438,8 @@ struct ethtool_ops { #define ETHTOOL_SGSO 0x00000024 /* Set GSO enable (ethtool_value) */ #define ETHTOOL_GFLAGS 0x00000025 /* Get flags bitmap(ethtool_value) */ #define ETHTOOL_SFLAGS 0x00000026 /* Set flags bitmap(ethtool_value) */ +#define ETHTOOL_GPFLAGS 0x00000027 /* Get driver-private flags bitmap */ +#define ETHTOOL_SPFLAGS 0x00000028 /* Set driver-private flags bitmap */ /* compatibility with older code */ #define SPARC_ETH_GSET ETHTOOL_GSET diff --git a/trunk/net/core/ethtool.c b/trunk/net/core/ethtool.c index 1edae460d616..d255209dc110 100644 --- a/trunk/net/core/ethtool.c +++ b/trunk/net/core/ethtool.c @@ -188,6 +188,9 @@ static int ethtool_get_drvinfo(struct net_device *dev, void __user *useraddr) rc = ops->get_sset_count(dev, ETH_SS_STATS); if (rc >= 0) info.n_stats = rc; + rc = ops->get_sset_count(dev, ETH_SS_PRIV_FLAGS); + if (rc >= 0) + info.n_priv_flags = rc; } else { /* code path for obsolete hooks */ @@ -881,6 +884,33 @@ static int ethtool_set_flags(struct net_device *dev, char __user *useraddr) return dev->ethtool_ops->set_flags(dev, edata.data); } +static int ethtool_get_priv_flags(struct net_device *dev, char __user *useraddr) +{ + struct ethtool_value edata = { ETHTOOL_GPFLAGS }; + + if (!dev->ethtool_ops->get_priv_flags) + return -EOPNOTSUPP; + + edata.data = dev->ethtool_ops->get_priv_flags(dev); + + if (copy_to_user(useraddr, &edata, sizeof(edata))) + return -EFAULT; + return 0; +} + +static int ethtool_set_priv_flags(struct net_device *dev, char __user *useraddr) +{ + struct ethtool_value edata; + + if (!dev->ethtool_ops->set_priv_flags) + return -EOPNOTSUPP; + + if (copy_from_user(&edata, useraddr, sizeof(edata))) + return -EFAULT; + + return dev->ethtool_ops->set_priv_flags(dev, edata.data); +} + /* The main entry point in this file. Called from net/core/dev.c */ int dev_ethtool(struct ifreq *ifr) @@ -915,6 +945,8 @@ int dev_ethtool(struct ifreq *ifr) case ETHTOOL_GPERMADDR: case ETHTOOL_GUFO: case ETHTOOL_GGSO: + case ETHTOOL_GFLAGS: + case ETHTOOL_GPFLAGS: break; default: if (!capable(CAP_NET_ADMIN)) @@ -1039,6 +1071,12 @@ int dev_ethtool(struct ifreq *ifr) case ETHTOOL_SFLAGS: rc = ethtool_set_flags(dev, useraddr); break; + case ETHTOOL_GPFLAGS: + rc = ethtool_get_priv_flags(dev, useraddr); + break; + case ETHTOOL_SPFLAGS: + rc = ethtool_set_priv_flags(dev, useraddr); + break; default: rc = -EOPNOTSUPP; }