From: Ben Hutchings <bhutchings@solarflare.com>
To: David Miller <davem@davemloft.net>
Cc: netdev@vger.kernel.org, linux-net-drivers@solarflare.com
Subject: [PATCH 07/33] sfc: Clean up waits for flash/EEPROM operations
Date: Fri, 12 Dec 2008 12:51:01 +0000 [thread overview]
Message-ID: <20081212125100.GG10372@solarflare.com> (raw)
In-Reply-To: <20081212124622.GK32518@solarflare.com>
Make falcon_spi_wait() ignore the write timer - it is only relevant to
write commands, it only works for the device that contains VPD, and it
might not be initialised properly at all.
Rename falcon_spi_fast_wait() to falcon_spi_wait_write(), reflecting
its use, and make it wait up to 10 ms (not 1 ms) since buffered writes
to EEPROM may take this long to complete.
Make both wait functions sleep instead of busy-waiting.
Replace wait for command completion at top of falcon_spi_cmd() with a
single poll; no command should be running when the function starts.
Correct some comments.
Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
---
drivers/net/sfc/falcon.c | 58 +++++++++++++++++++++++++++++----------------
drivers/net/sfc/mtd.c | 2 +-
drivers/net/sfc/spi.h | 2 +-
3 files changed, 39 insertions(+), 23 deletions(-)
diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c
index 3af361a..4b2ec12 100644
--- a/drivers/net/sfc/falcon.c
+++ b/drivers/net/sfc/falcon.c
@@ -1618,24 +1618,37 @@ void falcon_fini_interrupt(struct efx_nic *efx)
#define FALCON_SPI_MAX_LEN sizeof(efx_oword_t)
+static int falcon_spi_poll(struct efx_nic *efx)
+{
+ efx_oword_t reg;
+ falcon_read(efx, ®, EE_SPI_HCMD_REG_KER);
+ return EFX_OWORD_FIELD(reg, EE_SPI_HCMD_CMD_EN) ? -EBUSY : 0;
+}
+
/* Wait for SPI command completion */
static int falcon_spi_wait(struct efx_nic *efx)
{
- unsigned long timeout = jiffies + DIV_ROUND_UP(HZ, 10);
- efx_oword_t reg;
- bool cmd_en, timer_active;
+ /* Most commands will finish quickly, so we start polling at
+ * very short intervals. Sometimes the command may have to
+ * wait for VPD or expansion ROM access outside of our
+ * control, so we allow up to 100 ms. */
+ unsigned long timeout = jiffies + 1 + DIV_ROUND_UP(HZ, 10);
+ int i;
+
+ for (i = 0; i < 10; i++) {
+ if (!falcon_spi_poll(efx))
+ return 0;
+ udelay(10);
+ }
for (;;) {
- falcon_read(efx, ®, EE_SPI_HCMD_REG_KER);
- cmd_en = EFX_OWORD_FIELD(reg, EE_SPI_HCMD_CMD_EN);
- timer_active = EFX_OWORD_FIELD(reg, EE_WR_TIMER_ACTIVE);
- if (!cmd_en && !timer_active)
+ if (!falcon_spi_poll(efx))
return 0;
if (time_after_eq(jiffies, timeout)) {
EFX_ERR(efx, "timed out waiting for SPI\n");
return -ETIMEDOUT;
}
- cpu_relax();
+ schedule_timeout_uninterruptible(1);
}
}
@@ -1654,8 +1667,8 @@ int falcon_spi_cmd(const struct efx_spi_device *spi,
return -EINVAL;
BUG_ON(!mutex_is_locked(&efx->spi_lock));
- /* Check SPI not currently being accessed */
- rc = falcon_spi_wait(efx);
+ /* Check that previous command is not still running */
+ rc = falcon_spi_poll(efx);
if (rc)
return rc;
@@ -1711,26 +1724,29 @@ efx_spi_munge_command(const struct efx_spi_device *spi,
return command | (((address >> 8) & spi->munge_address) << 3);
}
-int falcon_spi_fast_wait(const struct efx_spi_device *spi)
+/* Wait up to 10 ms for buffered write completion */
+int falcon_spi_wait_write(const struct efx_spi_device *spi)
{
+ struct efx_nic *efx = spi->efx;
+ unsigned long timeout = jiffies + 1 + DIV_ROUND_UP(HZ, 100);
u8 status;
- int i, rc;
-
- /* Wait up to 1000us for flash/EEPROM to finish a fast operation. */
- for (i = 0; i < 50; i++) {
- udelay(20);
+ int rc;
+ for (;;) {
rc = falcon_spi_cmd(spi, SPI_RDSR, -1, NULL,
&status, sizeof(status));
if (rc)
return rc;
if (!(status & SPI_STATUS_NRDY))
return 0;
+ if (time_after_eq(jiffies, timeout)) {
+ EFX_ERR(efx, "SPI write timeout on device %d"
+ " last status=0x%02x\n",
+ spi->device_id, status);
+ return -ETIMEDOUT;
+ }
+ schedule_timeout_uninterruptible(1);
}
- EFX_ERR(spi->efx,
- "timed out waiting for device %d last status=0x%02x\n",
- spi->device_id, status);
- return -ETIMEDOUT;
}
int falcon_spi_read(const struct efx_spi_device *spi, loff_t start,
@@ -1784,7 +1800,7 @@ int falcon_spi_write(const struct efx_spi_device *spi, loff_t start,
if (rc)
break;
- rc = falcon_spi_fast_wait(spi);
+ rc = falcon_spi_wait_write(spi);
if (rc)
break;
diff --git a/drivers/net/sfc/mtd.c b/drivers/net/sfc/mtd.c
index a1e6c28..665cafb 100644
--- a/drivers/net/sfc/mtd.c
+++ b/drivers/net/sfc/mtd.c
@@ -76,7 +76,7 @@ static int efx_spi_unlock(const struct efx_spi_device *spi)
rc = falcon_spi_cmd(spi, SPI_WRSR, -1, &status, NULL, sizeof(status));
if (rc)
return rc;
- rc = falcon_spi_fast_wait(spi);
+ rc = falcon_spi_wait_write(spi);
if (rc)
return rc;
diff --git a/drivers/net/sfc/spi.h b/drivers/net/sfc/spi.h
index c4aca13..4e45d54 100644
--- a/drivers/net/sfc/spi.h
+++ b/drivers/net/sfc/spi.h
@@ -69,7 +69,7 @@ struct efx_spi_device {
int falcon_spi_cmd(const struct efx_spi_device *spi, unsigned int command,
int address, const void* in, void *out, unsigned int len);
-int falcon_spi_fast_wait(const struct efx_spi_device *spi);
+int falcon_spi_wait_write(const struct efx_spi_device *spi);
int falcon_spi_read(const struct efx_spi_device *spi, loff_t start,
size_t len, size_t *retlen, u8 *buffer);
int falcon_spi_write(const struct efx_spi_device *spi, loff_t start,
--
Ben Hutchings, Senior Software Engineer, Solarflare Communications
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.
next prev parent reply other threads:[~2008-12-12 12:51 UTC|newest]
Thread overview: 74+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <cover.1229085672.git.bhutchings@solarflare.com>
2008-12-12 12:46 ` [PATCH 00/33] sfc version 2.3 Ben Hutchings
2008-12-12 12:48 ` [PATCH 01/33] sfc: Board support fixes Ben Hutchings
2008-12-13 5:29 ` David Miller
2008-12-12 12:48 ` [PATCH 02/33] sfc: Change SPI lengths to type size_t Ben Hutchings
2008-12-13 5:30 ` David Miller
2008-12-13 5:53 ` David Miller
2008-12-13 6:30 ` Ben Hutchings
2008-12-12 12:49 ` [PATCH 03/33] sfc: Do not use pci_disable_device() to disable bus mastering Ben Hutchings
2008-12-13 5:31 ` David Miller
2008-12-13 6:27 ` Ben Hutchings
2008-12-12 12:49 ` [PATCH 04/33] sfc: Remove unneeded register write Ben Hutchings
2008-12-13 5:31 ` David Miller
2008-12-12 12:49 ` [PATCH 05/33] sfc: Correct interpretation of second param to ethtool phys_id() Ben Hutchings
2008-12-13 5:32 ` David Miller
2008-12-12 12:50 ` [PATCH 06/33] sfc: Make reset_workqueue driver-global rather than per-NIC Ben Hutchings
2008-12-13 5:33 ` David Miller
2008-12-12 12:51 ` Ben Hutchings [this message]
2008-12-13 5:33 ` [PATCH 07/33] sfc: Clean up waits for flash/EEPROM operations David Miller
2008-12-12 12:51 ` [PATCH 08/33] sfc: Work around unreliable strap pins Ben Hutchings
2008-12-13 5:34 ` David Miller
2008-12-12 12:51 ` [PATCH 09/33] sfc: Restore phy_flash_cfg module parameter Ben Hutchings
2008-12-13 5:35 ` David Miller
2008-12-12 12:53 ` [PATCH 13/33] sfc: Don't count RX checksum errors during loopback self-test Ben Hutchings
2008-12-13 5:42 ` David Miller
2008-12-12 12:53 ` [PATCH 14/33] sfc: Remove MII extension cruft Ben Hutchings
2008-12-13 5:43 ` David Miller
2008-12-12 12:53 ` [PATCH 15/33] sfc: Add support for MMDs numbered >15 Ben Hutchings
2008-12-13 5:44 ` David Miller
2008-12-12 12:54 ` [PATCH 16/33] sfc: Add phy_type device attribute Ben Hutchings
2008-12-13 5:47 ` David Miller
2008-12-12 12:54 ` [PATCH 17/33] sfc: Clean up board identification Ben Hutchings
2008-12-13 5:48 ` David Miller
2008-12-12 12:54 ` [PATCH 18/33] sfc: Clean up MDIO flag setting Ben Hutchings
2008-12-13 5:49 ` David Miller
2008-12-12 12:54 ` [PATCH 19/33] sfc: Add support for sub-10G speeds Ben Hutchings
2008-12-13 5:50 ` David Miller
2008-12-12 12:55 ` [PATCH 20/33] sfc: Implement auto-negotiation Ben Hutchings
2008-12-13 5:50 ` David Miller
2008-12-12 12:55 ` [PATCH 21/33] sfc: Rework MAC, PHY and board event handling Ben Hutchings
2008-12-13 5:59 ` David Miller
2008-12-12 12:56 ` [PATCH 22/33] sfc: Add support for Solarflare 10Xpress SFT9001 Ben Hutchings
2008-12-13 6:00 ` David Miller
2008-12-12 12:56 ` [PATCH 23/33] sfc: Add support for SFN4111T Ben Hutchings
2008-12-13 6:01 ` David Miller
2008-12-12 12:56 ` [PATCH 25/33] sfc: Generate unique names for per-NIC workqueues Ben Hutchings
2008-12-13 6:04 ` David Miller
2008-12-13 6:23 ` Ben Hutchings
2008-12-13 6:29 ` David Miller
2008-12-13 14:01 ` Ben Hutchings
2008-12-12 12:57 ` [PATCH 26/33] sfc: Remove leading spaces Ben Hutchings
2008-12-13 6:05 ` David Miller
2008-12-12 12:57 ` [PATCH 27/33] sfc: Specify a meaningful component for loopback RX-side and PHY tests Ben Hutchings
2008-12-13 6:05 ` David Miller
2008-12-12 12:59 ` [PATCH 28/33] sfc: Use mutex_lock_interruptible() for ethtool EEPROM access Ben Hutchings
2008-12-13 6:06 ` David Miller
2008-12-12 12:59 ` [PATCH 29/33] sfc: Use model numbers for PHY type names Ben Hutchings
2008-12-13 6:07 ` David Miller
2008-12-12 13:00 ` [PATCH 30/33] sfc: Treat probe as unsuccessful if it scheduled a reset Ben Hutchings
2008-12-13 6:08 ` David Miller
2008-12-12 13:00 ` [PATCH 31/33] sfc: Use kzalloc() to ensure struct efx_spi_device is fully initialised Ben Hutchings
2008-12-13 6:09 ` David Miller
2008-12-12 12:52 ` [PATCH 10/33] sfc: Add option to use a separate channel for TX completions Ben Hutchings
2008-12-13 5:36 ` David Miller
2008-12-12 12:52 ` [PATCH 11/33] sfc: Provide hints to irqbalance daemon Ben Hutchings
2008-12-13 5:37 ` David Miller
2008-12-12 12:52 ` [PATCH 12/33] sfc: Abbreviate self-test names so they are not truncated Ben Hutchings
2008-12-13 5:42 ` David Miller
2008-12-12 12:56 ` [PATCH 24/33] sfc: Fix format arguments for warning about MSI-X allocation Ben Hutchings
2008-12-12 20:34 ` Ben Hutchings
2008-12-13 5:25 ` David Miller
2008-12-12 13:00 ` [PATCH 32/33] sfc: Fix synchronisation of efx_mtd_{probe,rename,remove} Ben Hutchings
2008-12-13 6:09 ` David Miller
2008-12-12 13:01 ` [PATCH 33/33] sfc: Version 2.3 Ben Hutchings
2008-12-13 6:10 ` 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=20081212125100.GG10372@solarflare.com \
--to=bhutchings@solarflare.com \
--cc=davem@davemloft.net \
--cc=linux-net-drivers@solarflare.com \
--cc=netdev@vger.kernel.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).