diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/i2c/busses/i2c-mv64xxx.c | 20 | ||||
-rw-r--r-- | drivers/net/e1000/e1000.h | 14 | ||||
-rw-r--r-- | drivers/net/e1000/eeprom.c | 446 | ||||
-rw-r--r-- | drivers/net/e1000/main.c | 10 | ||||
-rw-r--r-- | drivers/usb/gadget/Kconfig | 1 |
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 |