Commit a6f9a705 authored by Jon Wetzel's avatar Jon Wetzel Committed by David S. Miller

[NET]: Add support for getting the permanent hardware address.

This patch adds a new field to net device to hold the permanent
hardware address, and adds a new generic ethtool_op function to
get that address.
Signed-off-by: default avatarJon Wetzel <jon_wetzel@dell.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 8cd25c1f
...@@ -250,6 +250,12 @@ struct ethtool_stats { ...@@ -250,6 +250,12 @@ struct ethtool_stats {
u64 data[0]; u64 data[0];
}; };
struct ethtool_perm_addr {
u32 cmd; /* ETHTOOL_GPERMADDR */
u32 size;
u8 data[0];
};
struct net_device; struct net_device;
/* Some generic methods drivers may use in their ethtool_ops */ /* Some generic methods drivers may use in their ethtool_ops */
...@@ -261,6 +267,8 @@ u32 ethtool_op_get_sg(struct net_device *dev); ...@@ -261,6 +267,8 @@ u32 ethtool_op_get_sg(struct net_device *dev);
int ethtool_op_set_sg(struct net_device *dev, u32 data); int ethtool_op_set_sg(struct net_device *dev, u32 data);
u32 ethtool_op_get_tso(struct net_device *dev); u32 ethtool_op_get_tso(struct net_device *dev);
int ethtool_op_set_tso(struct net_device *dev, u32 data); int ethtool_op_set_tso(struct net_device *dev, u32 data);
int ethtool_op_get_perm_addr(struct net_device *dev,
struct ethtool_perm_addr *addr, u8 *data);
/** /**
* &ethtool_ops - Alter and report network device settings * &ethtool_ops - Alter and report network device settings
...@@ -294,6 +302,7 @@ int ethtool_op_set_tso(struct net_device *dev, u32 data); ...@@ -294,6 +302,7 @@ int ethtool_op_set_tso(struct net_device *dev, u32 data);
* get_strings: Return a set of strings that describe the requested objects * get_strings: Return a set of strings that describe the requested objects
* phys_id: Identify the device * phys_id: Identify the device
* get_stats: Return statistics about the device * get_stats: Return statistics about the device
* get_perm_addr: Gets the permanent hardware address
* *
* Description: * Description:
* *
...@@ -352,6 +361,7 @@ struct ethtool_ops { ...@@ -352,6 +361,7 @@ struct ethtool_ops {
int (*phys_id)(struct net_device *, u32); int (*phys_id)(struct net_device *, u32);
int (*get_stats_count)(struct net_device *); int (*get_stats_count)(struct net_device *);
void (*get_ethtool_stats)(struct net_device *, struct ethtool_stats *, u64 *); void (*get_ethtool_stats)(struct net_device *, struct ethtool_stats *, u64 *);
int (*get_perm_addr)(struct net_device *, struct ethtool_perm_addr *, u8 *);
int (*begin)(struct net_device *); int (*begin)(struct net_device *);
void (*complete)(struct net_device *); void (*complete)(struct net_device *);
}; };
...@@ -389,6 +399,7 @@ struct ethtool_ops { ...@@ -389,6 +399,7 @@ struct ethtool_ops {
#define ETHTOOL_GSTATS 0x0000001d /* get NIC-specific statistics */ #define ETHTOOL_GSTATS 0x0000001d /* get NIC-specific statistics */
#define ETHTOOL_GTSO 0x0000001e /* Get TSO enable (ethtool_value) */ #define ETHTOOL_GTSO 0x0000001e /* Get TSO enable (ethtool_value) */
#define ETHTOOL_STSO 0x0000001f /* Set TSO enable (ethtool_value) */ #define ETHTOOL_STSO 0x0000001f /* Set TSO enable (ethtool_value) */
#define ETHTOOL_GPERMADDR 0x00000020 /* Get permanent hardware address */
/* compatibility with older code */ /* compatibility with older code */
#define SPARC_ETH_GSET ETHTOOL_GSET #define SPARC_ETH_GSET ETHTOOL_GSET
......
...@@ -337,6 +337,7 @@ struct net_device ...@@ -337,6 +337,7 @@ struct net_device
/* Interface address info. */ /* Interface address info. */
unsigned char broadcast[MAX_ADDR_LEN]; /* hw bcast add */ unsigned char broadcast[MAX_ADDR_LEN]; /* hw bcast add */
unsigned char dev_addr[MAX_ADDR_LEN]; /* hw address */ unsigned char dev_addr[MAX_ADDR_LEN]; /* hw address */
unsigned char perm_addr[MAX_ADDR_LEN]; /* permanent hw address */
unsigned char addr_len; /* hardware address length */ unsigned char addr_len; /* hardware address length */
unsigned short dev_id; /* for shared network cards */ unsigned short dev_id; /* for shared network cards */
......
...@@ -81,6 +81,18 @@ int ethtool_op_set_tso(struct net_device *dev, u32 data) ...@@ -81,6 +81,18 @@ int ethtool_op_set_tso(struct net_device *dev, u32 data)
return 0; return 0;
} }
int ethtool_op_get_perm_addr(struct net_device *dev, struct ethtool_perm_addr *addr, u8 *data)
{
unsigned char len = dev->addr_len;
if ( addr->size < len )
return -ETOOSMALL;
addr->size = len;
memcpy(data, dev->perm_addr, len);
return 0;
}
/* Handlers for each ethtool command */ /* Handlers for each ethtool command */
static int ethtool_get_settings(struct net_device *dev, void __user *useraddr) static int ethtool_get_settings(struct net_device *dev, void __user *useraddr)
...@@ -683,6 +695,39 @@ static int ethtool_get_stats(struct net_device *dev, void __user *useraddr) ...@@ -683,6 +695,39 @@ static int ethtool_get_stats(struct net_device *dev, void __user *useraddr)
return ret; return ret;
} }
static int ethtool_get_perm_addr(struct net_device *dev, void *useraddr)
{
struct ethtool_perm_addr epaddr;
u8 *data;
int ret;
if (!dev->ethtool_ops->get_perm_addr)
return -EOPNOTSUPP;
if (copy_from_user(&epaddr,useraddr,sizeof(epaddr)))
return -EFAULT;
data = kmalloc(epaddr.size, GFP_USER);
if (!data)
return -ENOMEM;
ret = dev->ethtool_ops->get_perm_addr(dev,&epaddr,data);
if (ret)
return ret;
ret = -EFAULT;
if (copy_to_user(useraddr, &epaddr, sizeof(epaddr)))
goto out;
useraddr += sizeof(epaddr);
if (copy_to_user(useraddr, data, epaddr.size))
goto out;
ret = 0;
out:
kfree(data);
return ret;
}
/* The main entry point in this file. Called from net/core/dev.c */ /* The main entry point in this file. Called from net/core/dev.c */
int dev_ethtool(struct ifreq *ifr) int dev_ethtool(struct ifreq *ifr)
...@@ -806,6 +851,9 @@ int dev_ethtool(struct ifreq *ifr) ...@@ -806,6 +851,9 @@ int dev_ethtool(struct ifreq *ifr)
case ETHTOOL_GSTATS: case ETHTOOL_GSTATS:
rc = ethtool_get_stats(dev, useraddr); rc = ethtool_get_stats(dev, useraddr);
break; break;
case ETHTOOL_GPERMADDR:
rc = ethtool_get_perm_addr(dev, useraddr);
break;
default: default:
rc = -EOPNOTSUPP; rc = -EOPNOTSUPP;
} }
...@@ -826,6 +874,7 @@ int dev_ethtool(struct ifreq *ifr) ...@@ -826,6 +874,7 @@ int dev_ethtool(struct ifreq *ifr)
EXPORT_SYMBOL(dev_ethtool); EXPORT_SYMBOL(dev_ethtool);
EXPORT_SYMBOL(ethtool_op_get_link); EXPORT_SYMBOL(ethtool_op_get_link);
EXPORT_SYMBOL_GPL(ethtool_op_get_perm_addr);
EXPORT_SYMBOL(ethtool_op_get_sg); EXPORT_SYMBOL(ethtool_op_get_sg);
EXPORT_SYMBOL(ethtool_op_get_tso); EXPORT_SYMBOL(ethtool_op_get_tso);
EXPORT_SYMBOL(ethtool_op_get_tx_csum); EXPORT_SYMBOL(ethtool_op_get_tx_csum);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment