This patch addresses an issue in which hardware detection programs
cannot correctly identify network cards due to their mutable MAC
addresses stored in net_device struct. As an example, in a configuration
with NIC team/bond, the MAC addresses in the dev_addr in net_device
struct of the members of a team/bond are changed to reflect MAC address
of the active/primary NIC. This causes Kudzu (RedHat hardware discovery
program) to identify them as something new or removed. This patch
provides a way to query the "permanent" MAC address stored in the EEPROM
of the card.  This patch makes the following changes to support the 
lookup of the factory provided mac address:

1) Adds a new field "perm_addr" to the net_device struct for holding 
the factory provided mac address of the card. (net_device.h)
2) Adds a new option to the ethtool ioctl called "ETHTOOL_GPERMADDR",
and added the function handle "get_perm_addr()" for handling 
this call.  The function will be implemented individually by each 
driver.
 
To obtain this functionality, a driver should set the perm_addr field 
and implement the new ethtool function.
 
This patch is the first of three.  The second patch is an implementation
of the function in the the e1000 driver, and the third adds a new IOCTL 
so that programs may access the new perm_addr field directly.

This patch has been tested in conjunction with the second.  Using a copy
of ethtool modified to use the new get_perm_addr function, the correct 
hardware address was returned.

Signed-off-by: Jon Wetzel <[EMAIL PROTECTED]>

--- linux-2.6.12.2/include/linux/netdevice.h    2005-06-29 18:00:53.000000000 
-0500
+++ linux-2.6.12.2-jw/include/linux/netdevice.h 2005-07-06 17:10:57.000000000 
-0500
@@ -342,6 +342,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.12.2/include/linux/ethtool.h      2005-06-29 18:00:53.000000000 
-0500
+++ linux-2.6.12.2-jw/include/linux/ethtool.h   2005-07-13 09:53:47.000000000 
-0500
@@ -250,6 +250,13 @@
        u64     data[0];
 };
 
+/* for getting the permanent mac address */
+#define ETH_MAX_ADDR_LEN       32
+struct ethtool_addr {
+       u32     cmd;            /* ETHTOOL_GPERMADDR */
+       u8      addr[ETH_MAX_ADDR_LEN]; 
+};
+
 struct net_device;
 
 /* Some generic methods drivers may use in their ethtool_ops */
@@ -354,6 +361,7 @@
        void    (*get_ethtool_stats)(struct net_device *, struct ethtool_stats 
*, u64 *);
        int     (*begin)(struct net_device *);
        void    (*complete)(struct net_device *);
+       int     (*get_perm_addr)(struct net_device *, struct ethtool_addr *);
 };
 
 /* CMDs currently supported */
@@ -389,6 +397,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.12.2/net/core/ethtool.c   2005-06-29 18:00:53.000000000 -0500
+++ linux-2.6.12.2-jw/net/core/ethtool.c        2005-07-14 15:26:37.000000000 
-0500
@@ -683,6 +683,22 @@
        return ret;
 }
 
+static int ethtool_get_perm_addr(struct net_device *dev, void __user *useraddr)
+{
+       struct ethtool_addr addr = { ETHTOOL_GPERMADDR };
+       struct ethtool_ops *ops = dev->ethtool_ops;
+       
+       if (!ops->get_perm_addr){
+               return -EOPNOTSUPP;
+
+       ops->get_perm_addr(dev, &addr);         
+
+       if (copy_to_user(useraddr, &addr, sizeof(addr)))
+               return -EFAULT;
+
+       return 0;
+}
+
 /* The main entry point in this file.  Called from net/core/dev.c */
 
 int dev_ethtool(struct ifreq *ifr)
@@ -806,6 +822,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;
        }
-
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

Reply via email to