aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/natsemi.c
diff options
context:
space:
mode:
authorMark Brown <broonie@sirena.org.uk>2006-03-28 17:08:55 -0500
committerJeff Garzik <jeff@garzik.org>2006-03-29 17:34:02 -0500
commita8b4cf42cf57e44e3c4a585e0f0a71e3a7efbf29 (patch)
treeba3bcaea18d88f12297d3302dd1c9a1b9cec4709 /drivers/net/natsemi.c
parent8dfc914a3f2ae4e303e2bff89f28fc14cee8a9a6 (diff)
[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 <broonie@sirena.org.uk> Cc: Tim Hockin <thockin@hockin.org> Cc: Jeff Garzik <jgarzik@pobox.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/net/natsemi.c')
-rw-r--r--drivers/net/natsemi.c18
1 files changed, 14 insertions, 4 deletions
diff --git a/drivers/net/natsemi.c b/drivers/net/natsemi.c
index 8d4999837b65..7826afbb9db9 100644
--- a/drivers/net/natsemi.c
+++ b/drivers/net/natsemi.c
@@ -226,7 +226,7 @@ static int full_duplex[MAX_UNITS];
226 NATSEMI_PG1_NREGS) 226 NATSEMI_PG1_NREGS)
227#define NATSEMI_REGS_VER 1 /* v1 added RFDR registers */ 227#define NATSEMI_REGS_VER 1 /* v1 added RFDR registers */
228#define NATSEMI_REGS_SIZE (NATSEMI_NREGS * sizeof(u32)) 228#define NATSEMI_REGS_SIZE (NATSEMI_NREGS * sizeof(u32))
229#define NATSEMI_EEPROM_SIZE 24 /* 12 16-bit values */ 229#define NATSEMI_DEF_EEPROM_SIZE 24 /* 12 16-bit values */
230 230
231/* Buffer sizes: 231/* Buffer sizes:
232 * The nic writes 32-bit values, even if the upper bytes of 232 * The nic writes 32-bit values, even if the upper bytes of
@@ -714,6 +714,8 @@ struct netdev_private {
714 unsigned int iosize; 714 unsigned int iosize;
715 spinlock_t lock; 715 spinlock_t lock;
716 u32 msg_enable; 716 u32 msg_enable;
717 /* EEPROM data */
718 int eeprom_size;
717}; 719};
718 720
719static void move_int_phy(struct net_device *dev, int addr); 721static void move_int_phy(struct net_device *dev, int addr);
@@ -890,6 +892,7 @@ static int __devinit natsemi_probe1 (struct pci_dev *pdev,
890 np->msg_enable = (debug >= 0) ? (1<<debug)-1 : NATSEMI_DEF_MSG; 892 np->msg_enable = (debug >= 0) ? (1<<debug)-1 : NATSEMI_DEF_MSG;
891 np->hands_off = 0; 893 np->hands_off = 0;
892 np->intr_status = 0; 894 np->intr_status = 0;
895 np->eeprom_size = NATSEMI_DEF_EEPROM_SIZE;
893 896
894 /* Initial port: 897 /* Initial port:
895 * - If the nic was configured to use an external phy and if find_mii 898 * - 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)
2582 2585
2583static int get_eeprom_len(struct net_device *dev) 2586static int get_eeprom_len(struct net_device *dev)
2584{ 2587{
2585 return NATSEMI_EEPROM_SIZE; 2588 struct netdev_private *np = netdev_priv(dev);
2589 return np->eeprom_size;
2586} 2590}
2587 2591
2588static int get_settings(struct net_device *dev, struct ethtool_cmd *ecmd) 2592static int get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
@@ -2669,15 +2673,20 @@ static u32 get_link(struct net_device *dev)
2669static int get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, u8 *data) 2673static int get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, u8 *data)
2670{ 2674{
2671 struct netdev_private *np = netdev_priv(dev); 2675 struct netdev_private *np = netdev_priv(dev);
2672 u8 eebuf[NATSEMI_EEPROM_SIZE]; 2676 u8 *eebuf;
2673 int res; 2677 int res;
2674 2678
2679 eebuf = kmalloc(np->eeprom_size, GFP_KERNEL);
2680 if (!eebuf)
2681 return -ENOMEM;
2682
2675 eeprom->magic = PCI_VENDOR_ID_NS | (PCI_DEVICE_ID_NS_83815<<16); 2683 eeprom->magic = PCI_VENDOR_ID_NS | (PCI_DEVICE_ID_NS_83815<<16);
2676 spin_lock_irq(&np->lock); 2684 spin_lock_irq(&np->lock);
2677 res = netdev_get_eeprom(dev, eebuf); 2685 res = netdev_get_eeprom(dev, eebuf);
2678 spin_unlock_irq(&np->lock); 2686 spin_unlock_irq(&np->lock);
2679 if (!res) 2687 if (!res)
2680 memcpy(data, eebuf+eeprom->offset, eeprom->len); 2688 memcpy(data, eebuf+eeprom->offset, eeprom->len);
2689 kfree(eebuf);
2681 return res; 2690 return res;
2682} 2691}
2683 2692
@@ -3033,9 +3042,10 @@ static int netdev_get_eeprom(struct net_device *dev, u8 *buf)
3033 int i; 3042 int i;
3034 u16 *ebuf = (u16 *)buf; 3043 u16 *ebuf = (u16 *)buf;
3035 void __iomem * ioaddr = ns_ioaddr(dev); 3044 void __iomem * ioaddr = ns_ioaddr(dev);
3045 struct netdev_private *np = netdev_priv(dev);
3036 3046
3037 /* eeprom_read reads 16 bits, and indexes by 16 bits */ 3047 /* eeprom_read reads 16 bits, and indexes by 16 bits */
3038 for (i = 0; i < NATSEMI_EEPROM_SIZE/2; i++) { 3048 for (i = 0; i < np->eeprom_size/2; i++) {
3039 ebuf[i] = eeprom_read(ioaddr, i); 3049 ebuf[i] = eeprom_read(ioaddr, i);
3040 /* The EEPROM itself stores data bit-swapped, but eeprom_read 3050 /* The EEPROM itself stores data bit-swapped, but eeprom_read
3041 * reads it back "sanely". So we swap it back here in order to 3051 * reads it back "sanely". So we swap it back here in order to