From: Mark Brown Date: Tue, 28 Mar 2006 22:08:55 +0000 (-0800) Subject: [PATCH] natsemi: Support oversized EEPROMs X-Git-Tag: v2.6.17-rc1~155 X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a8b4cf42cf57e44e3c4a585e0f0a71e3a7efbf29;p=linux-2.6 [PATCH] natsemi: Support oversized EEPROMs The natsemi chip can have a larger EEPROM attached than it itself uses for configuration. This patch adds support for user space access to such an EEPROM. Signed-off-by: Mark Brown Cc: Tim Hockin Cc: Jeff Garzik Signed-off-by: Andrew Morton Signed-off-by: Jeff Garzik --- diff --git a/drivers/net/natsemi.c b/drivers/net/natsemi.c index 8d4999837b..7826afbb9d 100644 --- a/drivers/net/natsemi.c +++ b/drivers/net/natsemi.c @@ -226,7 +226,7 @@ static int full_duplex[MAX_UNITS]; NATSEMI_PG1_NREGS) #define NATSEMI_REGS_VER 1 /* v1 added RFDR registers */ #define NATSEMI_REGS_SIZE (NATSEMI_NREGS * sizeof(u32)) -#define NATSEMI_EEPROM_SIZE 24 /* 12 16-bit values */ +#define NATSEMI_DEF_EEPROM_SIZE 24 /* 12 16-bit values */ /* Buffer sizes: * The nic writes 32-bit values, even if the upper bytes of @@ -714,6 +714,8 @@ struct netdev_private { unsigned int iosize; spinlock_t lock; u32 msg_enable; + /* EEPROM data */ + int eeprom_size; }; static void move_int_phy(struct net_device *dev, int addr); @@ -890,6 +892,7 @@ static int __devinit natsemi_probe1 (struct pci_dev *pdev, np->msg_enable = (debug >= 0) ? (1<hands_off = 0; np->intr_status = 0; + np->eeprom_size = NATSEMI_DEF_EEPROM_SIZE; /* Initial port: * - If the nic was configured to use an external phy and if find_mii @@ -2582,7 +2585,8 @@ static int get_regs_len(struct net_device *dev) static int get_eeprom_len(struct net_device *dev) { - return NATSEMI_EEPROM_SIZE; + struct netdev_private *np = netdev_priv(dev); + return np->eeprom_size; } static int get_settings(struct net_device *dev, struct ethtool_cmd *ecmd) @@ -2669,15 +2673,20 @@ static u32 get_link(struct net_device *dev) static int get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, u8 *data) { struct netdev_private *np = netdev_priv(dev); - u8 eebuf[NATSEMI_EEPROM_SIZE]; + u8 *eebuf; int res; + eebuf = kmalloc(np->eeprom_size, GFP_KERNEL); + if (!eebuf) + return -ENOMEM; + eeprom->magic = PCI_VENDOR_ID_NS | (PCI_DEVICE_ID_NS_83815<<16); spin_lock_irq(&np->lock); res = netdev_get_eeprom(dev, eebuf); spin_unlock_irq(&np->lock); if (!res) memcpy(data, eebuf+eeprom->offset, eeprom->len); + kfree(eebuf); return res; } @@ -3033,9 +3042,10 @@ static int netdev_get_eeprom(struct net_device *dev, u8 *buf) int i; u16 *ebuf = (u16 *)buf; void __iomem * ioaddr = ns_ioaddr(dev); + struct netdev_private *np = netdev_priv(dev); /* eeprom_read reads 16 bits, and indexes by 16 bits */ - for (i = 0; i < NATSEMI_EEPROM_SIZE/2; i++) { + for (i = 0; i < np->eeprom_size/2; i++) { ebuf[i] = eeprom_read(ioaddr, i); /* The EEPROM itself stores data bit-swapped, but eeprom_read * reads it back "sanely". So we swap it back here in order to