diff options
author | Bruce Allan <bruce.w.allan@intel.com> | 2008-11-21 20:02:41 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-11-21 20:02:41 -0500 |
commit | e243455d345ef62751723671bc2605a2f6032ceb (patch) | |
tree | 7246784e849ca0471a4bf2bc69a960d6194a6af9 /drivers/net/e1000e/ethtool.c | |
parent | a20e4cf9e6a37e40532593e00df153d01e317baf (diff) |
e1000e: check return code from NVM accesses and fix bank detection
Check return code for all NVM accesses[1] and error out accordingly; log
a debug message for failed accesses.
For ICH8/9, the valid NVM bank detect function was not checking whether the
SEC1VAL (sector 1 valid) bit in the EECD register was itself valid (bits 8
and 9 also have to be set). If invalid, it would have defaulted to the
possibly invalid bank 0. Instead, try to use the valid bank detection
method used by ICH10 which has been cleaned up a bit.
[1] - reads and updates only; not writes because those are only writing to
the Shadow RAM, the update following the write is the only thing actually
writing the modified Shadow RAM contents to the NVM.
Signed-off-by: Bruce Allan <bruce.w.allan@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/e1000e/ethtool.c')
-rw-r--r-- | drivers/net/e1000e/ethtool.c | 35 |
1 files changed, 21 insertions, 14 deletions
diff --git a/drivers/net/e1000e/ethtool.c b/drivers/net/e1000e/ethtool.c index 34f1f639429d..e48956d924b0 100644 --- a/drivers/net/e1000e/ethtool.c +++ b/drivers/net/e1000e/ethtool.c | |||
@@ -492,18 +492,19 @@ static int e1000_get_eeprom(struct net_device *netdev, | |||
492 | for (i = 0; i < last_word - first_word + 1; i++) { | 492 | for (i = 0; i < last_word - first_word + 1; i++) { |
493 | ret_val = e1000_read_nvm(hw, first_word + i, 1, | 493 | ret_val = e1000_read_nvm(hw, first_word + i, 1, |
494 | &eeprom_buff[i]); | 494 | &eeprom_buff[i]); |
495 | if (ret_val) { | 495 | if (ret_val) |
496 | /* a read error occurred, throw away the | ||
497 | * result */ | ||
498 | memset(eeprom_buff, 0xff, sizeof(eeprom_buff)); | ||
499 | break; | 496 | break; |
500 | } | ||
501 | } | 497 | } |
502 | } | 498 | } |
503 | 499 | ||
504 | /* Device's eeprom is always little-endian, word addressable */ | 500 | if (ret_val) { |
505 | for (i = 0; i < last_word - first_word + 1; i++) | 501 | /* a read error occurred, throw away the result */ |
506 | le16_to_cpus(&eeprom_buff[i]); | 502 | memset(eeprom_buff, 0xff, sizeof(eeprom_buff)); |
503 | } else { | ||
504 | /* Device's eeprom is always little-endian, word addressable */ | ||
505 | for (i = 0; i < last_word - first_word + 1; i++) | ||
506 | le16_to_cpus(&eeprom_buff[i]); | ||
507 | } | ||
507 | 508 | ||
508 | memcpy(bytes, (u8 *)eeprom_buff + (eeprom->offset & 1), eeprom->len); | 509 | memcpy(bytes, (u8 *)eeprom_buff + (eeprom->offset & 1), eeprom->len); |
509 | kfree(eeprom_buff); | 510 | kfree(eeprom_buff); |
@@ -555,6 +556,9 @@ static int e1000_set_eeprom(struct net_device *netdev, | |||
555 | ret_val = e1000_read_nvm(hw, last_word, 1, | 556 | ret_val = e1000_read_nvm(hw, last_word, 1, |
556 | &eeprom_buff[last_word - first_word]); | 557 | &eeprom_buff[last_word - first_word]); |
557 | 558 | ||
559 | if (ret_val) | ||
560 | goto out; | ||
561 | |||
558 | /* Device's eeprom is always little-endian, word addressable */ | 562 | /* Device's eeprom is always little-endian, word addressable */ |
559 | for (i = 0; i < last_word - first_word + 1; i++) | 563 | for (i = 0; i < last_word - first_word + 1; i++) |
560 | le16_to_cpus(&eeprom_buff[i]); | 564 | le16_to_cpus(&eeprom_buff[i]); |
@@ -567,15 +571,18 @@ static int e1000_set_eeprom(struct net_device *netdev, | |||
567 | ret_val = e1000_write_nvm(hw, first_word, | 571 | ret_val = e1000_write_nvm(hw, first_word, |
568 | last_word - first_word + 1, eeprom_buff); | 572 | last_word - first_word + 1, eeprom_buff); |
569 | 573 | ||
574 | if (ret_val) | ||
575 | goto out; | ||
576 | |||
570 | /* | 577 | /* |
571 | * Update the checksum over the first part of the EEPROM if needed | 578 | * Update the checksum over the first part of the EEPROM if needed |
572 | * and flush shadow RAM for 82573 controllers | 579 | * and flush shadow RAM for applicable controllers |
573 | */ | 580 | */ |
574 | if ((ret_val == 0) && ((first_word <= NVM_CHECKSUM_REG) || | 581 | if ((first_word <= NVM_CHECKSUM_REG) || |
575 | (hw->mac.type == e1000_82574) || | 582 | (hw->mac.type == e1000_82574) || (hw->mac.type == e1000_82573)) |
576 | (hw->mac.type == e1000_82573))) | 583 | ret_val = e1000e_update_nvm_checksum(hw); |
577 | e1000e_update_nvm_checksum(hw); | ||
578 | 584 | ||
585 | out: | ||
579 | kfree(eeprom_buff); | 586 | kfree(eeprom_buff); |
580 | return ret_val; | 587 | return ret_val; |
581 | } | 588 | } |
@@ -860,7 +867,7 @@ static int e1000_eeprom_test(struct e1000_adapter *adapter, u64 *data) | |||
860 | for (i = 0; i < (NVM_CHECKSUM_REG + 1); i++) { | 867 | for (i = 0; i < (NVM_CHECKSUM_REG + 1); i++) { |
861 | if ((e1000_read_nvm(&adapter->hw, i, 1, &temp)) < 0) { | 868 | if ((e1000_read_nvm(&adapter->hw, i, 1, &temp)) < 0) { |
862 | *data = 1; | 869 | *data = 1; |
863 | break; | 870 | return *data; |
864 | } | 871 | } |
865 | checksum += temp; | 872 | checksum += temp; |
866 | } | 873 | } |