summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/i2c/busses/i2c-mv64xxx.c20
-rw-r--r--drivers/net/e1000/e1000.h14
-rw-r--r--drivers/net/e1000/eeprom.c446
-rw-r--r--drivers/net/e1000/main.c10
-rw-r--r--drivers/usb/gadget/Kconfig1
5 files changed, 340 insertions, 151 deletions
diff --git a/drivers/i2c/busses/i2c-mv64xxx.c b/drivers/i2c/busses/i2c-mv64xxx.c
index fd1665bebb..f54d81608f 100644
--- a/drivers/i2c/busses/i2c-mv64xxx.c
+++ b/drivers/i2c/busses/i2c-mv64xxx.c
@@ -37,6 +37,8 @@
#define REG_CONTROL_TWSIEN 0x00000040
#define REG_CONTROL_INTEN 0x00000080
+#define MV46XXX_I2C_TIMEOUT (100 * MSECOND) /* transfer timeout */
+
/* Ctlr status values */
#define STATUS_MAST_START 0x08
#define STATUS_MAST_REPEAT_START 0x10
@@ -421,10 +423,11 @@ mv64xxx_i2c_do_action(struct mv64xxx_i2c_data *drv_data)
*
*****************************************************************************
*/
-static void
+static int
mv64xxx_i2c_wait_for_completion(struct mv64xxx_i2c_data *drv_data)
{
u32 status;
+ uint64_t start = get_time_ns();
do {
if (mv64xxx_read(drv_data, drv_data->reg_offsets.control) &
REG_CONTROL_IFLG) {
@@ -432,6 +435,11 @@ mv64xxx_i2c_wait_for_completion(struct mv64xxx_i2c_data *drv_data)
drv_data->reg_offsets.status);
mv64xxx_i2c_fsm(drv_data, status);
mv64xxx_i2c_do_action(drv_data);
+ } else {
+ if (is_timeout(start, MV46XXX_I2C_TIMEOUT)) {
+ dev_warn(&drv_data->adapter.dev, "timeout waiting for bus ready\n");
+ return -ETIMEDOUT;
+ }
}
if (drv_data->rc) {
drv_data->state = STATE_IDLE;
@@ -440,6 +448,8 @@ mv64xxx_i2c_wait_for_completion(struct mv64xxx_i2c_data *drv_data)
drv_data->block = false;
}
} while (drv_data->block);
+
+ return 0;
}
/*
@@ -453,7 +463,7 @@ static int
mv64xxx_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
{
struct mv64xxx_i2c_data *drv_data = container_of(adap, struct mv64xxx_i2c_data, adapter);
- int ret = num;
+ int ret;
BUG_ON(drv_data->msgs != NULL);
@@ -463,15 +473,15 @@ mv64xxx_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
drv_data->send_stop = (num == 1);
drv_data->block = true;
mv64xxx_i2c_send_start(drv_data);
- mv64xxx_i2c_wait_for_completion(drv_data);
+ ret = mv64xxx_i2c_wait_for_completion(drv_data);
- if (drv_data->rc < 0)
+ if (!ret && drv_data->rc < 0)
ret = drv_data->rc;
drv_data->num_msgs = 0;
drv_data->msgs = NULL;
- return ret;
+ return (ret < 0) ? ret : num;
}
/*
diff --git a/drivers/net/e1000/e1000.h b/drivers/net/e1000/e1000.h
index f2da08b4d5..1558b3c7f5 100644
--- a/drivers/net/e1000/e1000.h
+++ b/drivers/net/e1000/e1000.h
@@ -65,13 +65,9 @@ typedef enum {
} e1000_media_type;
typedef enum {
- e1000_eeprom_uninitialized = 0,
e1000_eeprom_spi,
e1000_eeprom_microwire,
- e1000_eeprom_flash,
- e1000_eeprom_ich8,
- e1000_eeprom_none, /* No NVM support */
- e1000_eeprom_invm,
+ e1000_eeprom_flash, /* access via EERD */
e1000_num_eeprom_types
} e1000_eeprom_type;
@@ -798,6 +794,8 @@ struct e1000_eeprom_info {
#ifndef E1000_EEPROM_GRANT_ATTEMPTS
#define E1000_EEPROM_GRANT_ATTEMPTS 1000 /* EEPROM # attempts to gain grant */
#endif
+#define E1000_EECD_FLASH_IN_USE 0x00000100 /* Flash is present with a valid signature */
+#define E1000_EECD_EE_PRES 0x00000100
#define E1000_EECD_AUTO_RD 0x00000200 /* EEPROM Auto Read done */
#define E1000_EECD_SIZE_EX_MASK 0x00007800 /* EEprom Size */
#define E1000_EECD_SIZE_EX_SHIFT 11
@@ -2103,6 +2101,7 @@ struct e1000_eeprom_info {
after IMS clear */
#define E1000_FLA 0x1201C
+#define E1000_FLA_LOCKED (1 << 6)
#define E1000_FLA_FL_SIZE_SHIFT 17
#define E1000_FLA_FL_SIZE_MASK (0b111 << E1000_FLA_FL_SIZE_SHIFT) /* EEprom Size */
@@ -2112,6 +2111,8 @@ struct e1000_eeprom_info {
#define E1000_FLSWCTL_CMD_WRITE 0b0001
#define E1000_FLSWCTL_CMD_ERASE_SECTOR 0b0010
#define E1000_FLSWCTL_CMD_ERASE_DEVICE 0b0011
+#define E1000_FLSWCTL_CMD_RDSR 0b0100
+#define E1000_FLSWCTL_CMD_WRSR 0b0101
#define E1000_FLSWCTL_CMD(c) ((0b1111 & (c)) << 24)
#define E1000_FLSWCTL_CMD_ADDR_MASK 0x0FFFFFFF
@@ -2165,6 +2166,8 @@ struct e1000_hw {
int line;
} invm;
+ struct cdev eepromcdev;
+
struct mtd_info mtd;
uint32_t phy_id;
@@ -2197,6 +2200,7 @@ void e1000_write_reg_array(struct e1000_hw *hw, uint32_t base,
void e1000_write_flush(struct e1000_hw *hw);
int32_t e1000_init_eeprom_params(struct e1000_hw *hw);
+int e1000_eeprom_valid(struct e1000_hw *hw);
int e1000_validate_eeprom_checksum(struct e1000_hw *hw);
int32_t e1000_read_eeprom(struct e1000_hw *hw, uint16_t offset,
uint16_t words,
diff --git a/drivers/net/e1000/eeprom.c b/drivers/net/e1000/eeprom.c
index 2a71fb1b15..23fb05ec72 100644
--- a/drivers/net/e1000/eeprom.c
+++ b/drivers/net/e1000/eeprom.c
@@ -3,21 +3,18 @@
#include <malloc.h>
#include <linux/math64.h>
#include <linux/sizes.h>
+#include <linux/mtd/spi-nor.h>
#include "e1000.h"
-static void e1000_release_eeprom_spi(struct e1000_hw *hw);
static int32_t e1000_read_eeprom_spi(struct e1000_hw *hw, uint16_t offset,
uint16_t words, uint16_t *data);
-static void e1000_release_eeprom_microwire(struct e1000_hw *hw);
static int32_t e1000_read_eeprom_microwire(struct e1000_hw *hw, uint16_t offset,
uint16_t words, uint16_t *data);
static int32_t e1000_read_eeprom_eerd(struct e1000_hw *hw, uint16_t offset,
uint16_t words, uint16_t *data);
static int32_t e1000_spi_eeprom_ready(struct e1000_hw *hw);
-static void e1000_release_eeprom(struct e1000_hw *hw);
-static int32_t e1000_acquire_eeprom_flash(struct e1000_hw *hw);
static void e1000_release_eeprom_flash(struct e1000_hw *hw);
@@ -252,6 +249,19 @@ e1000_acquire_eeprom_spi_microwire_prologue(struct e1000_hw *hw)
return E1000_SUCCESS;
}
+static void
+e1000_release_eeprom_spi_microwire_epilogue(struct e1000_hw *hw)
+{
+ uint32_t eecd = e1000_read_reg(hw, E1000_EECD);
+
+ /* Stop requesting EEPROM access */
+ if (hw->mac_type > e1000_82544) {
+ eecd &= ~E1000_EECD_REQ;
+ e1000_write_reg(hw, E1000_EECD, eecd);
+ }
+}
+
+
static int32_t e1000_acquire_eeprom_spi(struct e1000_hw *hw)
{
int32_t ret;
@@ -271,6 +281,19 @@ static int32_t e1000_acquire_eeprom_spi(struct e1000_hw *hw)
return E1000_SUCCESS;
}
+static void e1000_release_eeprom_spi(struct e1000_hw *hw)
+{
+ uint32_t eecd = e1000_read_reg(hw, E1000_EECD);
+
+ eecd |= E1000_EECD_CS; /* Pull CS high */
+ eecd &= ~E1000_EECD_SK; /* Lower SCK */
+
+ e1000_write_reg(hw, E1000_EECD, eecd);
+ udelay(hw->eeprom.delay_usec);
+
+ e1000_release_eeprom_spi_microwire_epilogue(hw);
+}
+
static int32_t e1000_acquire_eeprom_microwire(struct e1000_hw *hw)
{
int ret;
@@ -292,11 +315,46 @@ static int32_t e1000_acquire_eeprom_microwire(struct e1000_hw *hw)
return E1000_SUCCESS;
}
+static void e1000_release_eeprom_microwire(struct e1000_hw *hw)
+{
+ uint32_t eecd = e1000_read_reg(hw, E1000_EECD);
+
+ /* cleanup eeprom */
+
+ /* CS on Microwire is active-high */
+ eecd &= ~(E1000_EECD_CS | E1000_EECD_DI);
+
+ e1000_write_reg(hw, E1000_EECD, eecd);
+
+ /* Rising edge of clock */
+ eecd |= E1000_EECD_SK;
+ e1000_write_reg(hw, E1000_EECD, eecd);
+ e1000_write_flush(hw);
+ udelay(hw->eeprom.delay_usec);
+
+ /* Falling edge of clock */
+ eecd &= ~E1000_EECD_SK;
+ e1000_write_reg(hw, E1000_EECD, eecd);
+ e1000_write_flush(hw);
+ udelay(hw->eeprom.delay_usec);
+
+
+ e1000_release_eeprom_spi_microwire_epilogue(hw);
+}
+
static int32_t e1000_acquire_eeprom_flash(struct e1000_hw *hw)
{
return e1000_swfw_sync_acquire(hw, E1000_SWFW_EEP_SM);
}
+static void e1000_release_eeprom_flash(struct e1000_hw *hw)
+{
+ if (e1000_swfw_sync_release(hw, E1000_SWFW_EEP_SM) < 0)
+ dev_warn(hw->dev,
+ "Timeout while releasing SWFW_SYNC bits (0x%08x)\n",
+ E1000_SWFW_EEP_SM);
+}
+
static int32_t e1000_acquire_eeprom(struct e1000_hw *hw)
{
if (hw->eeprom.acquire)
@@ -305,6 +363,12 @@ static int32_t e1000_acquire_eeprom(struct e1000_hw *hw)
return E1000_SUCCESS;
}
+static void e1000_release_eeprom(struct e1000_hw *hw)
+{
+ if (hw->eeprom.release)
+ hw->eeprom.release(hw);
+}
+
static void e1000_eeprom_uses_spi(struct e1000_eeprom_info *eeprom,
uint32_t eecd)
{
@@ -366,7 +430,8 @@ int32_t e1000_init_eeprom_params(struct e1000_hw *hw)
case e1000_82543:
case e1000_82544:
e1000_eeprom_uses_microwire(eeprom, 0);
- break;
+ break;
+
case e1000_82540:
case e1000_82545:
case e1000_82545_rev_3:
@@ -374,6 +439,7 @@ int32_t e1000_init_eeprom_params(struct e1000_hw *hw)
case e1000_82546_rev_3:
e1000_eeprom_uses_microwire(eeprom, eecd);
break;
+
case e1000_82541:
case e1000_82541_rev_2:
case e1000_82547:
@@ -383,10 +449,12 @@ int32_t e1000_init_eeprom_params(struct e1000_hw *hw)
else
e1000_eeprom_uses_microwire(eeprom, eecd);
break;
+
case e1000_82571:
case e1000_82572:
e1000_eeprom_uses_spi(eeprom, eecd);
break;
+
case e1000_82573:
case e1000_82574:
if (e1000_is_onboard_nvm_eeprom(hw)) {
@@ -396,16 +464,20 @@ int32_t e1000_init_eeprom_params(struct e1000_hw *hw)
eeprom->type = e1000_eeprom_flash;
eeprom->word_size = 2048;
- /* Ensure that the Autonomous FLASH update bit is cleared due to
- * Flash update issue on parts which use a FLASH for NVM. */
+ /*
+ * Ensure that the Autonomous FLASH update bit is cleared due to
+ * Flash update issue on parts which use a FLASH for NVM.
+ */
eecd &= ~E1000_EECD_AUPDEN;
e1000_write_reg(hw, E1000_EECD, eecd);
}
break;
+
case e1000_80003es2lan:
eeprom->type = e1000_eeprom_spi;
eeprom->read = e1000_read_eeprom_eerd;
break;
+
case e1000_igb:
if (eecd & E1000_EECD_I210_FLASH_DETECTED) {
uint32_t fla;
@@ -422,21 +494,19 @@ int32_t e1000_init_eeprom_params(struct e1000_hw *hw)
"limiting access to first 4KB\n");
}
- eeprom->type = e1000_eeprom_flash;
eeprom->acquire = e1000_acquire_eeprom_flash;
eeprom->release = e1000_release_eeprom_flash;
- } else {
- eeprom->type = e1000_eeprom_invm;
}
+ eeprom->type = e1000_eeprom_flash;
eeprom->read = e1000_read_eeprom_eerd;
break;
+
default:
break;
}
- if (eeprom->type == e1000_eeprom_spi ||
- eeprom->type == e1000_eeprom_invm) {
+ if (eeprom->type == e1000_eeprom_spi) {
/* eeprom_size will be an enum [0..8] that maps
* to eeprom sizes 128B to
* 32KB (incremented by powers of 2).
@@ -591,72 +661,6 @@ static int32_t e1000_read_eeprom_microwire(struct e1000_hw *hw,
return E1000_SUCCESS;
}
-static void
-e1000_release_eeprom_spi_microwire_epilogue(struct e1000_hw *hw)
-{
- uint32_t eecd = e1000_read_reg(hw, E1000_EECD);
-
- /* Stop requesting EEPROM access */
- if (hw->mac_type > e1000_82544) {
- eecd &= ~E1000_EECD_REQ;
- e1000_write_reg(hw, E1000_EECD, eecd);
- }
-}
-
-static void e1000_release_eeprom_microwire(struct e1000_hw *hw)
-{
- uint32_t eecd = e1000_read_reg(hw, E1000_EECD);
-
- /* cleanup eeprom */
-
- /* CS on Microwire is active-high */
- eecd &= ~(E1000_EECD_CS | E1000_EECD_DI);
-
- e1000_write_reg(hw, E1000_EECD, eecd);
-
- /* Rising edge of clock */
- eecd |= E1000_EECD_SK;
- e1000_write_reg(hw, E1000_EECD, eecd);
- e1000_write_flush(hw);
- udelay(hw->eeprom.delay_usec);
-
- /* Falling edge of clock */
- eecd &= ~E1000_EECD_SK;
- e1000_write_reg(hw, E1000_EECD, eecd);
- e1000_write_flush(hw);
- udelay(hw->eeprom.delay_usec);
-
-
- e1000_release_eeprom_spi_microwire_epilogue(hw);
-}
-
-static void e1000_release_eeprom_spi(struct e1000_hw *hw)
-{
- uint32_t eecd = e1000_read_reg(hw, E1000_EECD);
-
- eecd |= E1000_EECD_CS; /* Pull CS high */
- eecd &= ~E1000_EECD_SK; /* Lower SCK */
-
- e1000_write_reg(hw, E1000_EECD, eecd);
- udelay(hw->eeprom.delay_usec);
-
- e1000_release_eeprom_spi_microwire_epilogue(hw);
-}
-
-static void e1000_release_eeprom_flash(struct e1000_hw *hw)
-{
- if (e1000_swfw_sync_release(hw, E1000_SWFW_EEP_SM) < 0)
- dev_warn(hw->dev,
- "Timeout while releasing SWFW_SYNC bits (0x%08x)\n",
- E1000_SWFW_EEP_SM);
-}
-
-static void e1000_release_eeprom(struct e1000_hw *hw)
-{
- if (hw->eeprom.release)
- hw->eeprom.release(hw);
-}
-
/******************************************************************************
* Reads a 16 bit word from the EEPROM.
*
@@ -705,7 +709,7 @@ static int e1000_flash_mode_wait_for_idle(struct e1000_hw *hw)
E1000_FLSWCTL_DONE, SECOND);
if (ret < 0)
dev_err(hw->dev,
- "Timeout waiting for FLSWCTL.DONE to be set\n");
+ "Timeout waiting for FLSWCTL.DONE to be set (wait)\n");
return ret;
}
@@ -713,7 +717,7 @@ static int e1000_flash_mode_check_command_valid(struct e1000_hw *hw)
{
const uint32_t flswctl = e1000_read_reg(hw, E1000_FLSWCTL);
if (!(flswctl & E1000_FLSWCTL_CMDV)) {
- dev_err(hw->dev, "FLSWCTL.CMDV was cleared");
+ dev_err(hw->dev, "FLSWCTL.CMDV was cleared\n");
return -EIO;
}
@@ -761,7 +765,7 @@ static int e1000_flash_mode_read_chunk(struct e1000_hw *hw, loff_t offset,
SECOND);
if (ret < 0) {
dev_err(hw->dev,
- "Timeout waiting for FLSWCTL.DONE to be set\n");
+ "Timeout waiting for FLSWCTL.DONE to be set (read)\n");
return ret;
}
@@ -817,7 +821,7 @@ static int e1000_flash_mode_write_chunk(struct e1000_hw *hw, loff_t offset,
SECOND);
if (ret < 0) {
dev_err(hw->dev,
- "Timeout waiting for FLSWCTL.DONE to be set\n");
+ "Timeout waiting for FLSWCTL.DONE to be set (write)\n");
return ret;
}
@@ -851,10 +855,10 @@ static int e1000_flash_mode_erase_chunk(struct e1000_hw *hw, loff_t offset,
ret = e1000_poll_reg(hw, E1000_FLSWCTL,
E1000_FLSWCTL_DONE | E1000_FLSWCTL_FLBUSY,
E1000_FLSWCTL_DONE,
- SECOND);
+ 10 * SECOND);
if (ret < 0) {
dev_err(hw->dev,
- "Timeout waiting for FLSWCTL.DONE to be set\n");
+ "Timeout waiting for FLSWCTL.DONE to be set (erase)\n");
return ret;
}
@@ -958,6 +962,9 @@ int32_t e1000_read_eeprom(struct e1000_hw *hw, uint16_t offset,
DEBUGFUNC();
+ if (!e1000_eeprom_valid(hw))
+ return -EINVAL;
+
/* A check for invalid values: offset too large, too many words,
* and not enough words.
*/
@@ -1295,6 +1302,31 @@ static struct file_operations e1000_invm_ops = {
.lseek = dev_lseek_default,
};
+static ssize_t e1000_eeprom_cdev_read(struct cdev *cdev, void *buf,
+ size_t count, loff_t offset, unsigned long flags)
+{
+ struct e1000_hw *hw = container_of(cdev, struct e1000_hw, eepromcdev);
+ int32_t ret;
+
+ /*
+ * The eeprom interface works on 16 bit words which gives a nice excuse
+ * for being lazy and not implementing unaligned reads.
+ */
+ if (offset & 1 || count == 1)
+ return -EIO;
+
+ ret = e1000_read_eeprom(hw, offset / 2, count / 2, buf);
+ if (ret)
+ return -EIO;
+ else
+ return (count / 2) * 2;
+};
+
+static struct file_operations e1000_eeprom_ops = {
+ .read = e1000_eeprom_cdev_read,
+ .lseek = dev_lseek_default,
+};
+
static int e1000_mtd_read_or_write(bool read,
struct mtd_info *mtd, loff_t off, size_t len,
size_t *retlen, u_char *buf)
@@ -1379,75 +1411,217 @@ fail:
return ret;
}
-int e1000_register_eeprom(struct e1000_hw *hw)
+static int e1000_mtd_sr_rmw(struct mtd_info *mtd, u8 mask, u8 val)
{
- int ret = E1000_SUCCESS;
+ struct e1000_hw *hw = container_of(mtd, struct e1000_hw, mtd);
+ uint32_t flswdata;
+ int ret;
+
+ ret = e1000_flash_mode_wait_for_idle(hw);
+ if (ret < 0)
+ return ret;
+
+ e1000_write_reg(hw, E1000_FLSWCNT, 1);
+ e1000_flash_cmd(hw, E1000_FLSWCTL_CMD_RDSR, 0);
+
+ ret = e1000_flash_mode_check_command_valid(hw);
+ if (ret < 0)
+ return -EIO;
+
+ ret = e1000_poll_reg(hw, E1000_FLSWCTL,
+ E1000_FLSWCTL_DONE, E1000_FLSWCTL_DONE,
+ SECOND);
+ if (ret < 0) {
+ dev_err(hw->dev,
+ "Timeout waiting for FLSWCTL.DONE to be set (RDSR)\n");
+ return ret;
+ }
+
+ flswdata = e1000_read_reg(hw, E1000_FLSWDATA);
+
+ flswdata = (flswdata & ~mask) | val;
+
+ e1000_write_reg(hw, E1000_FLSWCNT, 1);
+ e1000_flash_cmd(hw, E1000_FLSWCTL_CMD_WRSR, 0);
+
+ ret = e1000_flash_mode_check_command_valid(hw);
+ if (ret < 0)
+ return -EIO;
+
+ e1000_write_reg(hw, E1000_FLSWDATA, flswdata);
+
+ ret = e1000_poll_reg(hw, E1000_FLSWCTL,
+ E1000_FLSWCTL_DONE, E1000_FLSWCTL_DONE,
+ SECOND);
+ if (ret < 0) {
+ dev_err(hw->dev,
+ "Timeout waiting for FLSWCTL.DONE to be set (WRSR)\n");
+ }
+
+ return ret;
+}
+
+/*
+ * The available spi nor devices are very different in how the block protection
+ * bits affect which sectors to be protected. So take the simple approach and
+ * only use BP[012] = b000 (unprotected) and BP[012] = b111 (protected).
+ */
+#define SR_BPALL (SR_BP0 | SR_BP1 | SR_BP2)
+
+static int e1000_mtd_lock(struct mtd_info *mtd, loff_t ofs, size_t len)
+{
+ return e1000_mtd_sr_rmw(mtd, SR_BPALL, SR_BPALL);
+}
+
+static int e1000_mtd_unlock(struct mtd_info *mtd, loff_t ofs, size_t len)
+{
+ return e1000_mtd_sr_rmw(mtd, SR_BPALL, 0x0);
+}
+
+int e1000_register_invm(struct e1000_hw *hw)
+{
+ int ret;
u16 word;
struct param_d *p;
- struct e1000_eeprom_info *eeprom = &hw->eeprom;
-
- switch (eeprom->type) {
- case e1000_eeprom_invm:
- ret = e1000_read_eeprom(hw, 0x0A, 1, &word);
+ if (e1000_eeprom_valid(hw)) {
+ ret = e1000_read_eeprom(hw, 0x0a, 1, &word);
if (ret < 0)
return ret;
if (word & (1 << 15))
dev_warn(hw->dev, "iNVM lockout mechanism is active\n");
+ }
+
+ hw->invm.cdev.dev = hw->dev;
+ hw->invm.cdev.ops = &e1000_invm_ops;
+ hw->invm.cdev.priv = hw;
+ hw->invm.cdev.name = xasprintf("e1000-invm%d", hw->dev->id);
+ hw->invm.cdev.size = 4 * (E1000_INVM_DATA_MAX_N + 1);
+
+ ret = devfs_create(&hw->invm.cdev);
+ if (ret < 0)
+ return ret;
+
+ strcpy(hw->invm.dev.name, "invm");
+ hw->invm.dev.parent = hw->dev;
+ ret = register_device(&hw->invm.dev);
+ if (ret < 0) {
+ devfs_remove(&hw->invm.cdev);
+ return ret;
+ }
+
+ p = dev_add_param_int(&hw->invm.dev, "lock", e1000_invm_set_lock,
+ NULL, &hw->invm.line, "%u", hw);
+ if (IS_ERR(p)) {
+ unregister_device(&hw->invm.dev);
+ devfs_remove(&hw->invm.cdev);
+ ret = PTR_ERR(p);
+ }
+
+ return ret;
+}
+
+int e1000_eeprom_valid(struct e1000_hw *hw)
+{
+ uint32_t eecd;
+
+ if (hw->mac_type != e1000_igb)
+ return 1;
+
+ /*
+ * if AUTO_RD or EE_PRES are not set in EECD, the shadow RAM is invalid
+ * (and in practise seems to contain the contents of iNVM).
+ */
+ eecd = e1000_read_reg(hw, E1000_EECD);
+ if (!(eecd & E1000_EECD_AUTO_RD))
+ return 0;
- hw->invm.cdev.dev = hw->dev;
- hw->invm.cdev.ops = &e1000_invm_ops;
- hw->invm.cdev.priv = hw;
- hw->invm.cdev.name = xasprintf("e1000-invm%d", hw->dev->id);
- hw->invm.cdev.size = 32 * E1000_INVM_DATA_MAX_N;
+ if (!(eecd & E1000_EECD_EE_PRES))
+ return 0;
+
+ return 1;
+}
+
+/*
+ * This function has a wrong name for historic reasons, it doesn't add an
+ * eeprom, but the flash (if available) that is used to simulate the eeprom.
+ * Also a device that represents the invm is registered here (if available).
+ */
+int e1000_register_eeprom(struct e1000_hw *hw)
+{
+ int ret = E1000_SUCCESS;
- ret = devfs_create(&hw->invm.cdev);
+ struct e1000_eeprom_info *eeprom = &hw->eeprom;
+
+ if (hw->mac_type == e1000_igb) {
+ uint32_t eecd = e1000_read_reg(hw, E1000_EECD);
+
+ hw->eepromcdev.dev = hw->dev;
+ hw->eepromcdev.ops = &e1000_eeprom_ops;
+ hw->eepromcdev.name = xasprintf("e1000-eeprom%d", hw->dev->id);
+ hw->eepromcdev.size = 0x1000;
+
+ ret = devfs_create(&hw->eepromcdev);
if (ret < 0)
- break;
+ return ret;
- strcpy(hw->invm.dev.name, "invm");
- hw->invm.dev.parent = hw->dev;
- ret = register_device(&hw->invm.dev);
- if (ret < 0) {
- devfs_remove(&hw->invm.cdev);
- break;
+ if (eecd & E1000_EECD_AUTO_RD) {
+ if (eecd & E1000_EECD_EE_PRES) {
+ if (eecd & E1000_EECD_FLASH_IN_USE) {
+ uint32_t fla = e1000_read_reg(hw, E1000_FLA);
+ dev_info(hw->dev,
+ "Hardware programmed from flash (%ssecure)\n",
+ fla & E1000_FLA_LOCKED ? "" : "un");
+ } else {
+ dev_info(hw->dev, "Hardware programmed from iNVM\n");
+ }
+ } else {
+ dev_warn(hw->dev, "Shadow RAM invalid\n");
+ }
+ } else {
+ /*
+ * I never saw this case in practise and I'm unsure how
+ * to handle that. Maybe just wait until the hardware is
+ * up enough that this bit is set?
+ */
+ dev_err(hw->dev, "Flash Auto-Read not done\n");
}
- p = dev_add_param_int(&hw->invm.dev, "lock", e1000_invm_set_lock,
- NULL, &hw->invm.line, "%u", hw);
- if (IS_ERR(p)) {
- unregister_device(&hw->invm.dev);
- devfs_remove(&hw->invm.cdev);
- break;
+ if (eecd & E1000_EECD_I210_FLASH_DETECTED) {
+ hw->mtd.parent = hw->dev;
+ hw->mtd.read = e1000_mtd_read;
+ hw->mtd.write = e1000_mtd_write;
+ hw->mtd.erase = e1000_mtd_erase;
+ hw->mtd.lock = e1000_mtd_lock;
+ hw->mtd.unlock = e1000_mtd_unlock;
+ hw->mtd.size = eeprom->word_size * 2;
+ hw->mtd.writesize = 1;
+ hw->mtd.subpage_sft = 0;
+
+ hw->mtd.eraseregions = xzalloc(sizeof(struct mtd_erase_region_info));
+ hw->mtd.erasesize = SZ_4K;
+ hw->mtd.eraseregions[0].erasesize = SZ_4K;
+ hw->mtd.eraseregions[0].numblocks = hw->mtd.size / SZ_4K;
+ hw->mtd.numeraseregions = 1;
+
+ hw->mtd.flags = MTD_CAP_NORFLASH;
+ hw->mtd.type = MTD_NORFLASH;
+
+ ret = add_mtd_device(&hw->mtd, "e1000-nor",
+ DEVICE_ID_DYNAMIC);
+ if (ret) {
+ devfs_remove(&hw->eepromcdev);
+ return ret;
+ }
}
- break;
- case e1000_eeprom_flash:
- if (hw->mac_type != e1000_igb)
- break;
- hw->mtd.parent = hw->dev;
- hw->mtd.read = e1000_mtd_read;
- hw->mtd.write = e1000_mtd_write;
- hw->mtd.erase = e1000_mtd_erase;
- hw->mtd.size = eeprom->word_size * 2;
- hw->mtd.writesize = 1;
- hw->mtd.subpage_sft = 0;
-
- hw->mtd.eraseregions = xzalloc(sizeof(struct mtd_erase_region_info));
- hw->mtd.erasesize = SZ_4K;
- hw->mtd.eraseregions[0].erasesize = SZ_4K;
- hw->mtd.eraseregions[0].numblocks = hw->mtd.size / SZ_4K;
- hw->mtd.numeraseregions = 1;
-
- hw->mtd.flags = MTD_CAP_NORFLASH;
- hw->mtd.type = MTD_NORFLASH;
-
- ret = add_mtd_device(&hw->mtd, "e1000-nor",
- DEVICE_ID_DYNAMIC);
- break;
- default:
- break;
+ ret = e1000_register_invm(hw);
+ if (ret < 0) {
+ if (eecd & E1000_EECD_I210_FLASH_DETECTED)
+ del_mtd_device(&hw->mtd);
+ devfs_remove(&hw->eepromcdev);
+ }
}
return ret;
diff --git a/drivers/net/e1000/main.c b/drivers/net/e1000/main.c
index 00d18adff1..0139c4a6d7 100644
--- a/drivers/net/e1000/main.c
+++ b/drivers/net/e1000/main.c
@@ -142,8 +142,8 @@ static int32_t e1000_set_phy_mode(struct e1000_hw *hw)
***************************************************************************/
static int32_t e1000_get_software_semaphore(struct e1000_hw *hw)
{
- int32_t timeout = hw->eeprom.word_size + 1;
- uint32_t swsm;
+ int32_t timeout = 2049;
+ uint32_t swsm;
DEBUGFUNC();
@@ -214,7 +214,7 @@ static int32_t e1000_get_hw_eeprom_semaphore(struct e1000_hw *hw)
}
/* Get the FW semaphore. */
- timeout = hw->eeprom.word_size + 1;
+ timeout = 2049;
while (timeout) {
swsm = e1000_read_reg(hw, E1000_SWSM);
swsm |= E1000_SWSM_SWESMBI;
@@ -3597,8 +3597,8 @@ static int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *id)
}
}
- if (e1000_validate_eeprom_checksum(hw))
- return -EINVAL;
+ if (!e1000_eeprom_valid(hw) || e1000_validate_eeprom_checksum(hw))
+ return 0;
e1000_get_ethaddr(edev, edev->ethaddr);
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
index 4292371f09..64347f0d18 100644
--- a/drivers/usb/gadget/Kconfig
+++ b/drivers/usb/gadget/Kconfig
@@ -56,6 +56,7 @@ config USB_GADGET_SERIAL
config USB_GADGET_FASTBOOT
bool
select BANNER
+ select FILE_LIST
prompt "Android Fastboot support"
endif