diff options
author | Ben Hutchings <bhutchings@solarflare.com> | 2009-11-29 10:10:44 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-11-29 20:23:54 -0500 |
commit | 76884835684411264cda2f15585261eb02183541 (patch) | |
tree | 585b42235745acf3bf161838b14682428175e670 /drivers/net/sfc/falcon.c | |
parent | c1c4f453b61463df4df16f7aa5782fc0cfe05b9e (diff) |
sfc: Extend MTD driver for use with new NICs
In new NICs flash is managed by firmware and we will use high-level
operations on partitions rather than direct SPI commands. Add support
for multiple MTD partitions per flash device and remove the direct
link between MTD and SPI devices. Maintain a list of MTD partitions
in struct efx_nic.
Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/sfc/falcon.c')
-rw-r--r-- | drivers/net/sfc/falcon.c | 32 |
1 files changed, 15 insertions, 17 deletions
diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c index 29d45376e4c9..950de847d22b 100644 --- a/drivers/net/sfc/falcon.c +++ b/drivers/net/sfc/falcon.c | |||
@@ -1640,11 +1640,10 @@ static int falcon_spi_wait(struct efx_nic *efx) | |||
1640 | } | 1640 | } |
1641 | } | 1641 | } |
1642 | 1642 | ||
1643 | int falcon_spi_cmd(const struct efx_spi_device *spi, | 1643 | int falcon_spi_cmd(struct efx_nic *efx, const struct efx_spi_device *spi, |
1644 | unsigned int command, int address, | 1644 | unsigned int command, int address, |
1645 | const void *in, void *out, size_t len) | 1645 | const void *in, void *out, size_t len) |
1646 | { | 1646 | { |
1647 | struct efx_nic *efx = spi->efx; | ||
1648 | bool addressed = (address >= 0); | 1647 | bool addressed = (address >= 0); |
1649 | bool reading = (out != NULL); | 1648 | bool reading = (out != NULL); |
1650 | efx_oword_t reg; | 1649 | efx_oword_t reg; |
@@ -1713,15 +1712,15 @@ efx_spi_munge_command(const struct efx_spi_device *spi, | |||
1713 | } | 1712 | } |
1714 | 1713 | ||
1715 | /* Wait up to 10 ms for buffered write completion */ | 1714 | /* Wait up to 10 ms for buffered write completion */ |
1716 | int falcon_spi_wait_write(const struct efx_spi_device *spi) | 1715 | int |
1716 | falcon_spi_wait_write(struct efx_nic *efx, const struct efx_spi_device *spi) | ||
1717 | { | 1717 | { |
1718 | struct efx_nic *efx = spi->efx; | ||
1719 | unsigned long timeout = jiffies + 1 + DIV_ROUND_UP(HZ, 100); | 1718 | unsigned long timeout = jiffies + 1 + DIV_ROUND_UP(HZ, 100); |
1720 | u8 status; | 1719 | u8 status; |
1721 | int rc; | 1720 | int rc; |
1722 | 1721 | ||
1723 | for (;;) { | 1722 | for (;;) { |
1724 | rc = falcon_spi_cmd(spi, SPI_RDSR, -1, NULL, | 1723 | rc = falcon_spi_cmd(efx, spi, SPI_RDSR, -1, NULL, |
1725 | &status, sizeof(status)); | 1724 | &status, sizeof(status)); |
1726 | if (rc) | 1725 | if (rc) |
1727 | return rc; | 1726 | return rc; |
@@ -1737,8 +1736,8 @@ int falcon_spi_wait_write(const struct efx_spi_device *spi) | |||
1737 | } | 1736 | } |
1738 | } | 1737 | } |
1739 | 1738 | ||
1740 | int falcon_spi_read(const struct efx_spi_device *spi, loff_t start, | 1739 | int falcon_spi_read(struct efx_nic *efx, const struct efx_spi_device *spi, |
1741 | size_t len, size_t *retlen, u8 *buffer) | 1740 | loff_t start, size_t len, size_t *retlen, u8 *buffer) |
1742 | { | 1741 | { |
1743 | size_t block_len, pos = 0; | 1742 | size_t block_len, pos = 0; |
1744 | unsigned int command; | 1743 | unsigned int command; |
@@ -1748,7 +1747,7 @@ int falcon_spi_read(const struct efx_spi_device *spi, loff_t start, | |||
1748 | block_len = min(len - pos, FALCON_SPI_MAX_LEN); | 1747 | block_len = min(len - pos, FALCON_SPI_MAX_LEN); |
1749 | 1748 | ||
1750 | command = efx_spi_munge_command(spi, SPI_READ, start + pos); | 1749 | command = efx_spi_munge_command(spi, SPI_READ, start + pos); |
1751 | rc = falcon_spi_cmd(spi, command, start + pos, NULL, | 1750 | rc = falcon_spi_cmd(efx, spi, command, start + pos, NULL, |
1752 | buffer + pos, block_len); | 1751 | buffer + pos, block_len); |
1753 | if (rc) | 1752 | if (rc) |
1754 | break; | 1753 | break; |
@@ -1767,8 +1766,9 @@ int falcon_spi_read(const struct efx_spi_device *spi, loff_t start, | |||
1767 | return rc; | 1766 | return rc; |
1768 | } | 1767 | } |
1769 | 1768 | ||
1770 | int falcon_spi_write(const struct efx_spi_device *spi, loff_t start, | 1769 | int |
1771 | size_t len, size_t *retlen, const u8 *buffer) | 1770 | falcon_spi_write(struct efx_nic *efx, const struct efx_spi_device *spi, |
1771 | loff_t start, size_t len, size_t *retlen, const u8 *buffer) | ||
1772 | { | 1772 | { |
1773 | u8 verify_buffer[FALCON_SPI_MAX_LEN]; | 1773 | u8 verify_buffer[FALCON_SPI_MAX_LEN]; |
1774 | size_t block_len, pos = 0; | 1774 | size_t block_len, pos = 0; |
@@ -1776,24 +1776,24 @@ int falcon_spi_write(const struct efx_spi_device *spi, loff_t start, | |||
1776 | int rc = 0; | 1776 | int rc = 0; |
1777 | 1777 | ||
1778 | while (pos < len) { | 1778 | while (pos < len) { |
1779 | rc = falcon_spi_cmd(spi, SPI_WREN, -1, NULL, NULL, 0); | 1779 | rc = falcon_spi_cmd(efx, spi, SPI_WREN, -1, NULL, NULL, 0); |
1780 | if (rc) | 1780 | if (rc) |
1781 | break; | 1781 | break; |
1782 | 1782 | ||
1783 | block_len = min(len - pos, | 1783 | block_len = min(len - pos, |
1784 | falcon_spi_write_limit(spi, start + pos)); | 1784 | falcon_spi_write_limit(spi, start + pos)); |
1785 | command = efx_spi_munge_command(spi, SPI_WRITE, start + pos); | 1785 | command = efx_spi_munge_command(spi, SPI_WRITE, start + pos); |
1786 | rc = falcon_spi_cmd(spi, command, start + pos, | 1786 | rc = falcon_spi_cmd(efx, spi, command, start + pos, |
1787 | buffer + pos, NULL, block_len); | 1787 | buffer + pos, NULL, block_len); |
1788 | if (rc) | 1788 | if (rc) |
1789 | break; | 1789 | break; |
1790 | 1790 | ||
1791 | rc = falcon_spi_wait_write(spi); | 1791 | rc = falcon_spi_wait_write(efx, spi); |
1792 | if (rc) | 1792 | if (rc) |
1793 | break; | 1793 | break; |
1794 | 1794 | ||
1795 | command = efx_spi_munge_command(spi, SPI_READ, start + pos); | 1795 | command = efx_spi_munge_command(spi, SPI_READ, start + pos); |
1796 | rc = falcon_spi_cmd(spi, command, start + pos, | 1796 | rc = falcon_spi_cmd(efx, spi, command, start + pos, |
1797 | NULL, verify_buffer, block_len); | 1797 | NULL, verify_buffer, block_len); |
1798 | if (memcmp(verify_buffer, buffer + pos, block_len)) { | 1798 | if (memcmp(verify_buffer, buffer + pos, block_len)) { |
1799 | rc = -EIO; | 1799 | rc = -EIO; |
@@ -2352,7 +2352,7 @@ falcon_read_nvram(struct efx_nic *efx, struct falcon_nvconfig *nvconfig_out) | |||
2352 | nvconfig = region + FALCON_NVCONFIG_OFFSET; | 2352 | nvconfig = region + FALCON_NVCONFIG_OFFSET; |
2353 | 2353 | ||
2354 | mutex_lock(&efx->spi_lock); | 2354 | mutex_lock(&efx->spi_lock); |
2355 | rc = falcon_spi_read(spi, 0, FALCON_NVCONFIG_END, NULL, region); | 2355 | rc = falcon_spi_read(efx, spi, 0, FALCON_NVCONFIG_END, NULL, region); |
2356 | mutex_unlock(&efx->spi_lock); | 2356 | mutex_unlock(&efx->spi_lock); |
2357 | if (rc) { | 2357 | if (rc) { |
2358 | EFX_ERR(efx, "Failed to read %s\n", | 2358 | EFX_ERR(efx, "Failed to read %s\n", |
@@ -2710,8 +2710,6 @@ static int falcon_spi_device_init(struct efx_nic *efx, | |||
2710 | spi_device->block_size = | 2710 | spi_device->block_size = |
2711 | 1 << SPI_DEV_TYPE_FIELD(device_type, | 2711 | 1 << SPI_DEV_TYPE_FIELD(device_type, |
2712 | SPI_DEV_TYPE_BLOCK_SIZE); | 2712 | SPI_DEV_TYPE_BLOCK_SIZE); |
2713 | |||
2714 | spi_device->efx = efx; | ||
2715 | } else { | 2713 | } else { |
2716 | spi_device = NULL; | 2714 | spi_device = NULL; |
2717 | } | 2715 | } |