From: Ben Hutchings <bhutchings@solarflare.com>
To: Steve Glendinning <steve.glendinning@smsc.com>
Cc: netdev@vger.kernel.org, Michael.Hennerich@analog.com,
Enrik.Berkhan@ge.com, hennerich@blackfin.uclinux.org,
ian.saturley@smsc.com, uclinux-dist-devel@blackfin.uclinux.org,
catalin.marinas@arm.com, Bahadir Balban <Bahadir.Balban@arm.com>,
Dustin Mcintire <dustin@sensoria.com>,
Bill Gatliff <bgat@billgatliff.com>
Subject: Re: [PATCH] SMSC LAN911x and LAN921x vendor driver
Date: Mon, 2 Jun 2008 16:54:17 +0100 [thread overview]
Message-ID: <20080602155415.GA6192@solarflare.com> (raw)
In-Reply-To: <1212403502-4604-1-git-send-email-steve.glendinning@smsc.com>
Steve Glendinning wrote:
[...]
> +static inline void smsc911x_reg_write(u32 val, struct smsc911x_data *pdata,
> + u32 reg)
It's more common to make the value the last parameter to a write-register
function.
[...]
> +/* Fetches a MAC register value. Assumes phy_lock is acquired */
> +static u32 smsc911x_mac_read(struct smsc911x_data *pdata, unsigned int offset)
> +{
> + unsigned int temp;
> +
> +#ifdef CONFIG_DEBUG_SPINLOCK
> + if (!spin_is_locked(&pdata->phy_lock))
> + SMSC_WARNING("phy_lock not held");
> +#endif /* CONFIG_DEBUG_SPINLOCK */
This is replicated in several functions; why not make it a macro, and use
the standard warning macro:
#ifdef CONFIG_DEBUG_SPINLOCK
#define ASSERT_PHY_LOCK(pdata) WARN_ON(!spin_is_locked(&pdata->phy_lock))
#else
#define ASSERT_PHY_LOCK(pdata) do {} while (0)
#endif
(Also, why is it called phy_lock if it's also used by the MAC access
functions?)
[...]
> +/* Set a mac register, phy_lock must be acquired before calling */
> +static void smsc911x_mac_write(struct smsc911x_data *pdata,
> + unsigned int offset, u32 val)
> +{
> + unsigned int temp;
> +
> +#ifdef CONFIG_DEBUG_SPINLOCK
> + if (!spin_is_locked(&pdata->phy_lock))
> + SMSC_WARNING("phy_lock not held");
> +#endif /* CONFIG_DEBUG_SPINLOCK */
> +
> + temp = smsc911x_reg_read(pdata, MAC_CSR_CMD);
> + if (unlikely(temp & MAC_CSR_CMD_CSR_BUSY_)) {
> + SMSC_WARNING("smsc911x_mac_write failed, MAC busy at entry");
> + return;
> + }
Shouldn't this return an error code?
[...]
> +/* Sets a phy register, phy_lock must be acquired before calling */
> +static void smsc911x_phy_write(struct smsc911x_data *pdata,
> + unsigned int index, u16 val)
> +{
> + unsigned int addr;
> + int i;
> +
> +#ifdef CONFIG_DEBUG_SPINLOCK
> + if (!spin_is_locked(&pdata->phy_lock))
> + SMSC_WARNING("phy_lock not held");
> +#endif /* CONFIG_DEBUG_SPINLOCK */
> +
> + /* Confirm MII not busy */
> + if (unlikely(smsc911x_mac_read(pdata, MII_ACC) & MII_ACC_MII_BUSY_)) {
> + SMSC_WARNING("MII is busy in smsc911x_write_phy???");
> + return;
> + }
Similarly for this function.
[...]
> +/* called by phy_initialise and loopback test */
> +static int smsc911x_phy_reset(struct smsc911x_data *pdata)
> +{
> + unsigned int temp;
> + unsigned int i = 100000;
> + unsigned long flags;
> +
> + SMSC_TRACE("Performing PHY BCR Reset");
> + spin_lock_irqsave(&pdata->phy_lock, flags);
> + smsc911x_phy_write(pdata, MII_BMCR, BMCR_RESET);
> + do {
> + udelay(10);
> + temp = smsc911x_phy_read(pdata, MII_BMCR);
> + } while ((i--) && (temp & BMCR_RESET));
> + spin_unlock_irqrestore(&pdata->phy_lock, flags);
I think this was already mentioned, but that's a very long time to busy-
wait. Maybe you could find a way to block PHY access that doesn't require
holding phy_lock; then you could sleep while waiting.
[...]
> +static int smsc911x_phy_loopbacktest(struct smsc911x_data *pdata)
> +{
> + int result = 0;
> + unsigned int i;
> + unsigned int val;
> + unsigned long flags;
> +
> + /* Initialise tx packet using broadcast destination address */
> + for (i = 0; i < 6; i++)
> + pdata->loopback_tx_pkt[i] = (char)0xFF;
The cast to char is just noise.
[...]
> + /* Set length type field */
> + pdata->loopback_tx_pkt[12] = 0x00;
> + pdata->loopback_tx_pkt[13] = 0x00;
> + for (i = 14; i < MIN_PACKET_SIZE; i++)
> + pdata->loopback_tx_pkt[i] = (char)i;
The comment applies to the following two lines only, so you could do with a
blank line after them.
> + val = smsc911x_reg_read(pdata, HW_CFG);
> + val &= HW_CFG_TX_FIF_SZ_;
> + val |= HW_CFG_SF_;
> + smsc911x_reg_write(val, pdata, HW_CFG);
> +
> + smsc911x_reg_write(TX_CFG_TX_ON_, pdata, TX_CFG);
> + smsc911x_reg_write((((unsigned int)pdata->loopback_rx_pkt)
> + & 0x03) << 8, pdata, RX_CFG);
> +
> + for (i = 0; i < 10; i++) {
> + /* Set PHY to 10/FD, no ANEG, and loopback mode */
> + spin_lock_irqsave(&pdata->phy_lock, flags);
> + smsc911x_phy_write(pdata, MII_BMCR, 0x4100);
You could write BMCR_LOOPBACK | BMCR_FULLDPLX instead of 0x4100; then the
comment is unnecessary.
[...]
> +/* Update link mode if any thing has changed */
> +static void smsc911x_phy_update_linkmode(struct net_device *dev, int init)
[...]
> +#ifdef USE_LED1_WORK_AROUND
Shouldn't this workaround be controlled by platform data or a module
parameter rather than a compile-time option which isn't in Kconfig? I
notice this macro is defined by default, so maybe it shouldn't be
conditional at all.
[...]
> +static int smsc911x_soft_reset(struct smsc911x_data *pdata)
> +{
> + unsigned int timeout;
> + unsigned int temp;
> +
> + /* Reset the LAN911x */
> + smsc911x_reg_write(HW_CFG_SRST_, pdata, HW_CFG);
> + timeout = 10;
> + do {
> + udelay(10);
> + temp = smsc911x_reg_read(pdata, HW_CFG);
> + } while ((--timeout) && (temp & HW_CFG_SRST_));
> +
> + if (unlikely(temp & HW_CFG_SRST_)) {
> + SMSC_WARNING("Failed to complete reset");
> + return -ENODEV;
I think this should be -EIO unless this is only called during probe.
[...]
> +static int smsc911x_open(struct net_device *dev)
[...]
> + timeout = 1000;
> + while (timeout--) {
> + smp_rmb();
I think you're trying to ensure that software_irq_signal is re-read each
time round the loop. For that you should use barrier(), not smp_rmb().
However, msleep() acts as a compiler barrier already. So just remove the
smp_rmb().
> + if (pdata->software_irq_signal)
> + break;
> + msleep(1);
> + }
> +
> + if (!pdata->software_irq_signal) {
> + printk(KERN_WARNING "%s: ISR failed signaling test (IRQ %d)\n",
> + dev->name, dev->irq);
> + return -ENODEV;
> + }
> + SMSC_TRACE("IRQ handler passed test using IRQ %d", dev->irq);
> +
> + printk(KERN_INFO "%s: SMSC911x/921x identified at %#08lx, IRQ: %d\n",
> + dev->name, (unsigned long)pdata->ioaddr, dev->irq);
Should use dev_info().
[...]
> +static void smsc911x_ethtool_getdrvinfo(struct net_device *dev,
> + struct ethtool_drvinfo *info)
> +{
> + strncpy(info->driver, SMSC_CHIPNAME, sizeof(info->driver));
> + strncpy(info->version, SMSC_DRV_VERSION, sizeof(info->version));
> + strncpy(info->bus_info, dev->dev.parent->bus_id,
> + sizeof(info->bus_info));
> +}
Use strlcpy(), not strncpy().
[...]
> +static void smsc911x_ethtool_setmsglevel(struct net_device *dev, u32 level)
> +{
> + struct smsc911x_data *pdata = netdev_priv(dev);
> + pdata->msg_enable = level;
> +}
It would be nice if the logging macros actually tested msg_enable too. ;-)
[...]
> +static int smsc911x_ethtool_get_eeprom(struct net_device *dev,
> + struct ethtool_eeprom *eeprom, u8 *data)
> +{
> + struct smsc911x_data *pdata = netdev_priv(dev);
> + u8 eeprom_data[SMSC911X_EEPROM_SIZE];
> + int len;
> + int i;
> +
> + smsc911x_eeprom_enable_access(pdata);
> +
> + len = min(eeprom->len, SMSC911X_EEPROM_SIZE);
> + for (i = 0; i < len; i++) {
> + int ret = smsc911x_eeprom_read_location(pdata, i, eeprom_data);
> + if (ret < 0) {
> + eeprom->len = 0;
> + return ret;
> + }
> + }
Doesn't this need to take eeprom->offset into account?
[...]
> + printk(KERN_INFO
> + "%s: SMSC911x MAC Address: %02x:%02x:%02x:%02x:%02x:%02x\n",
> + dev->name, dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2],
> + dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]);
This should use print_mac().
[...]
> +/* SMSC911x registers and bitfields */
> +#define RX_DATA_FIFO 0x00
> +
> +#define TX_DATA_FIFO 0x20
> +#define TX_CMD_A_ON_COMP_ 0x80000000
Why do these flag/mask names have trailing underscores?
Ben.
--
Ben Hutchings, Senior Software Engineer, Solarflare Communications
Not speaking for my employer; that's the marketing department's job.
next prev parent reply other threads:[~2008-06-02 15:55 UTC|newest]
Thread overview: 39+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <20080515170728.GA3176@PTXN0038.genpitfi01.og.ge.com>
2008-05-19 12:34 ` [PATCH] SMSC LAN911x and LAN921x vendor driver Steve Glendinning
2008-05-19 15:27 ` [Uclinux-dist-devel] " Mike Frysinger
2008-05-19 15:45 ` Catalin Marinas
2008-05-19 15:50 ` Mike Frysinger
2008-05-19 15:55 ` Catalin Marinas
2008-05-19 16:24 ` Catalin Marinas
2008-05-19 19:06 ` Steve.Glendinning
2008-06-02 10:45 ` Steve Glendinning
2008-06-02 15:54 ` Ben Hutchings [this message]
2008-06-02 16:09 ` Bill Gatliff
2008-06-02 18:32 ` Peter Korsgaard
2008-06-02 18:30 ` Steve.Glendinning
2008-06-02 19:03 ` Ben Hutchings
2008-06-04 16:34 ` Steve.Glendinning
2008-06-02 18:47 ` Peter Korsgaard
2008-10-21 13:00 Steve Glendinning
-- strict thread matches above, loose matches on Subject: below --
2007-07-16 18:54 Steve Glendinning
2007-07-18 22:38 ` Jeff Garzik
2007-07-20 16:22 ` Steve.Glendinning
2007-07-29 20:53 ` Peter Korsgaard
2007-07-30 18:31 ` Steve.Glendinning
2007-08-01 22:27 ` Peter Korsgaard
2007-08-07 23:09 ` Peter Korsgaard
2006-12-30 16:34 Steve Glendinning
2007-01-04 14:42 ` Pierre TARDY
2006-12-04 22:31 Steve Glendinning
2006-07-28 21:38 Francois Romieu
2006-08-01 15:12 ` [PATCH] " Steve Glendinning
2006-08-01 15:33 ` John W. Linville
2006-08-02 19:23 ` Steve.Glendinning
2006-08-02 19:51 ` John W. Linville
2006-08-01 18:28 ` Scott Murray
2006-08-01 19:27 ` Steve.Glendinning
2006-08-01 23:51 ` Scott Murray
2006-08-03 15:26 ` Steve.Glendinning
2006-08-03 21:07 ` Scott Murray
2006-08-01 21:40 ` Francois Romieu
2006-08-02 19:39 ` Steve.Glendinning
2006-08-02 21:07 ` Francois Romieu
2006-08-04 11:29 ` Steve Glendinning
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=20080602155415.GA6192@solarflare.com \
--to=bhutchings@solarflare.com \
--cc=Bahadir.Balban@arm.com \
--cc=Enrik.Berkhan@ge.com \
--cc=Michael.Hennerich@analog.com \
--cc=bgat@billgatliff.com \
--cc=catalin.marinas@arm.com \
--cc=dustin@sensoria.com \
--cc=hennerich@blackfin.uclinux.org \
--cc=ian.saturley@smsc.com \
--cc=netdev@vger.kernel.org \
--cc=steve.glendinning@smsc.com \
--cc=uclinux-dist-devel@blackfin.uclinux.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 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).