aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/sfc/falcon.c
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/sfc/falcon.c
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/sfc/falcon.c')
-rw-r--r--drivers/net/ethernet/sfc/falcon.c381
1 files changed, 340 insertions, 41 deletions
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,