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 two as applied to a 2.6.12.2 kernel.  The 
second patch is an implementation of the function in the the e1000 
driver.  

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