Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

[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
Loading
Loading
Loading
Loading
+12 −1
Original line number Original line Diff line number Diff line
@@ -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);
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);
 * 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 {
	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 {
#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
+1 −0
Original line number Original line Diff line number Diff line
@@ -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 */


+49 −0
Original line number Original line Diff line number Diff line
@@ -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)
	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)
	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)


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);