mirror of https://gitee.com/openkylin/linux.git
[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: Jon Wetzel <jon_wetzel@dell.com> Signed-off-by: John W. Linville <linville@tuxdriver.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
8cd25c1fcf
commit
a6f9a70578
|
@ -250,6 +250,12 @@ struct ethtool_stats {
|
|||
u64 data[0];
|
||||
};
|
||||
|
||||
struct ethtool_perm_addr {
|
||||
u32 cmd; /* ETHTOOL_GPERMADDR */
|
||||
u32 size;
|
||||
u8 data[0];
|
||||
};
|
||||
|
||||
struct net_device;
|
||||
|
||||
/* Some generic methods drivers may use in their ethtool_ops */
|
||||
|
@ -261,6 +267,8 @@ u32 ethtool_op_get_sg(struct net_device *dev);
|
|||
int ethtool_op_set_sg(struct net_device *dev, u32 data);
|
||||
u32 ethtool_op_get_tso(struct net_device *dev);
|
||||
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);
|
||||
|
||||
/**
|
||||
* ðtool_ops - Alter and report network device settings
|
||||
|
@ -294,7 +302,8 @@ int ethtool_op_set_tso(struct net_device *dev, u32 data);
|
|||
* get_strings: Return a set of strings that describe the requested objects
|
||||
* phys_id: Identify the device
|
||||
* get_stats: Return statistics about the device
|
||||
*
|
||||
* get_perm_addr: Gets the permanent hardware address
|
||||
*
|
||||
* Description:
|
||||
*
|
||||
* get_settings:
|
||||
|
@ -352,6 +361,7 @@ struct ethtool_ops {
|
|||
int (*phys_id)(struct net_device *, u32);
|
||||
int (*get_stats_count)(struct net_device *);
|
||||
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 *);
|
||||
void (*complete)(struct net_device *);
|
||||
};
|
||||
|
@ -389,6 +399,7 @@ struct ethtool_ops {
|
|||
#define ETHTOOL_GSTATS 0x0000001d /* get NIC-specific statistics */
|
||||
#define ETHTOOL_GTSO 0x0000001e /* Get 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 */
|
||||
#define SPARC_ETH_GSET ETHTOOL_GSET
|
||||
|
|
|
@ -337,6 +337,7 @@ struct net_device
|
|||
/* Interface address info. */
|
||||
unsigned char broadcast[MAX_ADDR_LEN]; /* hw bcast add */
|
||||
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 short dev_id; /* for shared network cards */
|
||||
|
||||
|
|
|
@ -81,6 +81,18 @@ int ethtool_op_set_tso(struct net_device *dev, u32 data)
|
|||
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 */
|
||||
|
||||
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)
|
|||
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 */
|
||||
|
||||
int dev_ethtool(struct ifreq *ifr)
|
||||
|
@ -806,6 +851,9 @@ int dev_ethtool(struct ifreq *ifr)
|
|||
case ETHTOOL_GSTATS:
|
||||
rc = ethtool_get_stats(dev, useraddr);
|
||||
break;
|
||||
case ETHTOOL_GPERMADDR:
|
||||
rc = ethtool_get_perm_addr(dev, useraddr);
|
||||
break;
|
||||
default:
|
||||
rc = -EOPNOTSUPP;
|
||||
}
|
||||
|
@ -826,6 +874,7 @@ int dev_ethtool(struct ifreq *ifr)
|
|||
|
||||
EXPORT_SYMBOL(dev_ethtool);
|
||||
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_tso);
|
||||
EXPORT_SYMBOL(ethtool_op_get_tx_csum);
|
||||
|
|
Loading…
Reference in New Issue