(Now I've shown my great skill with e-mail, cc'ing this to not one but _two_
invalid e-mail addresses. Sorry for sending this to you twice Dave, you
probably figured it out already, but my actual e-mail address is below.)
Patch compiles (!) and has been tested using a modified ethtool.
Apologies to everyone whose time I wasted by neglecting to make
sure the patch worked before submission. This is the end of my
internship at Dell, so please send any responses to:
[EMAIL PROTECTED]
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 <[EMAIL PROTECTED]>
Signed-off-by: John W. Linville <[EMAIL PROTECTED]>
--- linux-2.6.13-rc6/include/linux/netdevice.h 2005-08-12 13:10:12.000000000
-0500
+++ linux-2.6.13-rc6-jww/include/linux/netdevice.h 2005-08-19
08:20:49.000000000 -0500
@@ -336,6 +336,7 @@
/* 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 */
--- linux-2.6.13-rc6/include/linux/ethtool.h 2005-08-05 02:04:37.000000000
-0500
+++ linux-2.6.13-rc6-jww/include/linux/ethtool.h 2005-08-19
08:32:41.000000000 -0500
@@ -250,6 +250,12 @@
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 @@
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 @@
* 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 @@
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 @@
#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
--- linux-2.6.13-rc6/net/core/ethtool.c 2005-08-05 02:04:37.000000000 -0500
+++ linux-2.6.13-rc6-jww/net/core/ethtool.c 2005-08-19 08:35:00.000000000
-0500
@@ -81,6 +81,18 @@
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 @@
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 @@
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 @@
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);
-
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at http://vger.kernel.org/majordomo-info.html