.set_settings           = vortex_set_settings,
        .get_link               = ethtool_op_get_link,
        .nway_reset             = vortex_nway_reset,
-       .get_perm_addr          = ethtool_op_get_perm_addr,
 };
 
 #ifdef CONFIG_PCI
 
        .set_wol                = cp_set_wol,
        .get_strings            = cp_get_strings,
        .get_ethtool_stats      = cp_get_ethtool_stats,
-       .get_perm_addr          = ethtool_op_get_perm_addr,
        .get_eeprom_len         = cp_get_eeprom_len,
        .get_eeprom             = cp_get_eeprom,
        .set_eeprom             = cp_set_eeprom,
 
        .get_strings            = rtl8139_get_strings,
        .get_stats_count        = rtl8139_get_stats_count,
        .get_ethtool_stats      = rtl8139_get_ethtool_stats,
-       .get_perm_addr          = ethtool_op_get_perm_addr,
 };
 
 static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 
        .set_settings           = ax_set_settings,
        .nway_reset             = ax_nway_reset,
        .get_link               = ax_get_link,
-       .get_perm_addr          = ethtool_op_get_perm_addr,
 };
 
 /* setup code */
 
        .get_strings            = b44_get_strings,
        .get_stats_count        = b44_get_stats_count,
        .get_ethtool_stats      = b44_get_ethtool_stats,
-       .get_perm_addr          = ethtool_op_get_perm_addr,
 };
 
 static int b44_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
 
        .phys_id                = bnx2_phys_id,
        .get_stats_count        = bnx2_get_stats_count,
        .get_ethtool_stats      = bnx2_get_ethtool_stats,
-       .get_perm_addr          = ethtool_op_get_perm_addr,
 };
 
 /* Called with rtnl_lock */
 
        .get_wol = get_wol,
        .get_tso = ethtool_op_get_tso,
        .set_tso = ethtool_op_set_tso,
-       .get_perm_addr = ethtool_op_get_perm_addr
 };
 
 static int in_range(int val, int lo, int hi)
 
        .phys_id                = e100_phys_id,
        .get_stats_count        = e100_get_stats_count,
        .get_ethtool_stats      = e100_get_ethtool_stats,
-       .get_perm_addr          = ethtool_op_get_perm_addr,
 };
 
 static int e100_do_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
 
        .phys_id                = e1000_phys_id,
        .get_stats_count        = e1000_get_stats_count,
        .get_ethtool_stats      = e1000_get_ethtool_stats,
-       .get_perm_addr          = ethtool_op_get_perm_addr,
 };
 
 void e1000_set_ethtool_ops(struct net_device *netdev)
 
        .get_regs_len = nv_get_regs_len,
        .get_regs = nv_get_regs,
        .nway_reset = nv_nway_reset,
-       .get_perm_addr = ethtool_op_get_perm_addr,
        .get_tso = ethtool_op_get_tso,
        .set_tso = nv_set_tso,
        .get_ringparam = nv_get_ringparam,
 
        .phys_id = ixgb_phys_id,
        .get_stats_count = ixgb_get_stats_count,
        .get_ethtool_stats = ixgb_get_ethtool_stats,
-       .get_perm_addr = ethtool_op_get_perm_addr,
 };
 
 void ixgb_set_ethtool_ops(struct net_device *netdev)
 
        .get_drvinfo            = ne2k_pci_get_drvinfo,
        .get_tx_csum            = ethtool_op_get_tx_csum,
        .get_sg                 = ethtool_op_get_sg,
-       .get_perm_addr          = ethtool_op_get_perm_addr,
 };
 
 static void __devexit ne2k_pci_remove_one (struct pci_dev *pdev)
 
        .get_strings = netxen_nic_get_strings,
        .get_stats_count = netxen_nic_get_stats_count,
        .get_ethtool_stats = netxen_nic_get_ethtool_stats,
-       .get_perm_addr = ethtool_op_get_perm_addr,
 };
 
        .phys_id                = pcnet32_phys_id,
        .get_regs_len           = pcnet32_get_regs_len,
        .get_regs               = pcnet32_get_regs,
