All of lore.kernel.org
 help / color / mirror / Atom feed
From: Vernon Sauder <vernoninhand@gmail.com>
To: Nicolas Pitre <nico@cam.org>
Cc: netdev@vger.kernel.org
Subject: Re: [PATCH] smc91x: enable ethtool EEPROM interface
Date: Fri, 16 Jan 2009 12:28:20 -0500	[thread overview]
Message-ID: <4970C3B4.1040006@gmail.com> (raw)
In-Reply-To: <alpine.LFD.2.00.0901160004110.9524@xanadu.home>

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


  reply	other threads:[~2009-01-16 17:28 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
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 [this message]
2009-01-16 18:35     ` Nicolas Pitre
2009-01-16 23:23       ` Vernon Sauder
2009-01-20  1:08         ` David Miller

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4970C3B4.1040006@gmail.com \
    --to=vernoninhand@gmail.com \
    --cc=netdev@vger.kernel.org \
    --cc=nico@cam.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.