forked from luck/tmp_suning_uos_patched
[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>
This commit is contained in:
parent
8dfc914a3f
commit
a8b4cf42cf
@ -226,7 +226,7 @@ static int full_duplex[MAX_UNITS];
|
|||||||
NATSEMI_PG1_NREGS)
|
NATSEMI_PG1_NREGS)
|
||||||
#define NATSEMI_REGS_VER 1 /* v1 added RFDR registers */
|
#define NATSEMI_REGS_VER 1 /* v1 added RFDR registers */
|
||||||
#define NATSEMI_REGS_SIZE (NATSEMI_NREGS * sizeof(u32))
|
#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:
|
/* Buffer sizes:
|
||||||
* The nic writes 32-bit values, even if the upper bytes of
|
* The nic writes 32-bit values, even if the upper bytes of
|
||||||
@ -714,6 +714,8 @@ struct netdev_private {
|
|||||||
unsigned int iosize;
|
unsigned int iosize;
|
||||||
spinlock_t lock;
|
spinlock_t lock;
|
||||||
u32 msg_enable;
|
u32 msg_enable;
|
||||||
|
/* EEPROM data */
|
||||||
|
int eeprom_size;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void move_int_phy(struct net_device *dev, int addr);
|
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<<debug)-1 : NATSEMI_DEF_MSG;
|
np->msg_enable = (debug >= 0) ? (1<<debug)-1 : NATSEMI_DEF_MSG;
|
||||||
np->hands_off = 0;
|
np->hands_off = 0;
|
||||||
np->intr_status = 0;
|
np->intr_status = 0;
|
||||||
|
np->eeprom_size = NATSEMI_DEF_EEPROM_SIZE;
|
||||||
|
|
||||||
/* Initial port:
|
/* Initial port:
|
||||||
* - If the nic was configured to use an external phy and if find_mii
|
* - 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)
|
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)
|
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)
|
static int get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, u8 *data)
|
||||||
{
|
{
|
||||||
struct netdev_private *np = netdev_priv(dev);
|
struct netdev_private *np = netdev_priv(dev);
|
||||||
u8 eebuf[NATSEMI_EEPROM_SIZE];
|
u8 *eebuf;
|
||||||
int res;
|
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);
|
eeprom->magic = PCI_VENDOR_ID_NS | (PCI_DEVICE_ID_NS_83815<<16);
|
||||||
spin_lock_irq(&np->lock);
|
spin_lock_irq(&np->lock);
|
||||||
res = netdev_get_eeprom(dev, eebuf);
|
res = netdev_get_eeprom(dev, eebuf);
|
||||||
spin_unlock_irq(&np->lock);
|
spin_unlock_irq(&np->lock);
|
||||||
if (!res)
|
if (!res)
|
||||||
memcpy(data, eebuf+eeprom->offset, eeprom->len);
|
memcpy(data, eebuf+eeprom->offset, eeprom->len);
|
||||||
|
kfree(eebuf);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3033,9 +3042,10 @@ static int netdev_get_eeprom(struct net_device *dev, u8 *buf)
|
|||||||
int i;
|
int i;
|
||||||
u16 *ebuf = (u16 *)buf;
|
u16 *ebuf = (u16 *)buf;
|
||||||
void __iomem * ioaddr = ns_ioaddr(dev);
|
void __iomem * ioaddr = ns_ioaddr(dev);
|
||||||
|
struct netdev_private *np = netdev_priv(dev);
|
||||||
|
|
||||||
/* eeprom_read reads 16 bits, and indexes by 16 bits */
|
/* 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);
|
ebuf[i] = eeprom_read(ioaddr, i);
|
||||||
/* The EEPROM itself stores data bit-swapped, but eeprom_read
|
/* The EEPROM itself stores data bit-swapped, but eeprom_read
|
||||||
* reads it back "sanely". So we swap it back here in order to
|
* reads it back "sanely". So we swap it back here in order to
|
||||||
|
Loading…
Reference in New Issue
Block a user