-       .get_perm_addr          = ethtool_op_get_perm_addr,
 };
 
 /* only probes for non-PCI devices, the rest are handled by
 
 static const struct ethtool_ops ql3xxx_ethtool_ops = {
        .get_settings = ql_get_settings,
        .get_drvinfo = ql_get_drvinfo,
-       .get_perm_addr = ethtool_op_get_perm_addr,
        .get_link = ethtool_op_get_link,
        .get_msglevel = ql_get_msglevel,
        .set_msglevel = ql_set_msglevel,
 
        .get_strings            = rtl8169_get_strings,
        .get_stats_count        = rtl8169_get_stats_count,
        .get_ethtool_stats      = rtl8169_get_ethtool_stats,
-       .get_perm_addr          = ethtool_op_get_perm_addr,
 };
 
 static void rtl8169_write_gmii_reg_bit(void __iomem *ioaddr, int reg,
 
        .get_strings            = sc92031_ethtool_get_strings,
        .get_stats_count        = sc92031_ethtool_get_stats_count,
        .get_ethtool_stats      = sc92031_ethtool_get_ethtool_stats,
-       .get_perm_addr          = ethtool_op_get_perm_addr,
        .get_ufo                = ethtool_op_get_ufo,
 };
 
 
        .phys_id        = skge_phys_id,
        .get_stats_count = skge_get_stats_count,
        .get_ethtool_stats = skge_get_ethtool_stats,
-       .get_perm_addr  = ethtool_op_get_perm_addr,
 };
 
 /*
 
        .phys_id        = sky2_phys_id,
        .get_stats_count = sky2_get_stats_count,
        .get_ethtool_stats = sky2_get_ethtool_stats,
-       .get_perm_addr  = ethtool_op_get_perm_addr,
 };
 
 #ifdef CONFIG_SKY2_DEBUG
 
        .get_link = get_link,
        .get_msglevel = get_msglevel,
        .set_msglevel = set_msglevel,
-       .get_perm_addr = ethtool_op_get_perm_addr,
 };
 
 static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 
        .get_msglevel           = vnet_get_msglevel,
        .set_msglevel           = vnet_set_msglevel,
        .get_link               = ethtool_op_get_link,
-       .get_perm_addr          = ethtool_op_get_perm_addr,
 };
 
 static void vnet_port_free_tx_bufs(struct vnet_port *port)
 
        .get_strings            = tc35815_get_strings,
        .get_stats_count        = tc35815_get_stats_count,
        .get_ethtool_stats      = tc35815_get_ethtool_stats,
-       .get_perm_addr          = ethtool_op_get_perm_addr,
 };
 
 static int tc35815_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 
        .get_ethtool_stats      = tg3_get_ethtool_stats,
        .get_coalesce           = tg3_get_coalesce,
        .set_coalesce           = tg3_set_coalesce,
-       .get_perm_addr          = ethtool_op_get_perm_addr,
 };
 
 static void __devinit tg3_get_eeprom_size(struct tg3 *tp)
 
        .set_wol                = rhine_set_wol,
        .get_sg                 = ethtool_op_get_sg,
        .get_tx_csum            = ethtool_op_get_tx_csum,
-       .get_perm_addr          = ethtool_op_get_perm_addr,
 };
 
 static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 
 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);
 u32 ethtool_op_get_ufo(struct net_device *dev);
 int ethtool_op_set_ufo(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:
  *
        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 *);
        u32     (*get_ufo)(struct net_device *);
 
        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;
-}
-
-
 u32 ethtool_op_get_ufo(struct net_device *dev)
 {
        return (dev->features & NETIF_F_UFO) != 0;
 static int ethtool_get_perm_addr(struct net_device *dev, void __user *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)))
+       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;
+       if (epaddr.size < dev->addr_len)
+               return -ETOOSMALL;
+       epaddr.size = dev->addr_len;
 
-       ret = -EFAULT;
        if (copy_to_user(useraddr, &epaddr, sizeof(epaddr)))
-               goto out;
+               return -EFAULT;
        useraddr += sizeof(epaddr);
-       if (copy_to_user(useraddr, data, epaddr.size))
-               goto out;
-       ret = 0;
-
- out:
-       kfree(data);
-       return ret;
+       if (copy_to_user(useraddr, dev->perm_addr, epaddr.size))
+               return -EFAULT;
+       return 0;
 }
 
 /* The main entry point in this file.  Called from net/core/dev.c */
 
 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);