Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 133859
b: refs/heads/master
c: 357fe2c
h: refs/heads/master
i:
  133857: fa4bda6
  133855: f10832d
v: v3
  • Loading branch information
Vernon Sauder authored and David S. Miller committed Jan 21, 2009
1 parent 198d62b commit 45d7336
Show file tree
Hide file tree
Showing 3 changed files with 125 additions and 3 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 31e2b7bd21035cb3d7cd567dfdf4f82817c4f6fb
refs/heads/master: 357fe2c6d2b12482abd1c3f24a086a2f507f03fc
116 changes: 114 additions & 2 deletions trunk/drivers/net/smc91x.c
Original file line number Diff line number Diff line change
Expand Up @@ -1643,6 +1643,117 @@ static void smc_ethtool_setmsglevel(struct net_device *dev, u32 level)
lp->msg_enable = level;
}

static int smc_write_eeprom_word(struct net_device *dev, u16 addr, u16 word)
{
u16 ctl;
struct smc_local *lp = netdev_priv(dev);
void __iomem *ioaddr = lp->base;

spin_lock_irq(&lp->lock);
/* load word into GP register */
SMC_SELECT_BANK(lp, 1);
SMC_SET_GP(lp, word);
/* set the address to put the data in EEPROM */
SMC_SELECT_BANK(lp, 2);
SMC_SET_PTR(lp, addr);
/* tell it to write */
SMC_SELECT_BANK(lp, 1);
ctl = SMC_GET_CTL(lp);
SMC_SET_CTL(lp, ctl | (CTL_EEPROM_SELECT | CTL_STORE));
/* wait for it to finish */
do {
udelay(1);
} while (SMC_GET_CTL(lp) & CTL_STORE);
/* clean up */
SMC_SET_CTL(lp, ctl);
SMC_SELECT_BANK(lp, 2);
spin_unlock_irq(&lp->lock);
return 0;
}

static int smc_read_eeprom_word(struct net_device *dev, u16 addr, u16 *word)
{
u16 ctl;
struct smc_local *lp = netdev_priv(dev);
void __iomem *ioaddr = lp->base;

spin_lock_irq(&lp->lock);
/* set the EEPROM address to get the data from */
SMC_SELECT_BANK(lp, 2);
SMC_SET_PTR(lp, addr | PTR_READ);
/* tell it to load */
SMC_SELECT_BANK(lp, 1);
SMC_SET_GP(lp, 0xffff); /* init to known */
ctl = SMC_GET_CTL(lp);
SMC_SET_CTL(lp, ctl | (CTL_EEPROM_SELECT | CTL_RELOAD));
/* wait for it to finish */
do {
udelay(1);
} while (SMC_GET_CTL(lp) & CTL_RELOAD);
/* read word from GP register */
*word = SMC_GET_GP(lp);
/* clean up */
SMC_SET_CTL(lp, ctl);
SMC_SELECT_BANK(lp, 2);
spin_unlock_irq(&lp->lock);
return 0;
}

static int smc_ethtool_geteeprom_len(struct net_device *dev)
{
return 0x23 * 2;
}

static int smc_ethtool_geteeprom(struct net_device *dev,
struct ethtool_eeprom *eeprom, u8 *data)
{
int i;
int imax;

DBG(1, "Reading %d bytes at %d(0x%x)\n",
eeprom->len, eeprom->offset, eeprom->offset);
imax = smc_ethtool_geteeprom_len(dev);
for (i = 0; i < eeprom->len; i += 2) {
int ret;
u16 wbuf;
int offset = i + eeprom->offset;
if (offset > imax)
break;
ret = smc_read_eeprom_word(dev, offset >> 1, &wbuf);
if (ret != 0)
return ret;
DBG(2, "Read 0x%x from 0x%x\n", wbuf, offset >> 1);
data[i] = (wbuf >> 8) & 0xff;
data[i+1] = wbuf & 0xff;
}
return 0;
}

static int smc_ethtool_seteeprom(struct net_device *dev,
struct ethtool_eeprom *eeprom, u8 *data)
{
int i;
int imax;

DBG(1, "Writing %d bytes to %d(0x%x)\n",
eeprom->len, eeprom->offset, eeprom->offset);
imax = smc_ethtool_geteeprom_len(dev);
for (i = 0; i < eeprom->len; i += 2) {
int ret;
u16 wbuf;
int offset = i + eeprom->offset;
if (offset > imax)
break;
wbuf = (data[i] << 8) | data[i + 1];
DBG(2, "Writing 0x%x to 0x%x\n", wbuf, offset >> 1);
ret = smc_write_eeprom_word(dev, offset >> 1, wbuf);
if (ret != 0)
return ret;
}
return 0;
}


static const struct ethtool_ops smc_ethtool_ops = {
.get_settings = smc_ethtool_getsettings,
.set_settings = smc_ethtool_setsettings,
Expand All @@ -1652,8 +1763,9 @@ static const struct ethtool_ops smc_ethtool_ops = {
.set_msglevel = smc_ethtool_setmsglevel,
.nway_reset = smc_ethtool_nwayreset,
.get_link = ethtool_op_get_link,
// .get_eeprom = smc_ethtool_geteeprom,
// .set_eeprom = smc_ethtool_seteeprom,
.get_eeprom_len = smc_ethtool_geteeprom_len,
.get_eeprom = smc_ethtool_geteeprom,
.set_eeprom = smc_ethtool_seteeprom,
};

/*
Expand Down
10 changes: 10 additions & 0 deletions trunk/drivers/net/smc91x.h
Original file line number Diff line number Diff line change
Expand Up @@ -1141,6 +1141,16 @@ static const char * chip_ids[ 16 ] = {

#define SMC_GET_MII(lp) SMC_inw(ioaddr, MII_REG(lp))

#define SMC_GET_GP(lp) SMC_inw(ioaddr, GP_REG(lp))

#define SMC_SET_GP(lp, x) \
do { \
if (SMC_MUST_ALIGN_WRITE(lp)) \
SMC_outl((x)<<16, ioaddr, SMC_REG(lp, 8, 1)); \
else \
SMC_outw(x, ioaddr, GP_REG(lp)); \
} while (0)

#define SMC_SET_MII(lp, x) SMC_outw(x, ioaddr, MII_REG(lp))

#define SMC_GET_MIR(lp) SMC_inw(ioaddr, MIR_REG(lp))
Expand Down

0 comments on commit 45d7336

Please sign in to comment.