aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/sfc
diff options
context:
space:
mode:
authorBen Hutchings <bhutchings@solarflare.com>2008-12-13 00:33:50 -0500
committerDavid S. Miller <davem@davemloft.net>2008-12-13 00:57:35 -0500
commitbe4ea89c8df06f48d0d64cf1d9d20009e83c77c8 (patch)
treefb48f89ea32ef55e336242e33d6ccfd1f5ff4295 /drivers/net/sfc
parent1ab00629f06fb3c47de6373cd92d086f33775444 (diff)
sfc: Clean up waits for flash/EEPROM operations
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> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/sfc')
-rw-r--r--drivers/net/sfc/falcon.c58
-rw-r--r--drivers/net/sfc/mtd.c2
-rw-r--r--drivers/net/sfc/spi.h2
3 files changed, 39 insertions, 23 deletions
diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c
index 1d160daf83bb..511308560487 100644
--- a/drivers/net/sfc/falcon.c
+++ b/drivers/net/sfc/falcon.c
@@ -1607,24 +1607,37 @@ void falcon_fini_interrupt(struct efx_nic *efx)
1607 1607
1608#define FALCON_SPI_MAX_LEN sizeof(efx_oword_t) 1608#define FALCON_SPI_MAX_LEN sizeof(efx_oword_t)
1609 1609
1610static int falcon_spi_poll(struct efx_nic *efx)
1611{
1612 efx_oword_t reg;
1613 falcon_read(efx, &reg, EE_SPI_HCMD_REG_KER);
1614 return EFX_OWORD_FIELD(reg, EE_SPI_HCMD_CMD_EN) ? -EBUSY : 0;
1615}
1616
1610/* Wait for SPI command completion */ 1617/* Wait for SPI command completion */
1611static int falcon_spi_wait(struct efx_nic *efx) 1618static int falcon_spi_wait(struct efx_nic *efx)
1612{ 1619{
1613 unsigned long timeout = jiffies + DIV_ROUND_UP(HZ, 10); 1620 /* Most commands will finish quickly, so we start polling at
1614 efx_oword_t reg; 1621 * very short intervals. Sometimes the command may have to
1615 bool cmd_en, timer_active; 1622 * wait for VPD or expansion ROM access outside of our
1623 * control, so we allow up to 100 ms. */
1624 unsigned long timeout = jiffies + 1 + DIV_ROUND_UP(HZ, 10);
1625 int i;
1626
1627 for (i = 0; i < 10; i++) {
1628 if (!falcon_spi_poll(efx))
1629 return 0;
1630 udelay(10);
1631 }
1616 1632
1617 for (;;) { 1633 for (;;) {
1618 falcon_read(efx, &reg, EE_SPI_HCMD_REG_KER); 1634 if (!falcon_spi_poll(efx))
1619 cmd_en = EFX_OWORD_FIELD(reg, EE_SPI_HCMD_CMD_EN);
1620 timer_active = EFX_OWORD_FIELD(reg, EE_WR_TIMER_ACTIVE);
1621 if (!cmd_en && !timer_active)
1622 return 0; 1635 return 0;
1623 if (time_after_eq(jiffies, timeout)) { 1636 if (time_after_eq(jiffies, timeout)) {
1624 EFX_ERR(efx, "timed out waiting for SPI\n"); 1637 EFX_ERR(efx, "timed out waiting for SPI\n");
1625 return -ETIMEDOUT; 1638 return -ETIMEDOUT;
1626 } 1639 }
1627 cpu_relax(); 1640 schedule_timeout_uninterruptible(1);
1628 } 1641 }
1629} 1642}
1630 1643
@@ -1643,8 +1656,8 @@ int falcon_spi_cmd(const struct efx_spi_device *spi,
1643 return -EINVAL; 1656 return -EINVAL;
1644 BUG_ON(!mutex_is_locked(&efx->spi_lock)); 1657 BUG_ON(!mutex_is_locked(&efx->spi_lock));
1645 1658
1646 /* Check SPI not currently being accessed */ 1659 /* Check that previous command is not still running */
1647 rc = falcon_spi_wait(efx); 1660 rc = falcon_spi_poll(efx);
1648 if (rc) 1661 if (rc)
1649 return rc; 1662 return rc;
1650 1663
@@ -1700,26 +1713,29 @@ efx_spi_munge_command(const struct efx_spi_device *spi,
1700 return command | (((address >> 8) & spi->munge_address) << 3); 1713 return command | (((address >> 8) & spi->munge_address) << 3);
1701} 1714}
1702 1715
1703int falcon_spi_fast_wait(const struct efx_spi_device *spi) 1716/* Wait up to 10 ms for buffered write completion */
1717int falcon_spi_wait_write(const struct efx_spi_device *spi)
1704{ 1718{
1719 struct efx_nic *efx = spi->efx;
1720 unsigned long timeout = jiffies + 1 + DIV_ROUND_UP(HZ, 100);
1705 u8 status; 1721 u8 status;
1706 int i, rc; 1722 int rc;
1707
1708 /* Wait up to 1000us for flash/EEPROM to finish a fast operation. */
1709 for (i = 0; i < 50; i++) {
1710 udelay(20);
1711 1723
1724 for (;;) {
1712 rc = falcon_spi_cmd(spi, SPI_RDSR, -1, NULL, 1725 rc = falcon_spi_cmd(spi, SPI_RDSR, -1, NULL,
1713 &status, sizeof(status)); 1726 &status, sizeof(status));
1714 if (rc) 1727 if (rc)
1715 return rc; 1728 return rc;
1716 if (!(status & SPI_STATUS_NRDY)) 1729 if (!(status & SPI_STATUS_NRDY))
1717 return 0; 1730 return 0;
1731 if (time_after_eq(jiffies, timeout)) {
1732 EFX_ERR(efx, "SPI write timeout on device %d"
1733 " last status=0x%02x\n",
1734 spi->device_id, status);
1735 return -ETIMEDOUT;
1736 }
1737 schedule_timeout_uninterruptible(1);
1718 } 1738 }
1719 EFX_ERR(spi->efx,
1720 "timed out waiting for device %d last status=0x%02x\n",
1721 spi->device_id, status);
1722 return -ETIMEDOUT;
1723} 1739}
1724 1740
1725int falcon_spi_read(const struct efx_spi_device *spi, loff_t start, 1741int falcon_spi_read(const struct efx_spi_device *spi, loff_t start,
@@ -1773,7 +1789,7 @@ int falcon_spi_write(const struct efx_spi_device *spi, loff_t start,
1773 if (rc) 1789 if (rc)
1774 break; 1790 break;
1775 1791
1776 rc = falcon_spi_fast_wait(spi); 1792 rc = falcon_spi_wait_write(spi);
1777 if (rc) 1793 if (rc)
1778 break; 1794 break;
1779 1795
diff --git a/drivers/net/sfc/mtd.c b/drivers/net/sfc/mtd.c
index a1e6c2875fc0..665cafb88d6a 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)
76 rc = falcon_spi_cmd(spi, SPI_WRSR, -1, &status, NULL, sizeof(status)); 76 rc = falcon_spi_cmd(spi, SPI_WRSR, -1, &status, NULL, sizeof(status));
77 if (rc) 77 if (rc)
78 return rc; 78 return rc;
79 rc = falcon_spi_fast_wait(spi); 79 rc = falcon_spi_wait_write(spi);
80 if (rc) 80 if (rc)
81 return rc; 81 return rc;
82 82
diff --git a/drivers/net/sfc/spi.h b/drivers/net/sfc/spi.h
index 38e22ff4d7af..1b1ceb411671 100644
--- a/drivers/net/sfc/spi.h
+++ b/drivers/net/sfc/spi.h
@@ -69,7 +69,7 @@ struct efx_spi_device {
69 69
70int falcon_spi_cmd(const struct efx_spi_device *spi, unsigned int command, 70int falcon_spi_cmd(const struct efx_spi_device *spi, unsigned int command,
71 int address, const void* in, void *out, size_t len); 71 int address, const void* in, void *out, size_t len);
72int falcon_spi_fast_wait(const struct efx_spi_device *spi); 72int falcon_spi_wait_write(const struct efx_spi_device *spi);
73int falcon_spi_read(const struct efx_spi_device *spi, loff_t start, 73int falcon_spi_read(const struct efx_spi_device *spi, loff_t start,
74 size_t len, size_t *retlen, u8 *buffer); 74 size_t len, size_t *retlen, u8 *buffer);
75int falcon_spi_write(const struct efx_spi_device *spi, loff_t start, 75int falcon_spi_write(const struct efx_spi_device *spi, loff_t start,