* [PATCH] smc91x: enable ethtool EEPROM interface @ 2009-01-16 4:53 Vernon Sauder 2009-01-16 5:06 ` Nicolas Pitre 0 siblings, 1 reply; 6+ messages in thread From: Vernon Sauder @ 2009-01-16 4:53 UTC (permalink / raw) To: nico; +Cc: netdev From: Vernon Sauder <vsauder@inhand.com> Signed-off-by: Vernon Sauder <vsauder@inhand.com> --- drivers/net/smc91x.c | 112 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 files changed, 110 insertions(+), 2 deletions(-) diff --git a/drivers/net/smc91x.c b/drivers/net/smc91x.c index b215a8d..f692439 100644 --- a/drivers/net/smc91x.c +++ b/drivers/net/smc91x.c @@ -1643,6 +1643,113 @@ static void smc_ethtool_setmsglevel(struct net_device *dev, u32 level) lp->msg_enable = level; } +/* GP is same as RPC, just bank 1 */ +#define SMC_GET_GP SMC_GET_RPC +#define SMC_SET_GP SMC_SET_RPC + +static int smc_write_eeprom_word(struct net_device *dev, u16 addr, u16 word) +{ + 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); + u16 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) +{ + 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 */ + u16 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, ret; + + DBG(1, "Reading %d bytes at %d(0x%x)\n", + eeprom->len, eeprom->offset, eeprom->offset); + int imax = smc_ethtool_geteeprom_len(dev); + for (i = 0; i < eeprom->len; i += 2) { + int offset = i + eeprom->offset; + if (offset > imax) + break; + u16 wbuf; + 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, ret; + + DBG(1, "Writing %d bytes to %d(0x%x)\n", + eeprom->len, eeprom->offset, eeprom->offset); + int imax = smc_ethtool_geteeprom_len(dev); + for (i = 0; i < eeprom->len; i += 2) { + int offset = i + eeprom->offset; + if (offset > imax) + break; + u16 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, @@ -1652,8 +1759,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, }; /* -- 1.6.1 ^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH] smc91x: enable ethtool EEPROM interface 2009-01-16 4:53 [PATCH] smc91x: enable ethtool EEPROM interface Vernon Sauder @ 2009-01-16 5:06 ` Nicolas Pitre 2009-01-16 17:28 ` Vernon Sauder 0 siblings, 1 reply; 6+ messages in thread From: Nicolas Pitre @ 2009-01-16 5:06 UTC (permalink / raw) To: Vernon Sauder; +Cc: netdev On Thu, 15 Jan 2009, Vernon Sauder wrote: > From: Vernon Sauder <vsauder@inhand.com> > > > Signed-off-by: Vernon Sauder <vsauder@inhand.com> > --- > drivers/net/smc91x.c | 112 +++++++++++++++++++++++++++++++++++++++++++++++++- > 1 files changed, 110 insertions(+), 2 deletions(-) > > diff --git a/drivers/net/smc91x.c b/drivers/net/smc91x.c > index b215a8d..f692439 100644 > --- a/drivers/net/smc91x.c > +++ b/drivers/net/smc91x.c > @@ -1643,6 +1643,113 @@ static void smc_ethtool_setmsglevel(struct net_device *dev, u32 level) > lp->msg_enable = level; > } > > +/* GP is same as RPC, just bank 1 */ > +#define SMC_GET_GP SMC_GET_RPC > +#define SMC_SET_GP SMC_SET_RPC NAK. This will blow up the moment you have SMC_DEBUG > 0. Please add proper definitions in smc91x.h instead. Nicolas ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] smc91x: enable ethtool EEPROM interface 2009-01-16 5:06 ` Nicolas Pitre @ 2009-01-16 17:28 ` Vernon Sauder 2009-01-16 18:35 ` Nicolas Pitre 0 siblings, 1 reply; 6+ messages in thread From: Vernon Sauder @ 2009-01-16 17:28 UTC (permalink / raw) To: Nicolas Pitre; +Cc: netdev Nicolas Pitre wrote: >On Thu, 15 Jan 2009, Vernon Sauder wrote: > >> From: Vernon Sauder <vsauder@inhand.com> >> >> >> Signed-off-by: Vernon Sauder <vsauder@inhand.com> >> --- >> drivers/net/smc91x.c | 112 +++++++++++++++++++++++++++++++++++++++++++++++++- >> 1 files changed, 110 insertions(+), 2 deletions(-) >> >> diff --git a/drivers/net/smc91x.c b/drivers/net/smc91x.c >> index b215a8d..f692439 100644 >> --- a/drivers/net/smc91x.c >> +++ b/drivers/net/smc91x.c >> @@ -1643,6 +1643,113 @@ static void smc_ethtool_setmsglevel(struct net_device *dev, u32 level) >> lp->msg_enable = level; >> } >> >> +/* GP is same as RPC, just bank 1 */ >> +#define SMC_GET_GP SMC_GET_RPC >> +#define SMC_SET_GP SMC_SET_RPC > >NAK. This will blow up the moment you have SMC_DEBUG > 0. >Please add proper definitions in smc91x.h instead. > > >Nicolas Sorry about that. This was an old patch before bank checking. Here is an update. From: Vernon Sauder <vsauder@inhand.com> Date: Fri, 16 Jan 2009 12:05:42 -0500 Subject: [PATCH] smc91x: enable ethtool EEPROM interface Signed-off-by: Vernon Sauder <vsauder@inhand.com> --- drivers/net/smc91x.c | 108 +++++++++++++++++++++++++++++++++++++++++++++++++- drivers/net/smc91x.h | 10 +++++ 2 files changed, 116 insertions(+), 2 deletions(-) diff --git a/drivers/net/smc91x.c b/drivers/net/smc91x.c index b215a8d..ba802f5 100644 --- a/drivers/net/smc91x.c +++ b/drivers/net/smc91x.c @@ -1643,6 +1643,109 @@ 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) +{ + 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); + u16 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) +{ + 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 */ + u16 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, ret; + + DBG(1, "Reading %d bytes at %d(0x%x)\n", + eeprom->len, eeprom->offset, eeprom->offset); + int imax = smc_ethtool_geteeprom_len(dev); + for (i = 0; i < eeprom->len; i += 2) { + int offset = i + eeprom->offset; + if (offset > imax) + break; + u16 wbuf; + 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, ret; + + DBG(1, "Writing %d bytes to %d(0x%x)\n", + eeprom->len, eeprom->offset, eeprom->offset); + int imax = smc_ethtool_geteeprom_len(dev); + for (i = 0; i < eeprom->len; i += 2) { + int offset = i + eeprom->offset; + if (offset > imax) + break; + u16 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, @@ -1652,8 +1755,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, }; /* diff --git a/drivers/net/smc91x.h b/drivers/net/smc91x.h index c4ccd12..ed9ae43 100644 --- a/drivers/net/smc91x.h +++ b/drivers/net/smc91x.h @@ -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)) -- 1.6.1 ^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH] smc91x: enable ethtool EEPROM interface 2009-01-16 17:28 ` Vernon Sauder @ 2009-01-16 18:35 ` Nicolas Pitre 2009-01-16 23:23 ` Vernon Sauder 0 siblings, 1 reply; 6+ messages in thread From: Nicolas Pitre @ 2009-01-16 18:35 UTC (permalink / raw) To: Vernon Sauder; +Cc: netdev On Fri, 16 Jan 2009, Vernon Sauder wrote: > Sorry about that. This was an old patch before bank checking. Here is an update. > > From: Vernon Sauder <vsauder@inhand.com> > Date: Fri, 16 Jan 2009 12:05:42 -0500 > Subject: [PATCH] smc91x: enable ethtool EEPROM interface > > > Signed-off-by: Vernon Sauder <vsauder@inhand.com> > --- > drivers/net/smc91x.c | 108 +++++++++++++++++++++++++++++++++++++++++++++++++- > drivers/net/smc91x.h | 10 +++++ > 2 files changed, 116 insertions(+), 2 deletions(-) > > diff --git a/drivers/net/smc91x.c b/drivers/net/smc91x.c > index b215a8d..ba802f5 100644 > --- a/drivers/net/smc91x.c > +++ b/drivers/net/smc91x.c > @@ -1643,6 +1643,109 @@ 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) > +{ > + 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); > + u16 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) > +{ > + 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 */ > + u16 ctl = SMC_GET_CTL(lp); Don't put variable declaration in the middle of code sequences. Not all gcc versions support C++ variable declaration style. > + 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, ret; > + > + DBG(1, "Reading %d bytes at %d(0x%x)\n", > + eeprom->len, eeprom->offset, eeprom->offset); > + int imax = smc_ethtool_geteeprom_len(dev); > + for (i = 0; i < eeprom->len; i += 2) { > + int offset = i + eeprom->offset; > + if (offset > imax) > + break; > + u16 wbuf; Same here. > + 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, ret; > + > + DBG(1, "Writing %d bytes to %d(0x%x)\n", > + eeprom->len, eeprom->offset, eeprom->offset); > + int imax = smc_ethtool_geteeprom_len(dev); Same here. > + for (i = 0; i < eeprom->len; i += 2) { > + int offset = i + eeprom->offset; > + if (offset > imax) > + break; > + u16 wbuf = (data[i] << 8) | data[i + 1]; Same here. With those fixed you can resubmit with my ACK. Nicolas ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] smc91x: enable ethtool EEPROM interface 2009-01-16 18:35 ` Nicolas Pitre @ 2009-01-16 23:23 ` Vernon Sauder 2009-01-20 1:08 ` David Miller 0 siblings, 1 reply; 6+ messages in thread From: Vernon Sauder @ 2009-01-16 23:23 UTC (permalink / raw) To: Nicolas Pitre; +Cc: netdev Nicolas Pitre wrote, On 01/16/2009 01:35 PM: <snip> > > With those fixed you can resubmit with my ACK. > > > Nicolas Thanks. I fixed the variable declarations. I thought the patch checker would catch them but it doesn't. Here is the updated patch. Let me know if I should have started a new thread or if it is acceptable to append new patches to the end of a thread to preserve history. Vern --- From: Vernon Sauder <vsauder@inhand.com> Subject: [PATCH] smc91x: enable ethtool EEPROM interface Signed-off-by: Vernon Sauder <vsauder@inhand.com> Acked-by: Nicolas Pitre <nico@cam.org> --- Applies to latest Linus tree. drivers/net/smc91x.c | 116 +++++++++++++++++++++++++++++++++++++++++++++++++- drivers/net/smc91x.h | 10 ++++ 2 files changed, 124 insertions(+), 2 deletions(-) diff --git a/drivers/net/smc91x.c b/drivers/net/smc91x.c index b215a8d..508e8da 100644 --- a/drivers/net/smc91x.c +++ b/drivers/net/smc91x.c @@ -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, @@ -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, }; /* diff --git a/drivers/net/smc91x.h b/drivers/net/smc91x.h index c4ccd12..ed9ae43 100644 --- a/drivers/net/smc91x.h +++ b/drivers/net/smc91x.h @@ -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)) -- 1.6.1 ^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH] smc91x: enable ethtool EEPROM interface 2009-01-16 23:23 ` Vernon Sauder @ 2009-01-20 1:08 ` David Miller 0 siblings, 0 replies; 6+ messages in thread From: David Miller @ 2009-01-20 1:08 UTC (permalink / raw) To: vernoninhand; +Cc: nico, netdev From: Vernon Sauder <vernoninhand@gmail.com> Date: Fri, 16 Jan 2009 18:23:19 -0500 > Signed-off-by: Vernon Sauder <vsauder@inhand.com> > Acked-by: Nicolas Pitre <nico@cam.org> Applied, thanks. ^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2009-01-20 1:08 UTC | newest] Thread overview: 6+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2009-01-16 4:53 [PATCH] smc91x: enable ethtool EEPROM interface Vernon Sauder 2009-01-16 5:06 ` Nicolas Pitre 2009-01-16 17:28 ` Vernon Sauder 2009-01-16 18:35 ` Nicolas Pitre 2009-01-16 23:23 ` Vernon Sauder 2009-01-20 1:08 ` David Miller
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).