Commit 4a5b504d authored by Ben Hutchings's avatar Ben Hutchings Committed by Jeff Garzik

sfc: Export boot configuration in EEPROM through ethtool

Extend the SPI device setup code to support this.
Signed-off-by: default avatarBen Hutchings <bhutchings@solarflare.com>
Signed-off-by: default avatarJeff Garzik <jgarzik@redhat.com>
parent 4d566063
......@@ -17,6 +17,7 @@
#include "ethtool.h"
#include "falcon.h"
#include "gmii.h"
#include "spi.h"
#include "mac.h"
const char *efx_loopback_mode_names[] = {
......@@ -171,6 +172,11 @@ static struct efx_ethtool_stat efx_ethtool_stats[] = {
/* Number of ethtool statistics */
#define EFX_ETHTOOL_NUM_STATS ARRAY_SIZE(efx_ethtool_stats)
/* EEPROM range with gPXE configuration */
#define EFX_ETHTOOL_EEPROM_MAGIC 0xEFAB
#define EFX_ETHTOOL_EEPROM_MIN 0x100U
#define EFX_ETHTOOL_EEPROM_MAX 0x400U
/**************************************************************************
*
* Ethtool operations
......@@ -532,6 +538,49 @@ static u32 efx_ethtool_get_link(struct net_device *net_dev)
return efx->link_up;
}
static int efx_ethtool_get_eeprom_len(struct net_device *net_dev)
{
struct efx_nic *efx = netdev_priv(net_dev);
struct efx_spi_device *spi = efx->spi_eeprom;
if (!spi)
return 0;
return min(spi->size, EFX_ETHTOOL_EEPROM_MAX) -
min(spi->size, EFX_ETHTOOL_EEPROM_MIN);
}
static int efx_ethtool_get_eeprom(struct net_device *net_dev,
struct ethtool_eeprom *eeprom, u8 *buf)
{
struct efx_nic *efx = netdev_priv(net_dev);
struct efx_spi_device *spi = efx->spi_eeprom;
size_t len;
int rc;
rc = falcon_spi_read(spi, eeprom->offset + EFX_ETHTOOL_EEPROM_MIN,
eeprom->len, &len, buf);
eeprom->magic = EFX_ETHTOOL_EEPROM_MAGIC;
eeprom->len = len;
return rc;
}
static int efx_ethtool_set_eeprom(struct net_device *net_dev,
struct ethtool_eeprom *eeprom, u8 *buf)
{
struct efx_nic *efx = netdev_priv(net_dev);
struct efx_spi_device *spi = efx->spi_eeprom;
size_t len;
int rc;
if (eeprom->magic != EFX_ETHTOOL_EEPROM_MAGIC)
return -EINVAL;
rc = falcon_spi_write(spi, eeprom->offset + EFX_ETHTOOL_EEPROM_MIN,
eeprom->len, &len, buf);
eeprom->len = len;
return rc;
}
static int efx_ethtool_get_coalesce(struct net_device *net_dev,
struct ethtool_coalesce *coalesce)
{
......@@ -653,6 +702,9 @@ struct ethtool_ops efx_ethtool_ops = {
.get_drvinfo = efx_ethtool_get_drvinfo,
.nway_reset = efx_ethtool_nway_reset,
.get_link = efx_ethtool_get_link,
.get_eeprom_len = efx_ethtool_get_eeprom_len,
.get_eeprom = efx_ethtool_get_eeprom,
.set_eeprom = efx_ethtool_set_eeprom,
.get_coalesce = efx_ethtool_get_coalesce,
.set_coalesce = efx_ethtool_set_coalesce,
.get_pauseparam = efx_ethtool_get_pauseparam,
......
This diff is collapsed.
......@@ -92,6 +92,17 @@
/* SPI host data register */
#define EE_SPI_HDATA_REG_KER 0x0120
/* SPI/VPD config register */
#define EE_VPD_CFG_REG_KER 0x0140
#define EE_VPD_EN_LBN 0
#define EE_VPD_EN_WIDTH 1
#define EE_VPD_EN_AD9_MODE_LBN 1
#define EE_VPD_EN_AD9_MODE_WIDTH 1
#define EE_EE_CLOCK_DIV_LBN 112
#define EE_EE_CLOCK_DIV_WIDTH 7
#define EE_SF_CLOCK_DIV_LBN 120
#define EE_SF_CLOCK_DIV_WIDTH 7
/* PCIE CORE ACCESS REG */
#define PCIE_CORE_ADDR_PCIE_DEVICE_CTRL_STAT 0x68
#define PCIE_CORE_ADDR_PCIE_LINK_CTRL_STAT 0x70
......@@ -115,6 +126,9 @@
#define STRAP_PCIE_LBN 0
#define STRAP_PCIE_WIDTH 1
#define BOOTED_USING_NVDEVICE_LBN 3
#define BOOTED_USING_NVDEVICE_WIDTH 1
/* GPIO control register */
#define GPIO_CTL_REG_KER 0x0210
#define GPIO_OUTPUTS_LBN (16)
......@@ -1127,6 +1141,25 @@ struct falcon_nvconfig_board_v2 {
__le16 board_revision;
} __packed;
/* Board configuration v3 extra information */
struct falcon_nvconfig_board_v3 {
__le32 spi_device_type[2];
} __packed;
/* Bit numbers for spi_device_type */
#define SPI_DEV_TYPE_SIZE_LBN 0
#define SPI_DEV_TYPE_SIZE_WIDTH 5
#define SPI_DEV_TYPE_ADDR_LEN_LBN 6
#define SPI_DEV_TYPE_ADDR_LEN_WIDTH 2
#define SPI_DEV_TYPE_ERASE_CMD_LBN 8
#define SPI_DEV_TYPE_ERASE_CMD_WIDTH 8
#define SPI_DEV_TYPE_ERASE_SIZE_LBN 16
#define SPI_DEV_TYPE_ERASE_SIZE_WIDTH 5
#define SPI_DEV_TYPE_BLOCK_SIZE_LBN 24
#define SPI_DEV_TYPE_BLOCK_SIZE_WIDTH 5
#define SPI_DEV_TYPE_FIELD(type, field) \
(((type) >> EFX_LOW_BIT(field)) & EFX_MASK32(field))
#define NVCONFIG_BASE 0x300
#define NVCONFIG_BOARD_MAGIC_NUM 0xFA1C
struct falcon_nvconfig {
......@@ -1144,6 +1177,8 @@ struct falcon_nvconfig {
__le16 board_struct_ver;
__le16 board_checksum;
struct falcon_nvconfig_board_v2 board_v2;
efx_oword_t ee_base_page_reg; /* 0x3B0 */
struct falcon_nvconfig_board_v3 board_v3;
} __packed;
#endif /* EFX_FALCON_HWDEFS_H */
......@@ -638,6 +638,10 @@ union efx_multicast_hash {
* This register is written with the SMP processor ID whenever an
* interrupt is handled. It is used by falcon_test_interrupt()
* to verify that an interrupt has occurred.
* @spi_flash: SPI flash device
* This field will be %NULL if no flash device is present.
* @spi_eeprom: SPI EEPROM device
* This field will be %NULL if no EEPROM device is present.
* @n_rx_nodesc_drop_cnt: RX no descriptor drop count
* @nic_data: Hardware dependant state
* @mac_lock: MAC access lock. Protects @port_enabled, efx_monitor() and
......@@ -709,6 +713,9 @@ struct efx_nic {
struct efx_buffer irq_status;
volatile signed int last_irq_cpu;
struct efx_spi_device *spi_flash;
struct efx_spi_device *spi_eeprom;
unsigned n_rx_nodesc_drop_cnt;
struct falcon_nic_data *nic_data;
......
......@@ -19,53 +19,48 @@
*
*************************************************************************/
/*
* Commands common to all known devices.
*
#define SPI_WRSR 0x01 /* Write status register */
#define SPI_WRITE 0x02 /* Write data to memory array */
#define SPI_READ 0x03 /* Read data from memory array */
#define SPI_WRDI 0x04 /* Reset write enable latch */
#define SPI_RDSR 0x05 /* Read status register */
#define SPI_WREN 0x06 /* Set write enable latch */
#define SPI_STATUS_WPEN 0x80 /* Write-protect pin enabled */
#define SPI_STATUS_BP2 0x10 /* Block protection bit 2 */
#define SPI_STATUS_BP1 0x08 /* Block protection bit 1 */
#define SPI_STATUS_BP0 0x04 /* Block protection bit 0 */
#define SPI_STATUS_WEN 0x02 /* State of the write enable latch */
#define SPI_STATUS_NRDY 0x01 /* Device busy flag */
/**
* struct efx_spi_device - an Efx SPI (Serial Peripheral Interface) device
* @efx: The Efx controller that owns this device
* @device_id: Controller's id for the device
* @size: Size (in bytes)
* @addr_len: Number of address bytes in read/write commands
* @munge_address: Flag whether addresses should be munged.
* Some devices with 9-bit addresses (e.g. AT25040A EEPROM)
* use bit 3 of the command byte as address bit A8, rather
* than having a two-byte address. If this flag is set, then
* commands should be munged in this way.
* @block_size: Write block size (in bytes).
* Write commands are limited to blocks with this size and alignment.
* @read: Read function for the device
* @write: Write function for the device
*/
/* Write status register */
#define SPI_WRSR 0x01
/* Write data to memory array */
#define SPI_WRITE 0x02
/* Read data from memory array */
#define SPI_READ 0x03
/* Reset write enable latch */
#define SPI_WRDI 0x04
/* Read status register */
#define SPI_RDSR 0x05
/* Set write enable latch */
#define SPI_WREN 0x06
/* SST: Enable write to status register */
#define SPI_SST_EWSR 0x50
/*
* Status register bits. Not all bits are supported on all devices.
*
*/
/* Write-protect pin enabled */
#define SPI_STATUS_WPEN 0x80
/* Block protection bit 2 */
#define SPI_STATUS_BP2 0x10
/* Block protection bit 1 */
#define SPI_STATUS_BP1 0x08
/* Block protection bit 0 */
#define SPI_STATUS_BP0 0x04
/* State of the write enable latch */
#define SPI_STATUS_WEN 0x02
/* Device busy flag */
#define SPI_STATUS_NRDY 0x01
struct efx_spi_device {
struct efx_nic *efx;
int device_id;
unsigned int size;
unsigned int addr_len;
unsigned int munge_address:1;
unsigned int block_size;
};
int falcon_spi_read(const struct efx_spi_device *spi, loff_t start,
size_t len, size_t *retlen, u8 *buffer);
int falcon_spi_write(const struct efx_spi_device *spi, loff_t start,
size_t len, size_t *retlen, const u8 *buffer);
#endif /* EFX_SPI_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment