aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet
diff options
context:
space:
mode:
authorBen Hutchings <bhutchings@solarflare.com>2012-11-27 23:38:14 -0500
committerBen Hutchings <bhutchings@solarflare.com>2013-08-27 17:25:21 -0400
commit45a3fd55acc8989ff93d469e57b123cd3702a948 (patch)
tree39c1d3c5fdd95182b6832b2b7e27b765f4f97575 /drivers/net/ethernet
parent141d748e70a22629ef1e1823f88b3d5741ac38af (diff)
sfc: Move MTD operations into efx_nic_type
Merge the per-NIC-type MTD probe selection and struct efx_mtd_ops into struct efx_nic_type. Move the implementations into the appropriate source files. Several NVRAM functions are now only called from MTD operations which are now implemented in the same file (falcon.c or mcdi.c). There is no need for them to be extern, or to be defined at all if CONFIG_SFC_MTD is not enabled, so move them into the #ifdef CONFIG_SFC_MTD sections in those files. Most of the SPI-related definitions are also only used in falcon.c, so move them there. Put the remainder of spi.h into nic.h (which previously included it). Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
Diffstat (limited to 'drivers/net/ethernet')
-rw-r--r--drivers/net/ethernet/sfc/efx.h7
-rw-r--r--drivers/net/ethernet/sfc/falcon.c381
-rw-r--r--drivers/net/ethernet/sfc/mcdi.c352
-rw-r--r--drivers/net/ethernet/sfc/mcdi.h32
-rw-r--r--drivers/net/ethernet/sfc/mtd.c564
-rw-r--r--drivers/net/ethernet/sfc/net_driver.h29
-rw-r--r--drivers/net/ethernet/sfc/nic.h33
-rw-r--r--drivers/net/ethernet/sfc/siena.c141
-rw-r--r--drivers/net/ethernet/sfc/spi.h99
9 files changed, 807 insertions, 831 deletions
diff --git a/drivers/net/ethernet/sfc/efx.h b/drivers/net/ethernet/sfc/efx.h
index 9e3573872e57..3bbc047baea2 100644
--- a/drivers/net/ethernet/sfc/efx.h
+++ b/drivers/net/ethernet/sfc/efx.h
@@ -204,7 +204,12 @@ extern void efx_port_dummy_op_void(struct efx_nic *efx);
204 204
205/* MTD */ 205/* MTD */
206#ifdef CONFIG_SFC_MTD 206#ifdef CONFIG_SFC_MTD
207extern int efx_mtd_probe(struct efx_nic *efx); 207extern int efx_mtd_add(struct efx_nic *efx, struct efx_mtd_partition *parts,
208 size_t n_parts, size_t sizeof_part);
209static inline int efx_mtd_probe(struct efx_nic *efx)
210{
211 return efx->type->mtd_probe(efx);
212}
208extern void efx_mtd_rename(struct efx_nic *efx); 213extern void efx_mtd_rename(struct efx_nic *efx);
209extern void efx_mtd_remove(struct efx_nic *efx); 214extern void efx_mtd_remove(struct efx_nic *efx);
210#else 215#else
diff --git a/drivers/net/ethernet/sfc/falcon.c b/drivers/net/ethernet/sfc/falcon.c
index 304131b08f17..3c99b6c2d531 100644
--- a/drivers/net/ethernet/sfc/falcon.c
+++ b/drivers/net/ethernet/sfc/falcon.c
@@ -19,7 +19,6 @@
19#include "net_driver.h" 19#include "net_driver.h"
20#include "bitfield.h" 20#include "bitfield.h"
21#include "efx.h" 21#include "efx.h"
22#include "spi.h"
23#include "nic.h" 22#include "nic.h"
24#include "farch_regs.h" 23#include "farch_regs.h"
25#include "io.h" 24#include "io.h"
@@ -159,11 +158,49 @@
159 158
160/************************************************************************** 159/**************************************************************************
161 * 160 *
162 * Non-volatile configuration 161 * Basic SPI command set and bit definitions
162 *
163 *************************************************************************/
164
165#define SPI_WRSR 0x01 /* Write status register */
166#define SPI_WRITE 0x02 /* Write data to memory array */
167#define SPI_READ 0x03 /* Read data from memory array */
168#define SPI_WRDI 0x04 /* Reset write enable latch */
169#define SPI_RDSR 0x05 /* Read status register */
170#define SPI_WREN 0x06 /* Set write enable latch */
171#define SPI_SST_EWSR 0x50 /* SST: Enable write to status register */
172
173#define SPI_STATUS_WPEN 0x80 /* Write-protect pin enabled */
174#define SPI_STATUS_BP2 0x10 /* Block protection bit 2 */
175#define SPI_STATUS_BP1 0x08 /* Block protection bit 1 */
176#define SPI_STATUS_BP0 0x04 /* Block protection bit 0 */
177#define SPI_STATUS_WEN 0x02 /* State of the write enable latch */
178#define SPI_STATUS_NRDY 0x01 /* Device busy flag */
179
180/**************************************************************************
181 *
182 * Non-volatile memory layout
163 * 183 *
164 ************************************************************************** 184 **************************************************************************
165 */ 185 */
166 186
187/* SFC4000 flash is partitioned into:
188 * 0-0x400 chip and board config (see struct falcon_nvconfig)
189 * 0x400-0x8000 unused (or may contain VPD if EEPROM not present)
190 * 0x8000-end boot code (mapped to PCI expansion ROM)
191 * SFC4000 small EEPROM (size < 0x400) is used for VPD only.
192 * SFC4000 large EEPROM (size >= 0x400) is partitioned into:
193 * 0-0x400 chip and board config
194 * configurable VPD
195 * 0x800-0x1800 boot config
196 * Aside from the chip and board config, all of these are optional and may
197 * be absent or truncated depending on the devices used.
198 */
199#define FALCON_NVCONFIG_END 0x400U
200#define FALCON_FLASH_BOOTCODE_START 0x8000U
201#define FALCON_EEPROM_BOOTCONFIG_START 0x800U
202#define FALCON_EEPROM_BOOTCONFIG_END 0x1800U
203
167/* Board configuration v2 (v1 is obsolete; later versions are compatible) */ 204/* Board configuration v2 (v1 is obsolete; later versions are compatible) */
168struct falcon_nvconfig_board_v2 { 205struct falcon_nvconfig_board_v2 {
169 __le16 nports; 206 __le16 nports;
@@ -434,9 +471,10 @@ static int falcon_spi_wait(struct efx_nic *efx)
434 } 471 }
435} 472}
436 473
437int falcon_spi_cmd(struct efx_nic *efx, const struct falcon_spi_device *spi, 474static int
438 unsigned int command, int address, 475falcon_spi_cmd(struct efx_nic *efx, const struct falcon_spi_device *spi,
439 const void *in, void *out, size_t len) 476 unsigned int command, int address,
477 const void *in, void *out, size_t len)
440{ 478{
441 bool addressed = (address >= 0); 479 bool addressed = (address >= 0);
442 bool reading = (out != NULL); 480 bool reading = (out != NULL);
@@ -490,13 +528,6 @@ int falcon_spi_cmd(struct efx_nic *efx, const struct falcon_spi_device *spi,
490 return 0; 528 return 0;
491} 529}
492 530
493static size_t
494falcon_spi_write_limit(const struct falcon_spi_device *spi, size_t start)
495{
496 return min(FALCON_SPI_MAX_LEN,
497 (spi->block_size - (start & (spi->block_size - 1))));
498}
499
500static inline u8 531static inline u8
501falcon_spi_munge_command(const struct falcon_spi_device *spi, 532falcon_spi_munge_command(const struct falcon_spi_device *spi,
502 const u8 command, const unsigned int address) 533 const u8 command, const unsigned int address)
@@ -504,34 +535,9 @@ falcon_spi_munge_command(const struct falcon_spi_device *spi,
504 return command | (((address >> 8) & spi->munge_address) << 3); 535 return command | (((address >> 8) & spi->munge_address) << 3);
505} 536}
506 537
507/* Wait up to 10 ms for buffered write completion */ 538static int
508int 539falcon_spi_read(struct efx_nic *efx, const struct falcon_spi_device *spi,
509falcon_spi_wait_write(struct efx_nic *efx, const struct falcon_spi_device *spi) 540 loff_t start, size_t len, size_t *retlen, u8 *buffer)
510{
511 unsigned long timeout = jiffies + 1 + DIV_ROUND_UP(HZ, 100);
512 u8 status;
513 int rc;
514
515 for (;;) {
516 rc = falcon_spi_cmd(efx, spi, SPI_RDSR, -1, NULL,
517 &status, sizeof(status));
518 if (rc)
519 return rc;
520 if (!(status & SPI_STATUS_NRDY))
521 return 0;
522 if (time_after_eq(jiffies, timeout)) {
523 netif_err(efx, hw, efx->net_dev,
524 "SPI write timeout on device %d"
525 " last status=0x%02x\n",
526 spi->device_id, status);
527 return -ETIMEDOUT;
528 }
529 schedule_timeout_uninterruptible(1);
530 }
531}
532
533int falcon_spi_read(struct efx_nic *efx, const struct falcon_spi_device *spi,
534 loff_t start, size_t len, size_t *retlen, u8 *buffer)
535{ 541{
536 size_t block_len, pos = 0; 542 size_t block_len, pos = 0;
537 unsigned int command; 543 unsigned int command;
@@ -560,7 +566,51 @@ int falcon_spi_read(struct efx_nic *efx, const struct falcon_spi_device *spi,
560 return rc; 566 return rc;
561} 567}
562 568
563int 569#ifdef CONFIG_SFC_MTD
570
571struct falcon_mtd_partition {
572 struct efx_mtd_partition common;
573 const struct falcon_spi_device *spi;
574 size_t offset;
575};
576
577#define to_falcon_mtd_partition(mtd) \
578 container_of(mtd, struct falcon_mtd_partition, common.mtd)
579
580static size_t
581falcon_spi_write_limit(const struct falcon_spi_device *spi, size_t start)
582{
583 return min(FALCON_SPI_MAX_LEN,
584 (spi->block_size - (start & (spi->block_size - 1))));
585}
586
587/* Wait up to 10 ms for buffered write completion */
588static int
589falcon_spi_wait_write(struct efx_nic *efx, const struct falcon_spi_device *spi)
590{
591 unsigned long timeout = jiffies + 1 + DIV_ROUND_UP(HZ, 100);
592 u8 status;
593 int rc;
594
595 for (;;) {
596 rc = falcon_spi_cmd(efx, spi, SPI_RDSR, -1, NULL,
597 &status, sizeof(status));
598 if (rc)
599 return rc;
600 if (!(status & SPI_STATUS_NRDY))
601 return 0;
602 if (time_after_eq(jiffies, timeout)) {
603 netif_err(efx, hw, efx->net_dev,
604 "SPI write timeout on device %d"
605 " last status=0x%02x\n",
606 spi->device_id, status);
607 return -ETIMEDOUT;
608 }
609 schedule_timeout_uninterruptible(1);
610 }
611}
612
613static int
564falcon_spi_write(struct efx_nic *efx, const struct falcon_spi_device *spi, 614falcon_spi_write(struct efx_nic *efx, const struct falcon_spi_device *spi,
565 loff_t start, size_t len, size_t *retlen, const u8 *buffer) 615 loff_t start, size_t len, size_t *retlen, const u8 *buffer)
566{ 616{
@@ -609,6 +659,238 @@ falcon_spi_write(struct efx_nic *efx, const struct falcon_spi_device *spi,
609 return rc; 659 return rc;
610} 660}
611 661
662static int
663falcon_spi_slow_wait(struct falcon_mtd_partition *part, bool uninterruptible)
664{
665 const struct falcon_spi_device *spi = part->spi;
666 struct efx_nic *efx = part->common.mtd.priv;
667 u8 status;
668 int rc, i;
669
670 /* Wait up to 4s for flash/EEPROM to finish a slow operation. */
671 for (i = 0; i < 40; i++) {
672 __set_current_state(uninterruptible ?
673 TASK_UNINTERRUPTIBLE : TASK_INTERRUPTIBLE);
674 schedule_timeout(HZ / 10);
675 rc = falcon_spi_cmd(efx, spi, SPI_RDSR, -1, NULL,
676 &status, sizeof(status));
677 if (rc)
678 return rc;
679 if (!(status & SPI_STATUS_NRDY))
680 return 0;
681 if (signal_pending(current))
682 return -EINTR;
683 }
684 pr_err("%s: timed out waiting for %s\n",
685 part->common.name, part->common.dev_type_name);
686 return -ETIMEDOUT;
687}
688
689static int
690falcon_spi_unlock(struct efx_nic *efx, const struct falcon_spi_device *spi)
691{
692 const u8 unlock_mask = (SPI_STATUS_BP2 | SPI_STATUS_BP1 |
693 SPI_STATUS_BP0);
694 u8 status;
695 int rc;
696
697 rc = falcon_spi_cmd(efx, spi, SPI_RDSR, -1, NULL,
698 &status, sizeof(status));
699 if (rc)
700 return rc;
701
702 if (!(status & unlock_mask))
703 return 0; /* already unlocked */
704
705 rc = falcon_spi_cmd(efx, spi, SPI_WREN, -1, NULL, NULL, 0);
706 if (rc)
707 return rc;
708 rc = falcon_spi_cmd(efx, spi, SPI_SST_EWSR, -1, NULL, NULL, 0);
709 if (rc)
710 return rc;
711
712 status &= ~unlock_mask;
713 rc = falcon_spi_cmd(efx, spi, SPI_WRSR, -1, &status,
714 NULL, sizeof(status));
715 if (rc)
716 return rc;
717 rc = falcon_spi_wait_write(efx, spi);
718 if (rc)
719 return rc;
720
721 return 0;
722}
723
724#define FALCON_SPI_VERIFY_BUF_LEN 16
725
726static int
727falcon_spi_erase(struct falcon_mtd_partition *part, loff_t start, size_t len)
728{
729 const struct falcon_spi_device *spi = part->spi;
730 struct efx_nic *efx = part->common.mtd.priv;
731 unsigned pos, block_len;
732 u8 empty[FALCON_SPI_VERIFY_BUF_LEN];
733 u8 buffer[FALCON_SPI_VERIFY_BUF_LEN];
734 int rc;
735
736 if (len != spi->erase_size)
737 return -EINVAL;
738
739 if (spi->erase_command == 0)
740 return -EOPNOTSUPP;
741
742 rc = falcon_spi_unlock(efx, spi);
743 if (rc)
744 return rc;
745 rc = falcon_spi_cmd(efx, spi, SPI_WREN, -1, NULL, NULL, 0);
746 if (rc)
747 return rc;
748 rc = falcon_spi_cmd(efx, spi, spi->erase_command, start, NULL,
749 NULL, 0);
750 if (rc)
751 return rc;
752 rc = falcon_spi_slow_wait(part, false);
753
754 /* Verify the entire region has been wiped */
755 memset(empty, 0xff, sizeof(empty));
756 for (pos = 0; pos < len; pos += block_len) {
757 block_len = min(len - pos, sizeof(buffer));
758 rc = falcon_spi_read(efx, spi, start + pos, block_len,
759 NULL, buffer);
760 if (rc)
761 return rc;
762 if (memcmp(empty, buffer, block_len))
763 return -EIO;
764
765 /* Avoid locking up the system */
766 cond_resched();
767 if (signal_pending(current))
768 return -EINTR;
769 }
770
771 return rc;
772}
773
774static void falcon_mtd_rename(struct efx_mtd_partition *part)
775{
776 struct efx_nic *efx = part->mtd.priv;
777
778 snprintf(part->name, sizeof(part->name), "%s %s",
779 efx->name, part->type_name);
780}
781
782static int falcon_mtd_read(struct mtd_info *mtd, loff_t start,
783 size_t len, size_t *retlen, u8 *buffer)
784{
785 struct falcon_mtd_partition *part = to_falcon_mtd_partition(mtd);
786 struct efx_nic *efx = mtd->priv;
787 struct falcon_nic_data *nic_data = efx->nic_data;
788 int rc;
789
790 rc = mutex_lock_interruptible(&nic_data->spi_lock);
791 if (rc)
792 return rc;
793 rc = falcon_spi_read(efx, part->spi, part->offset + start,
794 len, retlen, buffer);
795 mutex_unlock(&nic_data->spi_lock);
796 return rc;
797}
798
799static int falcon_mtd_erase(struct mtd_info *mtd, loff_t start, size_t len)
800{
801 struct falcon_mtd_partition *part = to_falcon_mtd_partition(mtd);
802 struct efx_nic *efx = mtd->priv;
803 struct falcon_nic_data *nic_data = efx->nic_data;
804 int rc;
805
806 rc = mutex_lock_interruptible(&nic_data->spi_lock);
807 if (rc)
808 return rc;
809 rc = falcon_spi_erase(part, part->offset + start, len);
810 mutex_unlock(&nic_data->spi_lock);
811 return rc;
812}
813
814static int falcon_mtd_write(struct mtd_info *mtd, loff_t start,
815 size_t len, size_t *retlen, const u8 *buffer)
816{
817 struct falcon_mtd_partition *part = to_falcon_mtd_partition(mtd);
818 struct efx_nic *efx = mtd->priv;
819 struct falcon_nic_data *nic_data = efx->nic_data;
820 int rc;
821
822 rc = mutex_lock_interruptible(&nic_data->spi_lock);
823 if (rc)
824 return rc;
825 rc = falcon_spi_write(efx, part->spi, part->offset + start,
826 len, retlen, buffer);
827 mutex_unlock(&nic_data->spi_lock);
828 return rc;
829}
830
831static int falcon_mtd_sync(struct mtd_info *mtd)
832{
833 struct falcon_mtd_partition *part = to_falcon_mtd_partition(mtd);
834 struct efx_nic *efx = mtd->priv;
835 struct falcon_nic_data *nic_data = efx->nic_data;
836 int rc;
837
838 mutex_lock(&nic_data->spi_lock);
839 rc = falcon_spi_slow_wait(part, true);
840 mutex_unlock(&nic_data->spi_lock);
841 return rc;
842}
843
844static int falcon_mtd_probe(struct efx_nic *efx)
845{
846 struct falcon_nic_data *nic_data = efx->nic_data;
847 struct falcon_mtd_partition *parts;
848 struct falcon_spi_device *spi;
849 size_t n_parts;
850 int rc = -ENODEV;
851
852 ASSERT_RTNL();
853
854 /* Allocate space for maximum number of partitions */
855 parts = kcalloc(2, sizeof(*parts), GFP_KERNEL);
856 n_parts = 0;
857
858 spi = &nic_data->spi_flash;
859 if (falcon_spi_present(spi) && spi->size > FALCON_FLASH_BOOTCODE_START) {
860 parts[n_parts].spi = spi;
861 parts[n_parts].offset = FALCON_FLASH_BOOTCODE_START;
862 parts[n_parts].common.dev_type_name = "flash";
863 parts[n_parts].common.type_name = "sfc_flash_bootrom";
864 parts[n_parts].common.mtd.type = MTD_NORFLASH;
865 parts[n_parts].common.mtd.flags = MTD_CAP_NORFLASH;
866 parts[n_parts].common.mtd.size = spi->size - FALCON_FLASH_BOOTCODE_START;
867 parts[n_parts].common.mtd.erasesize = spi->erase_size;
868 n_parts++;
869 }
870
871 spi = &nic_data->spi_eeprom;
872 if (falcon_spi_present(spi) && spi->size > FALCON_EEPROM_BOOTCONFIG_START) {
873 parts[n_parts].spi = spi;
874 parts[n_parts].offset = FALCON_EEPROM_BOOTCONFIG_START;
875 parts[n_parts].common.dev_type_name = "EEPROM";
876 parts[n_parts].common.type_name = "sfc_bootconfig";
877 parts[n_parts].common.mtd.type = MTD_RAM;
878 parts[n_parts].common.mtd.flags = MTD_CAP_RAM;
879 parts[n_parts].common.mtd.size =
880 min(spi->size, FALCON_EEPROM_BOOTCONFIG_END) -
881 FALCON_EEPROM_BOOTCONFIG_START;
882 parts[n_parts].common.mtd.erasesize = spi->erase_size;
883 n_parts++;
884 }
885
886 rc = efx_mtd_add(efx, &parts[0].common, n_parts, sizeof(*parts));
887 if (rc)
888 kfree(parts);
889 return rc;
890}
891
892#endif /* CONFIG_SFC_MTD */
893
612/************************************************************************** 894/**************************************************************************
613 * 895 *
614 * XMAC operations 896 * XMAC operations
@@ -2417,6 +2699,15 @@ const struct efx_nic_type falcon_a1_nic_type = {
2417 .filter_get_rx_id_limit = efx_farch_filter_get_rx_id_limit, 2699 .filter_get_rx_id_limit = efx_farch_filter_get_rx_id_limit,
2418 .filter_get_rx_ids = efx_farch_filter_get_rx_ids, 2700 .filter_get_rx_ids = efx_farch_filter_get_rx_ids,
2419 2701
2702#ifdef CONFIG_SFC_MTD
2703 .mtd_probe = falcon_mtd_probe,
2704 .mtd_rename = falcon_mtd_rename,
2705 .mtd_read = falcon_mtd_read,
2706 .mtd_erase = falcon_mtd_erase,
2707 .mtd_write = falcon_mtd_write,
2708 .mtd_sync = falcon_mtd_sync,
2709#endif
2710
2420 .revision = EFX_REV_FALCON_A1, 2711 .revision = EFX_REV_FALCON_A1,
2421 .txd_ptr_tbl_base = FR_AA_TX_DESC_PTR_TBL_KER, 2712 .txd_ptr_tbl_base = FR_AA_TX_DESC_PTR_TBL_KER,
2422 .rxd_ptr_tbl_base = FR_AA_RX_DESC_PTR_TBL_KER, 2713 .rxd_ptr_tbl_base = FR_AA_RX_DESC_PTR_TBL_KER,
@@ -2500,6 +2791,14 @@ const struct efx_nic_type falcon_b0_nic_type = {
2500 .filter_rfs_insert = efx_farch_filter_rfs_insert, 2791 .filter_rfs_insert = efx_farch_filter_rfs_insert,
2501 .filter_rfs_expire_one = efx_farch_filter_rfs_expire_one, 2792 .filter_rfs_expire_one = efx_farch_filter_rfs_expire_one,
2502#endif 2793#endif
2794#ifdef CONFIG_SFC_MTD
2795 .mtd_probe = falcon_mtd_probe,
2796 .mtd_rename = falcon_mtd_rename,
2797 .mtd_read = falcon_mtd_read,
2798 .mtd_erase = falcon_mtd_erase,
2799 .mtd_write = falcon_mtd_write,
2800 .mtd_sync = falcon_mtd_sync,
2801#endif
2503 2802
2504 .revision = EFX_REV_FALCON_B0, 2803 .revision = EFX_REV_FALCON_B0,
2505 .txd_ptr_tbl_base = FR_BZ_TX_DESC_PTR_TBL, 2804 .txd_ptr_tbl_base = FR_BZ_TX_DESC_PTR_TBL,
diff --git a/drivers/net/ethernet/sfc/mcdi.c b/drivers/net/ethernet/sfc/mcdi.c
index 1c8bf81bdc03..67b07de2c599 100644
--- a/drivers/net/ethernet/sfc/mcdi.c
+++ b/drivers/net/ethernet/sfc/mcdi.c
@@ -811,125 +811,6 @@ fail:
811 return rc; 811 return rc;
812} 812}
813 813
814int efx_mcdi_nvram_update_start(struct efx_nic *efx, unsigned int type)
815{
816 MCDI_DECLARE_BUF(inbuf, MC_CMD_NVRAM_UPDATE_START_IN_LEN);
817 int rc;
818
819 MCDI_SET_DWORD(inbuf, NVRAM_UPDATE_START_IN_TYPE, type);
820
821 BUILD_BUG_ON(MC_CMD_NVRAM_UPDATE_START_OUT_LEN != 0);
822
823 rc = efx_mcdi_rpc(efx, MC_CMD_NVRAM_UPDATE_START, inbuf, sizeof(inbuf),
824 NULL, 0, NULL);
825 if (rc)
826 goto fail;
827
828 return 0;
829
830fail:
831 netif_err(efx, hw, efx->net_dev, "%s: failed rc=%d\n", __func__, rc);
832 return rc;
833}
834
835int efx_mcdi_nvram_read(struct efx_nic *efx, unsigned int type,
836 loff_t offset, u8 *buffer, size_t length)
837{
838 MCDI_DECLARE_BUF(inbuf, MC_CMD_NVRAM_READ_IN_LEN);
839 MCDI_DECLARE_BUF(outbuf,
840 MC_CMD_NVRAM_READ_OUT_LEN(EFX_MCDI_NVRAM_LEN_MAX));
841 size_t outlen;
842 int rc;
843
844 MCDI_SET_DWORD(inbuf, NVRAM_READ_IN_TYPE, type);
845 MCDI_SET_DWORD(inbuf, NVRAM_READ_IN_OFFSET, offset);
846 MCDI_SET_DWORD(inbuf, NVRAM_READ_IN_LENGTH, length);
847
848 rc = efx_mcdi_rpc(efx, MC_CMD_NVRAM_READ, inbuf, sizeof(inbuf),
849 outbuf, sizeof(outbuf), &outlen);
850 if (rc)
851 goto fail;
852
853 memcpy(buffer, MCDI_PTR(outbuf, NVRAM_READ_OUT_READ_BUFFER), length);
854 return 0;
855
856fail:
857 netif_err(efx, hw, efx->net_dev, "%s: failed rc=%d\n", __func__, rc);
858 return rc;
859}
860
861int efx_mcdi_nvram_write(struct efx_nic *efx, unsigned int type,
862 loff_t offset, const u8 *buffer, size_t length)
863{
864 MCDI_DECLARE_BUF(inbuf,
865 MC_CMD_NVRAM_WRITE_IN_LEN(EFX_MCDI_NVRAM_LEN_MAX));
866 int rc;
867
868 MCDI_SET_DWORD(inbuf, NVRAM_WRITE_IN_TYPE, type);
869 MCDI_SET_DWORD(inbuf, NVRAM_WRITE_IN_OFFSET, offset);
870 MCDI_SET_DWORD(inbuf, NVRAM_WRITE_IN_LENGTH, length);
871 memcpy(MCDI_PTR(inbuf, NVRAM_WRITE_IN_WRITE_BUFFER), buffer, length);
872
873 BUILD_BUG_ON(MC_CMD_NVRAM_WRITE_OUT_LEN != 0);
874
875 rc = efx_mcdi_rpc(efx, MC_CMD_NVRAM_WRITE, inbuf,
876 ALIGN(MC_CMD_NVRAM_WRITE_IN_LEN(length), 4),
877 NULL, 0, NULL);
878 if (rc)
879 goto fail;
880
881 return 0;
882
883fail:
884 netif_err(efx, hw, efx->net_dev, "%s: failed rc=%d\n", __func__, rc);
885 return rc;
886}
887
888int efx_mcdi_nvram_erase(struct efx_nic *efx, unsigned int type,
889 loff_t offset, size_t length)
890{
891 MCDI_DECLARE_BUF(inbuf, MC_CMD_NVRAM_ERASE_IN_LEN);
892 int rc;
893
894 MCDI_SET_DWORD(inbuf, NVRAM_ERASE_IN_TYPE, type);
895 MCDI_SET_DWORD(inbuf, NVRAM_ERASE_IN_OFFSET, offset);
896 MCDI_SET_DWORD(inbuf, NVRAM_ERASE_IN_LENGTH, length);
897
898 BUILD_BUG_ON(MC_CMD_NVRAM_ERASE_OUT_LEN != 0);
899
900 rc = efx_mcdi_rpc(efx, MC_CMD_NVRAM_ERASE, inbuf, sizeof(inbuf),
901 NULL, 0, NULL);
902 if (rc)
903 goto fail;
904
905 return 0;
906
907fail:
908 netif_err(efx, hw, efx->net_dev, "%s: failed rc=%d\n", __func__, rc);
909 return rc;
910}
911
912int efx_mcdi_nvram_update_finish(struct efx_nic *efx, unsigned int type)
913{
914 MCDI_DECLARE_BUF(inbuf, MC_CMD_NVRAM_UPDATE_FINISH_IN_LEN);
915 int rc;
916
917 MCDI_SET_DWORD(inbuf, NVRAM_UPDATE_FINISH_IN_TYPE, type);
918
919 BUILD_BUG_ON(MC_CMD_NVRAM_UPDATE_FINISH_OUT_LEN != 0);
920
921 rc = efx_mcdi_rpc(efx, MC_CMD_NVRAM_UPDATE_FINISH, inbuf, sizeof(inbuf),
922 NULL, 0, NULL);
923 if (rc)
924 goto fail;
925
926 return 0;
927
928fail:
929 netif_err(efx, hw, efx->net_dev, "%s: failed rc=%d\n", __func__, rc);
930 return rc;
931}
932
933static int efx_mcdi_nvram_test(struct efx_nic *efx, unsigned int type) 814static int efx_mcdi_nvram_test(struct efx_nic *efx, unsigned int type)
934{ 815{
935 MCDI_DECLARE_BUF(inbuf, MC_CMD_NVRAM_TEST_IN_LEN); 816 MCDI_DECLARE_BUF(inbuf, MC_CMD_NVRAM_TEST_IN_LEN);
@@ -1272,3 +1153,236 @@ fail:
1272 return rc; 1153 return rc;
1273} 1154}
1274 1155
1156#ifdef CONFIG_SFC_MTD
1157
1158#define EFX_MCDI_NVRAM_LEN_MAX 128
1159
1160static int efx_mcdi_nvram_update_start(struct efx_nic *efx, unsigned int type)
1161{
1162 MCDI_DECLARE_BUF(inbuf, MC_CMD_NVRAM_UPDATE_START_IN_LEN);
1163 int rc;
1164
1165 MCDI_SET_DWORD(inbuf, NVRAM_UPDATE_START_IN_TYPE, type);
1166
1167 BUILD_BUG_ON(MC_CMD_NVRAM_UPDATE_START_OUT_LEN != 0);
1168
1169 rc = efx_mcdi_rpc(efx, MC_CMD_NVRAM_UPDATE_START, inbuf, sizeof(inbuf),
1170 NULL, 0, NULL);
1171 if (rc)
1172 goto fail;
1173
1174 return 0;
1175
1176fail:
1177 netif_err(efx, hw, efx->net_dev, "%s: failed rc=%d\n", __func__, rc);
1178 return rc;
1179}
1180
1181static int efx_mcdi_nvram_read(struct efx_nic *efx, unsigned int type,
1182 loff_t offset, u8 *buffer, size_t length)
1183{
1184 MCDI_DECLARE_BUF(inbuf, MC_CMD_NVRAM_READ_IN_LEN);
1185 MCDI_DECLARE_BUF(outbuf,
1186 MC_CMD_NVRAM_READ_OUT_LEN(EFX_MCDI_NVRAM_LEN_MAX));
1187 size_t outlen;
1188 int rc;
1189
1190 MCDI_SET_DWORD(inbuf, NVRAM_READ_IN_TYPE, type);
1191 MCDI_SET_DWORD(inbuf, NVRAM_READ_IN_OFFSET, offset);
1192 MCDI_SET_DWORD(inbuf, NVRAM_READ_IN_LENGTH, length);
1193
1194 rc = efx_mcdi_rpc(efx, MC_CMD_NVRAM_READ, inbuf, sizeof(inbuf),
1195 outbuf, sizeof(outbuf), &outlen);
1196 if (rc)
1197 goto fail;
1198
1199 memcpy(buffer, MCDI_PTR(outbuf, NVRAM_READ_OUT_READ_BUFFER), length);
1200 return 0;
1201
1202fail:
1203 netif_err(efx, hw, efx->net_dev, "%s: failed rc=%d\n", __func__, rc);
1204 return rc;
1205}
1206
1207static int efx_mcdi_nvram_write(struct efx_nic *efx, unsigned int type,
1208 loff_t offset, const u8 *buffer, size_t length)
1209{
1210 MCDI_DECLARE_BUF(inbuf,
1211 MC_CMD_NVRAM_WRITE_IN_LEN(EFX_MCDI_NVRAM_LEN_MAX));
1212 int rc;
1213
1214 MCDI_SET_DWORD(inbuf, NVRAM_WRITE_IN_TYPE, type);
1215 MCDI_SET_DWORD(inbuf, NVRAM_WRITE_IN_OFFSET, offset);
1216 MCDI_SET_DWORD(inbuf, NVRAM_WRITE_IN_LENGTH, length);
1217 memcpy(MCDI_PTR(inbuf, NVRAM_WRITE_IN_WRITE_BUFFER), buffer, length);
1218
1219 BUILD_BUG_ON(MC_CMD_NVRAM_WRITE_OUT_LEN != 0);
1220
1221 rc = efx_mcdi_rpc(efx, MC_CMD_NVRAM_WRITE, inbuf,
1222 ALIGN(MC_CMD_NVRAM_WRITE_IN_LEN(length), 4),
1223 NULL, 0, NULL);
1224 if (rc)
1225 goto fail;
1226
1227 return 0;
1228
1229fail:
1230 netif_err(efx, hw, efx->net_dev, "%s: failed rc=%d\n", __func__, rc);
1231 return rc;
1232}
1233
1234static int efx_mcdi_nvram_erase(struct efx_nic *efx, unsigned int type,
1235 loff_t offset, size_t length)
1236{
1237 MCDI_DECLARE_BUF(inbuf, MC_CMD_NVRAM_ERASE_IN_LEN);
1238 int rc;
1239
1240 MCDI_SET_DWORD(inbuf, NVRAM_ERASE_IN_TYPE, type);
1241 MCDI_SET_DWORD(inbuf, NVRAM_ERASE_IN_OFFSET, offset);
1242 MCDI_SET_DWORD(inbuf, NVRAM_ERASE_IN_LENGTH, length);
1243
1244 BUILD_BUG_ON(MC_CMD_NVRAM_ERASE_OUT_LEN != 0);
1245
1246 rc = efx_mcdi_rpc(efx, MC_CMD_NVRAM_ERASE, inbuf, sizeof(inbuf),
1247 NULL, 0, NULL);
1248 if (rc)
1249 goto fail;
1250
1251 return 0;
1252
1253fail:
1254 netif_err(efx, hw, efx->net_dev, "%s: failed rc=%d\n", __func__, rc);
1255 return rc;
1256}
1257
1258static int efx_mcdi_nvram_update_finish(struct efx_nic *efx, unsigned int type)
1259{
1260 MCDI_DECLARE_BUF(inbuf, MC_CMD_NVRAM_UPDATE_FINISH_IN_LEN);
1261 int rc;
1262
1263 MCDI_SET_DWORD(inbuf, NVRAM_UPDATE_FINISH_IN_TYPE, type);
1264
1265 BUILD_BUG_ON(MC_CMD_NVRAM_UPDATE_FINISH_OUT_LEN != 0);
1266
1267 rc = efx_mcdi_rpc(efx, MC_CMD_NVRAM_UPDATE_FINISH, inbuf, sizeof(inbuf),
1268 NULL, 0, NULL);
1269 if (rc)
1270 goto fail;
1271
1272 return 0;
1273
1274fail:
1275 netif_err(efx, hw, efx->net_dev, "%s: failed rc=%d\n", __func__, rc);
1276 return rc;
1277}
1278
1279int efx_mcdi_mtd_read(struct mtd_info *mtd, loff_t start,
1280 size_t len, size_t *retlen, u8 *buffer)
1281{
1282 struct efx_mcdi_mtd_partition *part = to_efx_mcdi_mtd_partition(mtd);
1283 struct efx_nic *efx = mtd->priv;
1284 loff_t offset = start;
1285 loff_t end = min_t(loff_t, start + len, mtd->size);
1286 size_t chunk;
1287 int rc = 0;
1288
1289 while (offset < end) {
1290 chunk = min_t(size_t, end - offset, EFX_MCDI_NVRAM_LEN_MAX);
1291 rc = efx_mcdi_nvram_read(efx, part->nvram_type, offset,
1292 buffer, chunk);
1293 if (rc)
1294 goto out;
1295 offset += chunk;
1296 buffer += chunk;
1297 }
1298out:
1299 *retlen = offset - start;
1300 return rc;
1301}
1302
1303int efx_mcdi_mtd_erase(struct mtd_info *mtd, loff_t start, size_t len)
1304{
1305 struct efx_mcdi_mtd_partition *part = to_efx_mcdi_mtd_partition(mtd);
1306 struct efx_nic *efx = mtd->priv;
1307 loff_t offset = start & ~((loff_t)(mtd->erasesize - 1));
1308 loff_t end = min_t(loff_t, start + len, mtd->size);
1309 size_t chunk = part->common.mtd.erasesize;
1310 int rc = 0;
1311
1312 if (!part->updating) {
1313 rc = efx_mcdi_nvram_update_start(efx, part->nvram_type);
1314 if (rc)
1315 goto out;
1316 part->updating = true;
1317 }
1318
1319 /* The MCDI interface can in fact do multiple erase blocks at once;
1320 * but erasing may be slow, so we make multiple calls here to avoid
1321 * tripping the MCDI RPC timeout. */
1322 while (offset < end) {
1323 rc = efx_mcdi_nvram_erase(efx, part->nvram_type, offset,
1324 chunk);
1325 if (rc)
1326 goto out;
1327 offset += chunk;
1328 }
1329out:
1330 return rc;
1331}
1332
1333int efx_mcdi_mtd_write(struct mtd_info *mtd, loff_t start,
1334 size_t len, size_t *retlen, const u8 *buffer)
1335{
1336 struct efx_mcdi_mtd_partition *part = to_efx_mcdi_mtd_partition(mtd);
1337 struct efx_nic *efx = mtd->priv;
1338 loff_t offset = start;
1339 loff_t end = min_t(loff_t, start + len, mtd->size);
1340 size_t chunk;
1341 int rc = 0;
1342
1343 if (!part->updating) {
1344 rc = efx_mcdi_nvram_update_start(efx, part->nvram_type);
1345 if (rc)
1346 goto out;
1347 part->updating = true;
1348 }
1349
1350 while (offset < end) {
1351 chunk = min_t(size_t, end - offset, EFX_MCDI_NVRAM_LEN_MAX);
1352 rc = efx_mcdi_nvram_write(efx, part->nvram_type, offset,
1353 buffer, chunk);
1354 if (rc)
1355 goto out;
1356 offset += chunk;
1357 buffer += chunk;
1358 }
1359out:
1360 *retlen = offset - start;
1361 return rc;
1362}
1363
1364int efx_mcdi_mtd_sync(struct mtd_info *mtd)
1365{
1366 struct efx_mcdi_mtd_partition *part = to_efx_mcdi_mtd_partition(mtd);
1367 struct efx_nic *efx = mtd->priv;
1368 int rc = 0;
1369
1370 if (part->updating) {
1371 part->updating = false;
1372 rc = efx_mcdi_nvram_update_finish(efx, part->nvram_type);
1373 }
1374
1375 return rc;
1376}
1377
1378void efx_mcdi_mtd_rename(struct efx_mtd_partition *part)
1379{
1380 struct efx_mcdi_mtd_partition *mcdi_part =
1381 container_of(part, struct efx_mcdi_mtd_partition, common);
1382 struct efx_nic *efx = part->mtd.priv;
1383
1384 snprintf(part->name, sizeof(part->name), "%s %s:%02x",
1385 efx->name, part->type_name, mcdi_part->fw_subtype);
1386}
1387
1388#endif /* CONFIG_SFC_MTD */
diff --git a/drivers/net/ethernet/sfc/mcdi.h b/drivers/net/ethernet/sfc/mcdi.h
index a465cc154139..5f67ac3f2c8a 100644
--- a/drivers/net/ethernet/sfc/mcdi.h
+++ b/drivers/net/ethernet/sfc/mcdi.h
@@ -65,6 +65,16 @@ struct efx_mcdi_mon {
65 unsigned int n_attrs; 65 unsigned int n_attrs;
66}; 66};
67 67
68struct efx_mcdi_mtd_partition {
69 struct efx_mtd_partition common;
70 bool updating;
71 u8 nvram_type;
72 u16 fw_subtype;
73};
74
75#define to_efx_mcdi_mtd_partition(mtd) \
76 container_of(mtd, struct efx_mcdi_mtd_partition, common.mtd)
77
68/** 78/**
69 * struct efx_mcdi_data - extra state for NICs that implement MCDI 79 * struct efx_mcdi_data - extra state for NICs that implement MCDI
70 * @iface: Interface/protocol state 80 * @iface: Interface/protocol state
@@ -250,18 +260,6 @@ extern int efx_mcdi_nvram_types(struct efx_nic *efx, u32 *nvram_types_out);
250extern int efx_mcdi_nvram_info(struct efx_nic *efx, unsigned int type, 260extern int efx_mcdi_nvram_info(struct efx_nic *efx, unsigned int type,
251 size_t *size_out, size_t *erase_size_out, 261 size_t *size_out, size_t *erase_size_out,
252 bool *protected_out); 262 bool *protected_out);
253extern int efx_mcdi_nvram_update_start(struct efx_nic *efx,
254 unsigned int type);
255extern int efx_mcdi_nvram_read(struct efx_nic *efx, unsigned int type,
256 loff_t offset, u8 *buffer, size_t length);
257extern int efx_mcdi_nvram_write(struct efx_nic *efx, unsigned int type,
258 loff_t offset, const u8 *buffer,
259 size_t length);
260#define EFX_MCDI_NVRAM_LEN_MAX 128
261extern int efx_mcdi_nvram_erase(struct efx_nic *efx, unsigned int type,
262 loff_t offset, size_t length);
263extern int efx_mcdi_nvram_update_finish(struct efx_nic *efx,
264 unsigned int type);
265extern int efx_mcdi_nvram_test_all(struct efx_nic *efx); 263extern int efx_mcdi_nvram_test_all(struct efx_nic *efx);
266extern int efx_mcdi_handle_assertion(struct efx_nic *efx); 264extern int efx_mcdi_handle_assertion(struct efx_nic *efx);
267extern void efx_mcdi_set_id_led(struct efx_nic *efx, enum efx_led_mode mode); 265extern void efx_mcdi_set_id_led(struct efx_nic *efx, enum efx_led_mode mode);
@@ -291,4 +289,14 @@ static inline int efx_mcdi_mon_probe(struct efx_nic *efx) { return 0; }
291static inline void efx_mcdi_mon_remove(struct efx_nic *efx) {} 289static inline void efx_mcdi_mon_remove(struct efx_nic *efx) {}
292#endif 290#endif
293 291
292#ifdef CONFIG_SFC_MTD
293extern int efx_mcdi_mtd_read(struct mtd_info *mtd, loff_t start,
294 size_t len, size_t *retlen, u8 *buffer);
295extern int efx_mcdi_mtd_erase(struct mtd_info *mtd, loff_t start, size_t len);
296extern int efx_mcdi_mtd_write(struct mtd_info *mtd, loff_t start,
297 size_t len, size_t *retlen, const u8 *buffer);
298extern int efx_mcdi_mtd_sync(struct mtd_info *mtd);
299extern void efx_mcdi_mtd_rename(struct efx_mtd_partition *part);
300#endif
301
294#endif /* EFX_MCDI_H */ 302#endif /* EFX_MCDI_H */
diff --git a/drivers/net/ethernet/sfc/mtd.c b/drivers/net/ethernet/sfc/mtd.c
index f5819c746e7a..8be9a69a61e1 100644
--- a/drivers/net/ethernet/sfc/mtd.c
+++ b/drivers/net/ethernet/sfc/mtd.c
@@ -8,167 +8,17 @@
8 * by the Free Software Foundation, incorporated herein by reference. 8 * by the Free Software Foundation, incorporated herein by reference.
9 */ 9 */
10 10
11#include <linux/bitops.h>
12#include <linux/module.h> 11#include <linux/module.h>
13#include <linux/mtd/mtd.h> 12#include <linux/mtd/mtd.h>
14#include <linux/delay.h>
15#include <linux/slab.h> 13#include <linux/slab.h>
16#include <linux/rtnetlink.h> 14#include <linux/rtnetlink.h>
17 15
18#include "net_driver.h" 16#include "net_driver.h"
19#include "spi.h"
20#include "efx.h" 17#include "efx.h"
21#include "nic.h"
22#include "mcdi.h"
23#include "mcdi_pcol.h"
24
25#define FALCON_SPI_VERIFY_BUF_LEN 16
26
27struct efx_mtd_partition {
28 struct list_head node;
29 struct mtd_info mtd;
30 const char *dev_type_name;
31 const char *type_name;
32 char name[IFNAMSIZ + 20];
33};
34
35struct falcon_mtd_partition {
36 struct efx_mtd_partition common;
37 const struct falcon_spi_device *spi;
38 size_t offset;
39};
40
41struct efx_mtd_ops {
42 void (*rename)(struct efx_mtd_partition *part);
43 int (*read)(struct mtd_info *mtd, loff_t start, size_t len,
44 size_t *retlen, u8 *buffer);
45 int (*erase)(struct mtd_info *mtd, loff_t start, size_t len);
46 int (*write)(struct mtd_info *mtd, loff_t start, size_t len,
47 size_t *retlen, const u8 *buffer);
48 int (*sync)(struct mtd_info *mtd);
49};
50 18
51#define to_efx_mtd_partition(mtd) \ 19#define to_efx_mtd_partition(mtd) \
52 container_of(mtd, struct efx_mtd_partition, mtd) 20 container_of(mtd, struct efx_mtd_partition, mtd)
53 21
54#define to_falcon_mtd_partition(mtd) \
55 container_of(mtd, struct falcon_mtd_partition, common.mtd)
56
57static int falcon_mtd_probe(struct efx_nic *efx);
58static int siena_mtd_probe(struct efx_nic *efx);
59
60/* SPI utilities */
61
62static int
63falcon_spi_slow_wait(struct falcon_mtd_partition *part, bool uninterruptible)
64{
65 const struct falcon_spi_device *spi = part->spi;
66 struct efx_nic *efx = part->common.mtd.priv;
67 u8 status;
68 int rc, i;
69
70 /* Wait up to 4s for flash/EEPROM to finish a slow operation. */
71 for (i = 0; i < 40; i++) {
72 __set_current_state(uninterruptible ?
73 TASK_UNINTERRUPTIBLE : TASK_INTERRUPTIBLE);
74 schedule_timeout(HZ / 10);
75 rc = falcon_spi_cmd(efx, spi, SPI_RDSR, -1, NULL,
76 &status, sizeof(status));
77 if (rc)
78 return rc;
79 if (!(status & SPI_STATUS_NRDY))
80 return 0;
81 if (signal_pending(current))
82 return -EINTR;
83 }
84 pr_err("%s: timed out waiting for %s\n",
85 part->common.name, part->common.dev_type_name);
86 return -ETIMEDOUT;
87}
88
89static int
90falcon_spi_unlock(struct efx_nic *efx, const struct falcon_spi_device *spi)
91{
92 const u8 unlock_mask = (SPI_STATUS_BP2 | SPI_STATUS_BP1 |
93 SPI_STATUS_BP0);
94 u8 status;
95 int rc;
96
97 rc = falcon_spi_cmd(efx, spi, SPI_RDSR, -1, NULL,
98 &status, sizeof(status));
99 if (rc)
100 return rc;
101
102 if (!(status & unlock_mask))
103 return 0; /* already unlocked */
104
105 rc = falcon_spi_cmd(efx, spi, SPI_WREN, -1, NULL, NULL, 0);
106 if (rc)
107 return rc;
108 rc = falcon_spi_cmd(efx, spi, SPI_SST_EWSR, -1, NULL, NULL, 0);
109 if (rc)
110 return rc;
111
112 status &= ~unlock_mask;
113 rc = falcon_spi_cmd(efx, spi, SPI_WRSR, -1, &status,
114 NULL, sizeof(status));
115 if (rc)
116 return rc;
117 rc = falcon_spi_wait_write(efx, spi);
118 if (rc)
119 return rc;
120
121 return 0;
122}
123
124static int
125falcon_spi_erase(struct falcon_mtd_partition *part, loff_t start, size_t len)
126{
127 const struct falcon_spi_device *spi = part->spi;
128 struct efx_nic *efx = part->common.mtd.priv;
129 unsigned pos, block_len;
130 u8 empty[FALCON_SPI_VERIFY_BUF_LEN];
131 u8 buffer[FALCON_SPI_VERIFY_BUF_LEN];
132 int rc;
133
134 if (len != spi->erase_size)
135 return -EINVAL;
136
137 if (spi->erase_command == 0)
138 return -EOPNOTSUPP;
139
140 rc = falcon_spi_unlock(efx, spi);
141 if (rc)
142 return rc;
143 rc = falcon_spi_cmd(efx, spi, SPI_WREN, -1, NULL, NULL, 0);
144 if (rc)
145 return rc;
146 rc = falcon_spi_cmd(efx, spi, spi->erase_command, start, NULL,
147 NULL, 0);
148 if (rc)
149 return rc;
150 rc = falcon_spi_slow_wait(part, false);
151
152 /* Verify the entire region has been wiped */
153 memset(empty, 0xff, sizeof(empty));
154 for (pos = 0; pos < len; pos += block_len) {
155 block_len = min(len - pos, sizeof(buffer));
156 rc = falcon_spi_read(efx, spi, start + pos, block_len,
157 NULL, buffer);
158 if (rc)
159 return rc;
160 if (memcmp(empty, buffer, block_len))
161 return -EIO;
162
163 /* Avoid locking up the system */
164 cond_resched();
165 if (signal_pending(current))
166 return -EINTR;
167 }
168
169 return rc;
170}
171
172/* MTD interface */ 22/* MTD interface */
173 23
174static int efx_mtd_erase(struct mtd_info *mtd, struct erase_info *erase) 24static int efx_mtd_erase(struct mtd_info *mtd, struct erase_info *erase)
@@ -176,7 +26,7 @@ static int efx_mtd_erase(struct mtd_info *mtd, struct erase_info *erase)
176 struct efx_nic *efx = mtd->priv; 26 struct efx_nic *efx = mtd->priv;
177 int rc; 27 int rc;
178 28
179 rc = efx->mtd_ops->erase(mtd, erase->addr, erase->len); 29 rc = efx->type->mtd_erase(mtd, erase->addr, erase->len);
180 if (rc == 0) { 30 if (rc == 0) {
181 erase->state = MTD_ERASE_DONE; 31 erase->state = MTD_ERASE_DONE;
182 } else { 32 } else {
@@ -193,7 +43,7 @@ static void efx_mtd_sync(struct mtd_info *mtd)
193 struct efx_nic *efx = mtd->priv; 43 struct efx_nic *efx = mtd->priv;
194 int rc; 44 int rc;
195 45
196 rc = efx->mtd_ops->sync(mtd); 46 rc = efx->type->mtd_sync(mtd);
197 if (rc) 47 if (rc)
198 pr_err("%s: %s sync failed (%d)\n", 48 pr_err("%s: %s sync failed (%d)\n",
199 part->name, part->dev_type_name, rc); 49 part->name, part->dev_type_name, rc);
@@ -213,15 +63,8 @@ static void efx_mtd_remove_partition(struct efx_mtd_partition *part)
213 list_del(&part->node); 63 list_del(&part->node);
214} 64}
215 65
216static void efx_mtd_rename_partition(struct efx_mtd_partition *part) 66int efx_mtd_add(struct efx_nic *efx, struct efx_mtd_partition *parts,
217{ 67 size_t n_parts, size_t sizeof_part)
218 struct efx_nic *efx = part->mtd.priv;
219
220 efx->mtd_ops->rename(part);
221}
222
223static int efx_mtd_add(struct efx_nic *efx, struct efx_mtd_partition *parts,
224 size_t n_parts, size_t sizeof_part)
225{ 68{
226 struct efx_mtd_partition *part; 69 struct efx_mtd_partition *part;
227 size_t i; 70 size_t i;
@@ -236,11 +79,11 @@ static int efx_mtd_add(struct efx_nic *efx, struct efx_mtd_partition *parts,
236 part->mtd.priv = efx; 79 part->mtd.priv = efx;
237 part->mtd.name = part->name; 80 part->mtd.name = part->name;
238 part->mtd._erase = efx_mtd_erase; 81 part->mtd._erase = efx_mtd_erase;
239 part->mtd._read = efx->mtd_ops->read; 82 part->mtd._read = efx->type->mtd_read;
240 part->mtd._write = efx->mtd_ops->write; 83 part->mtd._write = efx->type->mtd_write;
241 part->mtd._sync = efx_mtd_sync; 84 part->mtd._sync = efx_mtd_sync;
242 85
243 efx_mtd_rename_partition(part); 86 efx->type->mtd_rename(part);
244 87
245 if (mtd_device_register(&part->mtd, NULL, 0)) 88 if (mtd_device_register(&part->mtd, NULL, 0))
246 goto fail; 89 goto fail;
@@ -286,396 +129,5 @@ void efx_mtd_rename(struct efx_nic *efx)
286 ASSERT_RTNL(); 129 ASSERT_RTNL();
287 130
288 list_for_each_entry(part, &efx->mtd_list, node) 131 list_for_each_entry(part, &efx->mtd_list, node)
289 efx_mtd_rename_partition(part); 132 efx->type->mtd_rename(part);
290}
291
292int efx_mtd_probe(struct efx_nic *efx)
293{
294 if (efx_nic_rev(efx) >= EFX_REV_SIENA_A0)
295 return siena_mtd_probe(efx);
296 else
297 return falcon_mtd_probe(efx);
298}
299
300/* Implementation of MTD operations for Falcon */
301
302static void falcon_mtd_rename(struct efx_mtd_partition *part)
303{
304 struct efx_nic *efx = part->mtd.priv;
305
306 snprintf(part->name, sizeof(part->name), "%s %s",
307 efx->name, part->type_name);
308}
309
310static int falcon_mtd_read(struct mtd_info *mtd, loff_t start,
311 size_t len, size_t *retlen, u8 *buffer)
312{
313 struct falcon_mtd_partition *part = to_falcon_mtd_partition(mtd);
314 struct efx_nic *efx = mtd->priv;
315 struct falcon_nic_data *nic_data = efx->nic_data;
316 int rc;
317
318 rc = mutex_lock_interruptible(&nic_data->spi_lock);
319 if (rc)
320 return rc;
321 rc = falcon_spi_read(efx, part->spi, part->offset + start,
322 len, retlen, buffer);
323 mutex_unlock(&nic_data->spi_lock);
324 return rc;
325}
326
327static int falcon_mtd_erase(struct mtd_info *mtd, loff_t start, size_t len)
328{
329 struct falcon_mtd_partition *part = to_falcon_mtd_partition(mtd);
330 struct efx_nic *efx = mtd->priv;
331 struct falcon_nic_data *nic_data = efx->nic_data;
332 int rc;
333
334 rc = mutex_lock_interruptible(&nic_data->spi_lock);
335 if (rc)
336 return rc;
337 rc = falcon_spi_erase(part, part->offset + start, len);
338 mutex_unlock(&nic_data->spi_lock);
339 return rc;
340}
341
342static int falcon_mtd_write(struct mtd_info *mtd, loff_t start,
343 size_t len, size_t *retlen, const u8 *buffer)
344{
345 struct falcon_mtd_partition *part = to_falcon_mtd_partition(mtd);
346 struct efx_nic *efx = mtd->priv;
347 struct falcon_nic_data *nic_data = efx->nic_data;
348 int rc;
349
350 rc = mutex_lock_interruptible(&nic_data->spi_lock);
351 if (rc)
352 return rc;
353 rc = falcon_spi_write(efx, part->spi, part->offset + start,
354 len, retlen, buffer);
355 mutex_unlock(&nic_data->spi_lock);
356 return rc;
357}
358
359static int falcon_mtd_sync(struct mtd_info *mtd)
360{
361 struct falcon_mtd_partition *part = to_falcon_mtd_partition(mtd);
362 struct efx_nic *efx = mtd->priv;
363 struct falcon_nic_data *nic_data = efx->nic_data;
364 int rc;
365
366 mutex_lock(&nic_data->spi_lock);
367 rc = falcon_spi_slow_wait(part, true);
368 mutex_unlock(&nic_data->spi_lock);
369 return rc;
370}
371
372static const struct efx_mtd_ops falcon_mtd_ops = {
373 .rename = falcon_mtd_rename,
374 .read = falcon_mtd_read,
375 .erase = falcon_mtd_erase,
376 .write = falcon_mtd_write,
377 .sync = falcon_mtd_sync,
378};
379
380static int falcon_mtd_probe(struct efx_nic *efx)
381{
382 struct falcon_nic_data *nic_data = efx->nic_data;
383 struct falcon_mtd_partition *parts;
384 struct falcon_spi_device *spi;
385 size_t n_parts;
386 int rc = -ENODEV;
387
388 ASSERT_RTNL();
389
390 efx->mtd_ops = &falcon_mtd_ops;
391
392 /* Allocate space for maximum number of partitions */
393 parts = kcalloc(2, sizeof(*parts), GFP_KERNEL);
394 n_parts = 0;
395
396 spi = &nic_data->spi_flash;
397 if (falcon_spi_present(spi) && spi->size > FALCON_FLASH_BOOTCODE_START) {
398 parts[n_parts].spi = spi;
399 parts[n_parts].offset = FALCON_FLASH_BOOTCODE_START;
400 parts[n_parts].common.dev_type_name = "flash";
401 parts[n_parts].common.type_name = "sfc_flash_bootrom";
402 parts[n_parts].common.mtd.type = MTD_NORFLASH;
403 parts[n_parts].common.mtd.flags = MTD_CAP_NORFLASH;
404 parts[n_parts].common.mtd.size = spi->size - FALCON_FLASH_BOOTCODE_START;
405 parts[n_parts].common.mtd.erasesize = spi->erase_size;
406 n_parts++;
407 }
408
409 spi = &nic_data->spi_eeprom;
410 if (falcon_spi_present(spi) && spi->size > FALCON_EEPROM_BOOTCONFIG_START) {
411 parts[n_parts].spi = spi;
412 parts[n_parts].offset = FALCON_EEPROM_BOOTCONFIG_START;
413 parts[n_parts].common.dev_type_name = "EEPROM";
414 parts[n_parts].common.type_name = "sfc_bootconfig";
415 parts[n_parts].common.mtd.type = MTD_RAM;
416 parts[n_parts].common.mtd.flags = MTD_CAP_RAM;
417 parts[n_parts].common.mtd.size =
418 min(spi->size, FALCON_EEPROM_BOOTCONFIG_END) -
419 FALCON_EEPROM_BOOTCONFIG_START;
420 parts[n_parts].common.mtd.erasesize = spi->erase_size;
421 n_parts++;
422 }
423
424 rc = efx_mtd_add(efx, &parts[0].common, n_parts, sizeof(*parts));
425 if (rc)
426 kfree(parts);
427 return rc;
428}
429
430/* Implementation of MTD operations for Siena */
431
432struct efx_mcdi_mtd_partition {
433 struct efx_mtd_partition common;
434 bool updating;
435 u8 nvram_type;
436 u16 fw_subtype;
437};
438
439#define to_efx_mcdi_mtd_partition(mtd) \
440 container_of(mtd, struct efx_mcdi_mtd_partition, common.mtd)
441
442static void siena_mtd_rename(struct efx_mtd_partition *part)
443{
444 struct efx_mcdi_mtd_partition *mcdi_part =
445 container_of(part, struct efx_mcdi_mtd_partition, common);
446 struct efx_nic *efx = part->mtd.priv;
447
448 snprintf(part->name, sizeof(part->name), "%s %s:%02x",
449 efx->name, part->type_name, mcdi_part->fw_subtype);
450}
451
452static int siena_mtd_read(struct mtd_info *mtd, loff_t start,
453 size_t len, size_t *retlen, u8 *buffer)
454{
455 struct efx_mcdi_mtd_partition *part = to_efx_mcdi_mtd_partition(mtd);
456 struct efx_nic *efx = mtd->priv;
457 loff_t offset = start;
458 loff_t end = min_t(loff_t, start + len, mtd->size);
459 size_t chunk;
460 int rc = 0;
461
462 while (offset < end) {
463 chunk = min_t(size_t, end - offset, EFX_MCDI_NVRAM_LEN_MAX);
464 rc = efx_mcdi_nvram_read(efx, part->nvram_type, offset,
465 buffer, chunk);
466 if (rc)
467 goto out;
468 offset += chunk;
469 buffer += chunk;
470 }
471out:
472 *retlen = offset - start;
473 return rc;
474}
475
476static int siena_mtd_erase(struct mtd_info *mtd, loff_t start, size_t len)
477{
478 struct efx_mcdi_mtd_partition *part = to_efx_mcdi_mtd_partition(mtd);
479 struct efx_nic *efx = mtd->priv;
480 loff_t offset = start & ~((loff_t)(mtd->erasesize - 1));
481 loff_t end = min_t(loff_t, start + len, mtd->size);
482 size_t chunk = part->common.mtd.erasesize;
483 int rc = 0;
484
485 if (!part->updating) {
486 rc = efx_mcdi_nvram_update_start(efx, part->nvram_type);
487 if (rc)
488 goto out;
489 part->updating = true;
490 }
491
492 /* The MCDI interface can in fact do multiple erase blocks at once;
493 * but erasing may be slow, so we make multiple calls here to avoid
494 * tripping the MCDI RPC timeout. */
495 while (offset < end) {
496 rc = efx_mcdi_nvram_erase(efx, part->nvram_type, offset,
497 chunk);
498 if (rc)
499 goto out;
500 offset += chunk;
501 }
502out:
503 return rc;
504}
505
506static int siena_mtd_write(struct mtd_info *mtd, loff_t start,
507 size_t len, size_t *retlen, const u8 *buffer)
508{
509 struct efx_mcdi_mtd_partition *part = to_efx_mcdi_mtd_partition(mtd);
510 struct efx_nic *efx = mtd->priv;
511 loff_t offset = start;
512 loff_t end = min_t(loff_t, start + len, mtd->size);
513 size_t chunk;
514 int rc = 0;
515
516 if (!part->updating) {
517 rc = efx_mcdi_nvram_update_start(efx, part->nvram_type);
518 if (rc)
519 goto out;
520 part->updating = true;
521 }
522
523 while (offset < end) {
524 chunk = min_t(size_t, end - offset, EFX_MCDI_NVRAM_LEN_MAX);
525 rc = efx_mcdi_nvram_write(efx, part->nvram_type, offset,
526 buffer, chunk);
527 if (rc)
528 goto out;
529 offset += chunk;
530 buffer += chunk;
531 }
532out:
533 *retlen = offset - start;
534 return rc;
535}
536
537static int siena_mtd_sync(struct mtd_info *mtd)
538{
539 struct efx_mcdi_mtd_partition *part = to_efx_mcdi_mtd_partition(mtd);
540 struct efx_nic *efx = mtd->priv;
541 int rc = 0;
542
543 if (part->updating) {
544 part->updating = false;
545 rc = efx_mcdi_nvram_update_finish(efx, part->nvram_type);
546 }
547
548 return rc;
549} 133}
550
551static const struct efx_mtd_ops siena_mtd_ops = {
552 .rename = siena_mtd_rename,
553 .read = siena_mtd_read,
554 .erase = siena_mtd_erase,
555 .write = siena_mtd_write,
556 .sync = siena_mtd_sync,
557};
558
559struct siena_nvram_type_info {
560 int port;
561 const char *name;
562};
563
564static const struct siena_nvram_type_info siena_nvram_types[] = {
565 [MC_CMD_NVRAM_TYPE_DISABLED_CALLISTO] = { 0, "sfc_dummy_phy" },
566 [MC_CMD_NVRAM_TYPE_MC_FW] = { 0, "sfc_mcfw" },
567 [MC_CMD_NVRAM_TYPE_MC_FW_BACKUP] = { 0, "sfc_mcfw_backup" },
568 [MC_CMD_NVRAM_TYPE_STATIC_CFG_PORT0] = { 0, "sfc_static_cfg" },
569 [MC_CMD_NVRAM_TYPE_STATIC_CFG_PORT1] = { 1, "sfc_static_cfg" },
570 [MC_CMD_NVRAM_TYPE_DYNAMIC_CFG_PORT0] = { 0, "sfc_dynamic_cfg" },
571 [MC_CMD_NVRAM_TYPE_DYNAMIC_CFG_PORT1] = { 1, "sfc_dynamic_cfg" },
572 [MC_CMD_NVRAM_TYPE_EXP_ROM] = { 0, "sfc_exp_rom" },
573 [MC_CMD_NVRAM_TYPE_EXP_ROM_CFG_PORT0] = { 0, "sfc_exp_rom_cfg" },
574 [MC_CMD_NVRAM_TYPE_EXP_ROM_CFG_PORT1] = { 1, "sfc_exp_rom_cfg" },
575 [MC_CMD_NVRAM_TYPE_PHY_PORT0] = { 0, "sfc_phy_fw" },
576 [MC_CMD_NVRAM_TYPE_PHY_PORT1] = { 1, "sfc_phy_fw" },
577 [MC_CMD_NVRAM_TYPE_FPGA] = { 0, "sfc_fpga" },
578};
579
580static int siena_mtd_probe_partition(struct efx_nic *efx,
581 struct efx_mcdi_mtd_partition *part,
582 unsigned int type)
583{
584 const struct siena_nvram_type_info *info;
585 size_t size, erase_size;
586 bool protected;
587 int rc;
588
589 if (type >= ARRAY_SIZE(siena_nvram_types) ||
590 siena_nvram_types[type].name == NULL)
591 return -ENODEV;
592
593 info = &siena_nvram_types[type];
594
595 if (info->port != efx_port_num(efx))
596 return -ENODEV;
597
598 rc = efx_mcdi_nvram_info(efx, type, &size, &erase_size, &protected);
599 if (rc)
600 return rc;
601 if (protected)
602 return -ENODEV; /* hide it */
603
604 part->nvram_type = type;
605 part->common.dev_type_name = "Siena NVRAM manager";
606 part->common.type_name = info->name;
607
608 part->common.mtd.type = MTD_NORFLASH;
609 part->common.mtd.flags = MTD_CAP_NORFLASH;
610 part->common.mtd.size = size;
611 part->common.mtd.erasesize = erase_size;
612
613 return 0;
614}
615
616static int siena_mtd_get_fw_subtypes(struct efx_nic *efx,
617 struct efx_mcdi_mtd_partition *parts,
618 size_t n_parts)
619{
620 uint16_t fw_subtype_list[
621 MC_CMD_GET_BOARD_CFG_OUT_FW_SUBTYPE_LIST_MAXNUM];
622 size_t i;
623 int rc;
624
625 rc = efx_mcdi_get_board_cfg(efx, NULL, fw_subtype_list, NULL);
626 if (rc)
627 return rc;
628
629 for (i = 0; i < n_parts; i++)
630 parts[i].fw_subtype = fw_subtype_list[parts[i].nvram_type];
631
632 return 0;
633}
634
635static int siena_mtd_probe(struct efx_nic *efx)
636{
637 struct efx_mcdi_mtd_partition *parts;
638 u32 nvram_types;
639 unsigned int type;
640 size_t n_parts;
641 int rc;
642
643 ASSERT_RTNL();
644
645 efx->mtd_ops = &siena_mtd_ops;
646
647 rc = efx_mcdi_nvram_types(efx, &nvram_types);
648 if (rc)
649 return rc;
650
651 parts = kcalloc(hweight32(nvram_types), sizeof(*parts), GFP_KERNEL);
652 if (!parts)
653 return -ENOMEM;
654
655 type = 0;
656 n_parts = 0;
657
658 while (nvram_types != 0) {
659 if (nvram_types & 1) {
660 rc = siena_mtd_probe_partition(efx, &parts[n_parts],
661 type);
662 if (rc == 0)
663 n_parts++;
664 else if (rc != -ENODEV)
665 goto fail;
666 }
667 type++;
668 nvram_types >>= 1;
669 }
670
671 rc = siena_mtd_get_fw_subtypes(efx, parts, n_parts);
672 if (rc)
673 goto fail;
674
675 rc = efx_mtd_add(efx, &parts[0].common, n_parts, sizeof(*parts));
676fail:
677 if (rc)
678 kfree(parts);
679 return rc;
680}
681
diff --git a/drivers/net/ethernet/sfc/net_driver.h b/drivers/net/ethernet/sfc/net_driver.h
index 958ede16077a..fa881cdd9dcc 100644
--- a/drivers/net/ethernet/sfc/net_driver.h
+++ b/drivers/net/ethernet/sfc/net_driver.h
@@ -27,6 +27,7 @@
27#include <linux/mutex.h> 27#include <linux/mutex.h>
28#include <linux/vmalloc.h> 28#include <linux/vmalloc.h>
29#include <linux/i2c.h> 29#include <linux/i2c.h>
30#include <linux/mtd/mtd.h>
30 31
31#include "enum.h" 32#include "enum.h"
32#include "bitfield.h" 33#include "bitfield.h"
@@ -868,7 +869,6 @@ struct efx_nic {
868 struct delayed_work selftest_work; 869 struct delayed_work selftest_work;
869 870
870#ifdef CONFIG_SFC_MTD 871#ifdef CONFIG_SFC_MTD
871 const struct efx_mtd_ops *mtd_ops;
872 struct list_head mtd_list; 872 struct list_head mtd_list;
873#endif 873#endif
874 874
@@ -954,6 +954,14 @@ static inline unsigned int efx_port_num(struct efx_nic *efx)
954 return efx->port_num; 954 return efx->port_num;
955} 955}
956 956
957struct efx_mtd_partition {
958 struct list_head node;
959 struct mtd_info mtd;
960 const char *dev_type_name;
961 const char *type_name;
962 char name[IFNAMSIZ + 20];
963};
964
957/** 965/**
958 * struct efx_nic_type - Efx device type definition 966 * struct efx_nic_type - Efx device type definition
959 * @mem_map_size: Get memory BAR mapped size 967 * @mem_map_size: Get memory BAR mapped size
@@ -1047,6 +1055,15 @@ static inline unsigned int efx_port_num(struct efx_nic *efx)
1047 * @filter_rfs_expire_one: Consider expiring a filter inserted for RFS. 1055 * @filter_rfs_expire_one: Consider expiring a filter inserted for RFS.
1048 * This must check whether the specified table entry is used by RFS 1056 * This must check whether the specified table entry is used by RFS
1049 * and that rps_may_expire_flow() returns true for it. 1057 * and that rps_may_expire_flow() returns true for it.
1058 * @mtd_probe: Probe and add MTD partitions associated with this net device,
1059 * using efx_mtd_add()
1060 * @mtd_rename: Set an MTD partition name using the net device name
1061 * @mtd_read: Read from an MTD partition
1062 * @mtd_erase: Erase part of an MTD partition
1063 * @mtd_write: Write to an MTD partition
1064 * @mtd_sync: Wait for write-back to complete on MTD partition. This
1065 * also notifies the driver that a writer has finished using this
1066 * partition.
1050 * @revision: Hardware architecture revision 1067 * @revision: Hardware architecture revision
1051 * @txd_ptr_tbl_base: TX descriptor ring base address 1068 * @txd_ptr_tbl_base: TX descriptor ring base address
1052 * @rxd_ptr_tbl_base: RX descriptor ring base address 1069 * @rxd_ptr_tbl_base: RX descriptor ring base address
@@ -1150,6 +1167,16 @@ struct efx_nic_type {
1150 bool (*filter_rfs_expire_one)(struct efx_nic *efx, u32 flow_id, 1167 bool (*filter_rfs_expire_one)(struct efx_nic *efx, u32 flow_id,
1151 unsigned int index); 1168 unsigned int index);
1152#endif 1169#endif
1170#ifdef CONFIG_SFC_MTD
1171 int (*mtd_probe)(struct efx_nic *efx);
1172 void (*mtd_rename)(struct efx_mtd_partition *part);
1173 int (*mtd_read)(struct mtd_info *mtd, loff_t start, size_t len,
1174 size_t *retlen, u8 *buffer);
1175 int (*mtd_erase)(struct mtd_info *mtd, loff_t start, size_t len);
1176 int (*mtd_write)(struct mtd_info *mtd, loff_t start, size_t len,
1177 size_t *retlen, const u8 *buffer);
1178 int (*mtd_sync)(struct mtd_info *mtd);
1179#endif
1153 1180
1154 int revision; 1181 int revision;
1155 unsigned int txd_ptr_tbl_base; 1182 unsigned int txd_ptr_tbl_base;
diff --git a/drivers/net/ethernet/sfc/nic.h b/drivers/net/ethernet/sfc/nic.h
index b90dc8a24cca..2b84aeb3c8ce 100644
--- a/drivers/net/ethernet/sfc/nic.h
+++ b/drivers/net/ethernet/sfc/nic.h
@@ -16,7 +16,6 @@
16#include "net_driver.h" 16#include "net_driver.h"
17#include "efx.h" 17#include "efx.h"
18#include "mcdi.h" 18#include "mcdi.h"
19#include "spi.h"
20 19
21/* 20/*
22 * Falcon hardware control 21 * Falcon hardware control
@@ -164,6 +163,38 @@ struct falcon_board {
164}; 163};
165 164
166/** 165/**
166 * struct falcon_spi_device - a Falcon SPI (Serial Peripheral Interface) device
167 * @device_id: Controller's id for the device
168 * @size: Size (in bytes)
169 * @addr_len: Number of address bytes in read/write commands
170 * @munge_address: Flag whether addresses should be munged.
171 * Some devices with 9-bit addresses (e.g. AT25040A EEPROM)
172 * use bit 3 of the command byte as address bit A8, rather
173 * than having a two-byte address. If this flag is set, then
174 * commands should be munged in this way.
175 * @erase_command: Erase command (or 0 if sector erase not needed).
176 * @erase_size: Erase sector size (in bytes)
177 * Erase commands affect sectors with this size and alignment.
178 * This must be a power of two.
179 * @block_size: Write block size (in bytes).
180 * Write commands are limited to blocks with this size and alignment.
181 */
182struct falcon_spi_device {
183 int device_id;
184 unsigned int size;
185 unsigned int addr_len;
186 unsigned int munge_address:1;
187 u8 erase_command;
188 unsigned int erase_size;
189 unsigned int block_size;
190};
191
192static inline bool falcon_spi_present(const struct falcon_spi_device *spi)
193{
194 return spi->size != 0;
195}
196
197/**
167 * struct falcon_nic_data - Falcon NIC state 198 * struct falcon_nic_data - Falcon NIC state
168 * @pci_dev2: Secondary function of Falcon A 199 * @pci_dev2: Secondary function of Falcon A
169 * @board: Board state and functions 200 * @board: Board state and functions
diff --git a/drivers/net/ethernet/sfc/siena.c b/drivers/net/ethernet/sfc/siena.c
index 1be81e431f07..11b4739b1705 100644
--- a/drivers/net/ethernet/sfc/siena.c
+++ b/drivers/net/ethernet/sfc/siena.c
@@ -18,7 +18,6 @@
18#include "bitfield.h" 18#include "bitfield.h"
19#include "efx.h" 19#include "efx.h"
20#include "nic.h" 20#include "nic.h"
21#include "spi.h"
22#include "farch_regs.h" 21#include "farch_regs.h"
23#include "io.h" 22#include "io.h"
24#include "phy.h" 23#include "phy.h"
@@ -674,6 +673,138 @@ static int siena_mcdi_poll_reboot(struct efx_nic *efx)
674 673
675/************************************************************************** 674/**************************************************************************
676 * 675 *
676 * MTD
677 *
678 **************************************************************************
679 */
680
681#ifdef CONFIG_SFC_MTD
682
683struct siena_nvram_type_info {
684 int port;
685 const char *name;
686};
687
688static const struct siena_nvram_type_info siena_nvram_types[] = {
689 [MC_CMD_NVRAM_TYPE_DISABLED_CALLISTO] = { 0, "sfc_dummy_phy" },
690 [MC_CMD_NVRAM_TYPE_MC_FW] = { 0, "sfc_mcfw" },
691 [MC_CMD_NVRAM_TYPE_MC_FW_BACKUP] = { 0, "sfc_mcfw_backup" },
692 [MC_CMD_NVRAM_TYPE_STATIC_CFG_PORT0] = { 0, "sfc_static_cfg" },
693 [MC_CMD_NVRAM_TYPE_STATIC_CFG_PORT1] = { 1, "sfc_static_cfg" },
694 [MC_CMD_NVRAM_TYPE_DYNAMIC_CFG_PORT0] = { 0, "sfc_dynamic_cfg" },
695 [MC_CMD_NVRAM_TYPE_DYNAMIC_CFG_PORT1] = { 1, "sfc_dynamic_cfg" },
696 [MC_CMD_NVRAM_TYPE_EXP_ROM] = { 0, "sfc_exp_rom" },
697 [MC_CMD_NVRAM_TYPE_EXP_ROM_CFG_PORT0] = { 0, "sfc_exp_rom_cfg" },
698 [MC_CMD_NVRAM_TYPE_EXP_ROM_CFG_PORT1] = { 1, "sfc_exp_rom_cfg" },
699 [MC_CMD_NVRAM_TYPE_PHY_PORT0] = { 0, "sfc_phy_fw" },
700 [MC_CMD_NVRAM_TYPE_PHY_PORT1] = { 1, "sfc_phy_fw" },
701 [MC_CMD_NVRAM_TYPE_FPGA] = { 0, "sfc_fpga" },
702};
703
704static int siena_mtd_probe_partition(struct efx_nic *efx,
705 struct efx_mcdi_mtd_partition *part,
706 unsigned int type)
707{
708 const struct siena_nvram_type_info *info;
709 size_t size, erase_size;
710 bool protected;
711 int rc;
712
713 if (type >= ARRAY_SIZE(siena_nvram_types) ||
714 siena_nvram_types[type].name == NULL)
715 return -ENODEV;
716
717 info = &siena_nvram_types[type];
718
719 if (info->port != efx_port_num(efx))
720 return -ENODEV;
721
722 rc = efx_mcdi_nvram_info(efx, type, &size, &erase_size, &protected);
723 if (rc)
724 return rc;
725 if (protected)
726 return -ENODEV; /* hide it */
727
728 part->nvram_type = type;
729 part->common.dev_type_name = "Siena NVRAM manager";
730 part->common.type_name = info->name;
731
732 part->common.mtd.type = MTD_NORFLASH;
733 part->common.mtd.flags = MTD_CAP_NORFLASH;
734 part->common.mtd.size = size;
735 part->common.mtd.erasesize = erase_size;
736
737 return 0;
738}
739
740static int siena_mtd_get_fw_subtypes(struct efx_nic *efx,
741 struct efx_mcdi_mtd_partition *parts,
742 size_t n_parts)
743{
744 uint16_t fw_subtype_list[
745 MC_CMD_GET_BOARD_CFG_OUT_FW_SUBTYPE_LIST_MAXNUM];
746 size_t i;
747 int rc;
748
749 rc = efx_mcdi_get_board_cfg(efx, NULL, fw_subtype_list, NULL);
750 if (rc)
751 return rc;
752
753 for (i = 0; i < n_parts; i++)
754 parts[i].fw_subtype = fw_subtype_list[parts[i].nvram_type];
755
756 return 0;
757}
758
759static int siena_mtd_probe(struct efx_nic *efx)
760{
761 struct efx_mcdi_mtd_partition *parts;
762 u32 nvram_types;
763 unsigned int type;
764 size_t n_parts;
765 int rc;
766
767 ASSERT_RTNL();
768
769 rc = efx_mcdi_nvram_types(efx, &nvram_types);
770 if (rc)
771 return rc;
772
773 parts = kcalloc(hweight32(nvram_types), sizeof(*parts), GFP_KERNEL);
774 if (!parts)
775 return -ENOMEM;
776
777 type = 0;
778 n_parts = 0;
779
780 while (nvram_types != 0) {
781 if (nvram_types & 1) {
782 rc = siena_mtd_probe_partition(efx, &parts[n_parts],
783 type);
784 if (rc == 0)
785 n_parts++;
786 else if (rc != -ENODEV)
787 goto fail;
788 }
789 type++;
790 nvram_types >>= 1;
791 }
792
793 rc = siena_mtd_get_fw_subtypes(efx, parts, n_parts);
794 if (rc)
795 goto fail;
796
797 rc = efx_mtd_add(efx, &parts[0].common, n_parts, sizeof(*parts));
798fail:
799 if (rc)
800 kfree(parts);
801 return rc;
802}
803
804#endif /* CONFIG_SFC_MTD */
805
806/**************************************************************************
807 *
677 * Revision-dependent attributes used by efx.c and nic.c 808 * Revision-dependent attributes used by efx.c and nic.c
678 * 809 *
679 ************************************************************************** 810 **************************************************************************
@@ -753,6 +884,14 @@ const struct efx_nic_type siena_a0_nic_type = {
753 .filter_rfs_insert = efx_farch_filter_rfs_insert, 884 .filter_rfs_insert = efx_farch_filter_rfs_insert,
754 .filter_rfs_expire_one = efx_farch_filter_rfs_expire_one, 885 .filter_rfs_expire_one = efx_farch_filter_rfs_expire_one,
755#endif 886#endif
887#ifdef CONFIG_SFC_MTD
888 .mtd_probe = siena_mtd_probe,
889 .mtd_rename = efx_mcdi_mtd_rename,
890 .mtd_read = efx_mcdi_mtd_read,
891 .mtd_erase = efx_mcdi_mtd_erase,
892 .mtd_write = efx_mcdi_mtd_write,
893 .mtd_sync = efx_mcdi_mtd_sync,
894#endif
756 895
757 .revision = EFX_REV_SIENA_A0, 896 .revision = EFX_REV_SIENA_A0,
758 .txd_ptr_tbl_base = FR_BZ_TX_DESC_PTR_TBL, 897 .txd_ptr_tbl_base = FR_BZ_TX_DESC_PTR_TBL,
diff --git a/drivers/net/ethernet/sfc/spi.h b/drivers/net/ethernet/sfc/spi.h
deleted file mode 100644
index ee951feb0100..000000000000
--- a/drivers/net/ethernet/sfc/spi.h
+++ /dev/null
@@ -1,99 +0,0 @@
1/****************************************************************************
2 * Driver for Solarflare Solarstorm network controllers and boards
3 * Copyright 2005 Fen Systems Ltd.
4 * Copyright 2006-2010 Solarflare Communications Inc.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License version 2 as published
8 * by the Free Software Foundation, incorporated herein by reference.
9 */
10
11#ifndef EFX_SPI_H
12#define EFX_SPI_H
13
14#include "net_driver.h"
15
16/**************************************************************************
17 *
18 * Basic SPI command set and bit definitions
19 *
20 *************************************************************************/
21
22#define SPI_WRSR 0x01 /* Write status register */
23#define SPI_WRITE 0x02 /* Write data to memory array */
24#define SPI_READ 0x03 /* Read data from memory array */
25#define SPI_WRDI 0x04 /* Reset write enable latch */
26#define SPI_RDSR 0x05 /* Read status register */
27#define SPI_WREN 0x06 /* Set write enable latch */
28#define SPI_SST_EWSR 0x50 /* SST: Enable write to status register */
29
30#define SPI_STATUS_WPEN 0x80 /* Write-protect pin enabled */
31#define SPI_STATUS_BP2 0x10 /* Block protection bit 2 */
32#define SPI_STATUS_BP1 0x08 /* Block protection bit 1 */
33#define SPI_STATUS_BP0 0x04 /* Block protection bit 0 */
34#define SPI_STATUS_WEN 0x02 /* State of the write enable latch */
35#define SPI_STATUS_NRDY 0x01 /* Device busy flag */
36
37/**
38 * struct falcon_spi_device - a Falcon SPI (Serial Peripheral Interface) device
39 * @device_id: Controller's id for the device
40 * @size: Size (in bytes)
41 * @addr_len: Number of address bytes in read/write commands
42 * @munge_address: Flag whether addresses should be munged.
43 * Some devices with 9-bit addresses (e.g. AT25040A EEPROM)
44 * use bit 3 of the command byte as address bit A8, rather
45 * than having a two-byte address. If this flag is set, then
46 * commands should be munged in this way.
47 * @erase_command: Erase command (or 0 if sector erase not needed).
48 * @erase_size: Erase sector size (in bytes)
49 * Erase commands affect sectors with this size and alignment.
50 * This must be a power of two.
51 * @block_size: Write block size (in bytes).
52 * Write commands are limited to blocks with this size and alignment.
53 */
54struct falcon_spi_device {
55 int device_id;
56 unsigned int size;
57 unsigned int addr_len;
58 unsigned int munge_address:1;
59 u8 erase_command;
60 unsigned int erase_size;
61 unsigned int block_size;
62};
63
64static inline bool falcon_spi_present(const struct falcon_spi_device *spi)
65{
66 return spi->size != 0;
67}
68
69int falcon_spi_cmd(struct efx_nic *efx,
70 const struct falcon_spi_device *spi, unsigned int command,
71 int address, const void *in, void *out, size_t len);
72int falcon_spi_wait_write(struct efx_nic *efx,
73 const struct falcon_spi_device *spi);
74int falcon_spi_read(struct efx_nic *efx,
75 const struct falcon_spi_device *spi, loff_t start,
76 size_t len, size_t *retlen, u8 *buffer);
77int falcon_spi_write(struct efx_nic *efx,
78 const struct falcon_spi_device *spi, loff_t start,
79 size_t len, size_t *retlen, const u8 *buffer);
80
81/*
82 * SFC4000 flash is partitioned into:
83 * 0-0x400 chip and board config (see falcon_hwdefs.h)
84 * 0x400-0x8000 unused (or may contain VPD if EEPROM not present)
85 * 0x8000-end boot code (mapped to PCI expansion ROM)
86 * SFC4000 small EEPROM (size < 0x400) is used for VPD only.
87 * SFC4000 large EEPROM (size >= 0x400) is partitioned into:
88 * 0-0x400 chip and board config
89 * configurable VPD
90 * 0x800-0x1800 boot config
91 * Aside from the chip and board config, all of these are optional and may
92 * be absent or truncated depending on the devices used.
93 */
94#define FALCON_NVCONFIG_END 0x400U
95#define FALCON_FLASH_BOOTCODE_START 0x8000U
96#define FALCON_EEPROM_BOOTCONFIG_START 0x800U
97#define FALCON_EEPROM_BOOTCONFIG_END 0x1800U
98
99#endif /* EFX_SPI_H */