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 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.