diff options
author | Uwe Kleine-König <u.kleine-koenig@pengutronix.de> | 2017-11-23 12:12:35 +0100 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2017-11-24 10:06:14 +0100 |
commit | 95c346ccaa6da2257f605d18ac7595b99f628419 (patch) | |
tree | 342810b4907e782778b4088ba8f30149c81f002a /drivers/net/e1000/eeprom.c | |
parent | f995e8ad825d0c3689c1ab8209c4b41e001fe9d6 (diff) | |
download | barebox-95c346ccaa6da2257f605d18ac7595b99f628419.tar.gz barebox-95c346ccaa6da2257f605d18ac7595b99f628419.tar.xz |
net/e1000: don't access the (simulated) eeprom when it is invalid
The shadow RAM that is used to serve read requests from the eeprom
interface isn't valid in all cases. Catch these by returning an error in
the eeprom read function and make eeprom validation dependant on
working access.
Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'drivers/net/e1000/eeprom.c')
-rw-r--r-- | drivers/net/e1000/eeprom.c | 36 |
1 files changed, 31 insertions, 5 deletions
diff --git a/drivers/net/e1000/eeprom.c b/drivers/net/e1000/eeprom.c index cb92deee3b..afd129b79f 100644 --- a/drivers/net/e1000/eeprom.c +++ b/drivers/net/e1000/eeprom.c @@ -961,6 +961,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. */ @@ -1413,12 +1416,14 @@ int e1000_register_invm(struct e1000_hw *hw) u16 word; struct param_d *p; - ret = e1000_read_eeprom(hw, 0x0a, 1, &word); - if (ret < 0) - return ret; + 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"); + 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; @@ -1449,6 +1454,27 @@ int e1000_register_invm(struct e1000_hw *hw) 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; + + 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. |