aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorBruce Allan <bruce.w.allan@intel.com>2008-11-21 20:02:41 -0500
committerDavid S. Miller <davem@davemloft.net>2008-11-21 20:02:41 -0500
commite243455d345ef62751723671bc2605a2f6032ceb (patch)
tree7246784e849ca0471a4bf2bc69a960d6194a6af9 /drivers
parenta20e4cf9e6a37e40532593e00df153d01e317baf (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')
-rw-r--r--drivers/net/e1000e/82571.c5
-rw-r--r--drivers/net/e1000e/defines.h1
-rw-r--r--drivers/net/e1000e/ethtool.c35
-rw-r--r--drivers/net/e1000e/ich8lan.c134
-rw-r--r--drivers/net/e1000e/netdev.c4
5 files changed, 116 insertions, 63 deletions
diff --git a/drivers/net/e1000e/82571.c b/drivers/net/e1000e/82571.c
index 60c15cbbc401..cf43ee743b3c 100644
--- a/drivers/net/e1000e/82571.c
+++ b/drivers/net/e1000e/82571.c
@@ -332,8 +332,9 @@ static s32 e1000_get_variants_82571(struct e1000_adapter *adapter)
332 332
333 case e1000_82573: 333 case e1000_82573:
334 if (pdev->device == E1000_DEV_ID_82573L) { 334 if (pdev->device == E1000_DEV_ID_82573L) {
335 e1000_read_nvm(&adapter->hw, NVM_INIT_3GIO_3, 1, 335 if (e1000_read_nvm(&adapter->hw, NVM_INIT_3GIO_3, 1,
336 &eeprom_data); 336 &eeprom_data) < 0)
337 break;
337 if (eeprom_data & NVM_WORD1A_ASPM_MASK) 338 if (eeprom_data & NVM_WORD1A_ASPM_MASK)
338 adapter->flags &= ~FLAG_HAS_JUMBO_FRAMES; 339 adapter->flags &= ~FLAG_HAS_JUMBO_FRAMES;
339 } 340 }
diff --git a/drivers/net/e1000e/defines.h b/drivers/net/e1000e/defines.h
index 34a68fcab5a9..e6caf29d4252 100644
--- a/drivers/net/e1000e/defines.h
+++ b/drivers/net/e1000e/defines.h
@@ -572,6 +572,7 @@
572#define E1000_EECD_FLUPD 0x00080000 /* Update FLASH */ 572#define E1000_EECD_FLUPD 0x00080000 /* Update FLASH */
573#define E1000_EECD_AUPDEN 0x00100000 /* Enable Autonomous FLASH update */ 573#define E1000_EECD_AUPDEN 0x00100000 /* Enable Autonomous FLASH update */
574#define E1000_EECD_SEC1VAL 0x00400000 /* Sector One Valid */ 574#define E1000_EECD_SEC1VAL 0x00400000 /* Sector One Valid */
575#define E1000_EECD_SEC1VAL_VALID_MASK (E1000_EECD_AUTO_RD | E1000_EECD_PRES)
575 576
576#define E1000_NVM_RW_REG_DATA 16 /* Offset to data in NVM read/write registers */ 577#define E1000_NVM_RW_REG_DATA 16 /* Offset to data in NVM read/write registers */
577#define E1000_NVM_RW_REG_DONE 2 /* Offset to READ/WRITE done bit */ 578#define E1000_NVM_RW_REG_DONE 2 /* Offset to READ/WRITE done bit */
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
585out:
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 }
diff --git a/drivers/net/e1000e/ich8lan.c b/drivers/net/e1000e/ich8lan.c
index 33898ead9276..92f2ace7ca68 100644
--- a/drivers/net/e1000e/ich8lan.c
+++ b/drivers/net/e1000e/ich8lan.c
@@ -94,6 +94,8 @@
94 94
95#define E1000_ICH_NVM_SIG_WORD 0x13 95#define E1000_ICH_NVM_SIG_WORD 0x13
96#define E1000_ICH_NVM_SIG_MASK 0xC000 96#define E1000_ICH_NVM_SIG_MASK 0xC000
97#define E1000_ICH_NVM_VALID_SIG_MASK 0xC0
98#define E1000_ICH_NVM_SIG_VALUE 0x80
97 99
98#define E1000_ICH8_LAN_INIT_TIMEOUT 1500 100#define E1000_ICH8_LAN_INIT_TIMEOUT 1500
99 101
@@ -958,45 +960,62 @@ static s32 e1000_set_d3_lplu_state_ich8lan(struct e1000_hw *hw, bool active)
958 * @bank: pointer to the variable that returns the active bank 960 * @bank: pointer to the variable that returns the active bank
959 * 961 *
960 * Reads signature byte from the NVM using the flash access registers. 962 * Reads signature byte from the NVM using the flash access registers.
963 * Word 0x13 bits 15:14 = 10b indicate a valid signature for that bank.
961 **/ 964 **/
962static s32 e1000_valid_nvm_bank_detect_ich8lan(struct e1000_hw *hw, u32 *bank) 965static s32 e1000_valid_nvm_bank_detect_ich8lan(struct e1000_hw *hw, u32 *bank)
963{ 966{
967 u32 eecd;
964 struct e1000_nvm_info *nvm = &hw->nvm; 968 struct e1000_nvm_info *nvm = &hw->nvm;
965 /* flash bank size is in words */
966 u32 bank1_offset = nvm->flash_bank_size * sizeof(u16); 969 u32 bank1_offset = nvm->flash_bank_size * sizeof(u16);
967 u32 act_offset = E1000_ICH_NVM_SIG_WORD * 2 + 1; 970 u32 act_offset = E1000_ICH_NVM_SIG_WORD * 2 + 1;
968 u8 bank_high_byte = 0; 971 u8 sig_byte = 0;
972 s32 ret_val = 0;
969 973
970 if (hw->mac.type != e1000_ich10lan) { 974 switch (hw->mac.type) {
971 if (er32(EECD) & E1000_EECD_SEC1VAL) 975 case e1000_ich8lan:
972 *bank = 1; 976 case e1000_ich9lan:
973 else 977 eecd = er32(EECD);
974 *bank = 0; 978 if ((eecd & E1000_EECD_SEC1VAL_VALID_MASK) ==
975 } else { 979 E1000_EECD_SEC1VAL_VALID_MASK) {
976 /* 980 if (eecd & E1000_EECD_SEC1VAL)
977 * Make sure the signature for bank 0 is valid, 981 *bank = 1;
978 * if not check for bank1 982 else
979 */ 983 *bank = 0;
980 e1000_read_flash_byte_ich8lan(hw, act_offset, &bank_high_byte); 984
981 if ((bank_high_byte & 0xC0) == 0x80) { 985 return 0;
986 }
987 hw_dbg(hw, "Unable to determine valid NVM bank via EEC - "
988 "reading flash signature\n");
989 /* fall-thru */
990 default:
991 /* set bank to 0 in case flash read fails */
992 *bank = 0;
993
994 /* Check bank 0 */
995 ret_val = e1000_read_flash_byte_ich8lan(hw, act_offset,
996 &sig_byte);
997 if (ret_val)
998 return ret_val;
999 if ((sig_byte & E1000_ICH_NVM_VALID_SIG_MASK) ==
1000 E1000_ICH_NVM_SIG_VALUE) {
982 *bank = 0; 1001 *bank = 0;
983 } else { 1002 return 0;
984 /* 1003 }
985 * find if segment 1 is valid by verifying
986 * bit 15:14 = 10b in word 0x13
987 */
988 e1000_read_flash_byte_ich8lan(hw,
989 act_offset + bank1_offset,
990 &bank_high_byte);
991 1004
992 /* bank1 has a valid signature equivalent to SEC1V */ 1005 /* Check bank 1 */
993 if ((bank_high_byte & 0xC0) == 0x80) { 1006 ret_val = e1000_read_flash_byte_ich8lan(hw, act_offset +
994 *bank = 1; 1007 bank1_offset,
995 } else { 1008 &sig_byte);
996 hw_dbg(hw, "ERROR: EEPROM not present\n"); 1009 if (ret_val)
997 return -E1000_ERR_NVM; 1010 return ret_val;
998 } 1011 if ((sig_byte & E1000_ICH_NVM_VALID_SIG_MASK) ==
1012 E1000_ICH_NVM_SIG_VALUE) {
1013 *bank = 1;
1014 return 0;
999 } 1015 }
1016
1017 hw_dbg(hw, "ERROR: No valid NVM bank present\n");
1018 return -E1000_ERR_NVM;
1000 } 1019 }
1001 1020
1002 return 0; 1021 return 0;
@@ -1029,11 +1048,11 @@ static s32 e1000_read_nvm_ich8lan(struct e1000_hw *hw, u16 offset, u16 words,
1029 1048
1030 ret_val = e1000_acquire_swflag_ich8lan(hw); 1049 ret_val = e1000_acquire_swflag_ich8lan(hw);
1031 if (ret_val) 1050 if (ret_val)
1032 return ret_val; 1051 goto out;
1033 1052
1034 ret_val = e1000_valid_nvm_bank_detect_ich8lan(hw, &bank); 1053 ret_val = e1000_valid_nvm_bank_detect_ich8lan(hw, &bank);
1035 if (ret_val) 1054 if (ret_val)
1036 return ret_val; 1055 goto release;
1037 1056
1038 act_offset = (bank) ? nvm->flash_bank_size : 0; 1057 act_offset = (bank) ? nvm->flash_bank_size : 0;
1039 act_offset += offset; 1058 act_offset += offset;
@@ -1052,8 +1071,13 @@ static s32 e1000_read_nvm_ich8lan(struct e1000_hw *hw, u16 offset, u16 words,
1052 } 1071 }
1053 } 1072 }
1054 1073
1074release:
1055 e1000_release_swflag_ich8lan(hw); 1075 e1000_release_swflag_ich8lan(hw);
1056 1076
1077out:
1078 if (ret_val)
1079 hw_dbg(hw, "NVM read error: %d\n", ret_val);
1080
1057 return ret_val; 1081 return ret_val;
1058} 1082}
1059 1083
@@ -1342,14 +1366,14 @@ static s32 e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw)
1342 1366
1343 ret_val = e1000e_update_nvm_checksum_generic(hw); 1367 ret_val = e1000e_update_nvm_checksum_generic(hw);
1344 if (ret_val) 1368 if (ret_val)
1345 return ret_val; 1369 goto out;
1346 1370
1347 if (nvm->type != e1000_nvm_flash_sw) 1371 if (nvm->type != e1000_nvm_flash_sw)
1348 return ret_val; 1372 goto out;
1349 1373
1350 ret_val = e1000_acquire_swflag_ich8lan(hw); 1374 ret_val = e1000_acquire_swflag_ich8lan(hw);
1351 if (ret_val) 1375 if (ret_val)
1352 return ret_val; 1376 goto out;
1353 1377
1354 /* 1378 /*
1355 * We're writing to the opposite bank so if we're on bank 1, 1379 * We're writing to the opposite bank so if we're on bank 1,
@@ -1357,17 +1381,27 @@ static s32 e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw)
1357 * is going to be written 1381 * is going to be written
1358 */ 1382 */
1359 ret_val = e1000_valid_nvm_bank_detect_ich8lan(hw, &bank); 1383 ret_val = e1000_valid_nvm_bank_detect_ich8lan(hw, &bank);
1360 if (ret_val) 1384 if (ret_val) {
1361 return ret_val; 1385 e1000_release_swflag_ich8lan(hw);
1386 goto out;
1387 }
1362 1388
1363 if (bank == 0) { 1389 if (bank == 0) {
1364 new_bank_offset = nvm->flash_bank_size; 1390 new_bank_offset = nvm->flash_bank_size;
1365 old_bank_offset = 0; 1391 old_bank_offset = 0;
1366 e1000_erase_flash_bank_ich8lan(hw, 1); 1392 ret_val = e1000_erase_flash_bank_ich8lan(hw, 1);
1393 if (ret_val) {
1394 e1000_release_swflag_ich8lan(hw);
1395 goto out;
1396 }
1367 } else { 1397 } else {
1368 old_bank_offset = nvm->flash_bank_size; 1398 old_bank_offset = nvm->flash_bank_size;
1369 new_bank_offset = 0; 1399 new_bank_offset = 0;
1370 e1000_erase_flash_bank_ich8lan(hw, 0); 1400 ret_val = e1000_erase_flash_bank_ich8lan(hw, 0);
1401 if (ret_val) {
1402 e1000_release_swflag_ich8lan(hw);
1403 goto out;
1404 }
1371 } 1405 }
1372 1406
1373 for (i = 0; i < E1000_ICH8_SHADOW_RAM_WORDS; i++) { 1407 for (i = 0; i < E1000_ICH8_SHADOW_RAM_WORDS; i++) {
@@ -1379,9 +1413,11 @@ static s32 e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw)
1379 if (dev_spec->shadow_ram[i].modified) { 1413 if (dev_spec->shadow_ram[i].modified) {
1380 data = dev_spec->shadow_ram[i].value; 1414 data = dev_spec->shadow_ram[i].value;
1381 } else { 1415 } else {
1382 e1000_read_flash_word_ich8lan(hw, 1416 ret_val = e1000_read_flash_word_ich8lan(hw, i +
1383 i + old_bank_offset, 1417 old_bank_offset,
1384 &data); 1418 &data);
1419 if (ret_val)
1420 break;
1385 } 1421 }
1386 1422
1387 /* 1423 /*
@@ -1422,7 +1458,7 @@ static s32 e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw)
1422 /* Possibly read-only, see e1000e_write_protect_nvm_ich8lan() */ 1458 /* Possibly read-only, see e1000e_write_protect_nvm_ich8lan() */
1423 hw_dbg(hw, "Flash commit failed.\n"); 1459 hw_dbg(hw, "Flash commit failed.\n");
1424 e1000_release_swflag_ich8lan(hw); 1460 e1000_release_swflag_ich8lan(hw);
1425 return ret_val; 1461 goto out;
1426 } 1462 }
1427 1463
1428 /* 1464 /*
@@ -1432,14 +1468,18 @@ static s32 e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw)
1432 * and we need to change bit 14 to 0b 1468 * and we need to change bit 14 to 0b
1433 */ 1469 */
1434 act_offset = new_bank_offset + E1000_ICH_NVM_SIG_WORD; 1470 act_offset = new_bank_offset + E1000_ICH_NVM_SIG_WORD;
1435 e1000_read_flash_word_ich8lan(hw, act_offset, &data); 1471 ret_val = e1000_read_flash_word_ich8lan(hw, act_offset, &data);
1472 if (ret_val) {
1473 e1000_release_swflag_ich8lan(hw);
1474 goto out;
1475 }
1436 data &= 0xBFFF; 1476 data &= 0xBFFF;
1437 ret_val = e1000_retry_write_flash_byte_ich8lan(hw, 1477 ret_val = e1000_retry_write_flash_byte_ich8lan(hw,
1438 act_offset * 2 + 1, 1478 act_offset * 2 + 1,
1439 (u8)(data >> 8)); 1479 (u8)(data >> 8));
1440 if (ret_val) { 1480 if (ret_val) {
1441 e1000_release_swflag_ich8lan(hw); 1481 e1000_release_swflag_ich8lan(hw);
1442 return ret_val; 1482 goto out;
1443 } 1483 }
1444 1484
1445 /* 1485 /*
@@ -1452,7 +1492,7 @@ static s32 e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw)
1452 ret_val = e1000_retry_write_flash_byte_ich8lan(hw, act_offset, 0); 1492 ret_val = e1000_retry_write_flash_byte_ich8lan(hw, act_offset, 0);
1453 if (ret_val) { 1493 if (ret_val) {
1454 e1000_release_swflag_ich8lan(hw); 1494 e1000_release_swflag_ich8lan(hw);
1455 return ret_val; 1495 goto out;
1456 } 1496 }
1457 1497
1458 /* Great! Everything worked, we can now clear the cached entries. */ 1498 /* Great! Everything worked, we can now clear the cached entries. */
@@ -1470,6 +1510,10 @@ static s32 e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw)
1470 e1000e_reload_nvm(hw); 1510 e1000e_reload_nvm(hw);
1471 msleep(10); 1511 msleep(10);
1472 1512
1513out:
1514 if (ret_val)
1515 hw_dbg(hw, "NVM update error: %d\n", ret_val);
1516
1473 return ret_val; 1517 return ret_val;
1474} 1518}
1475 1519
diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c
index b1b534d267ed..ca5d3f58329d 100644
--- a/drivers/net/e1000e/netdev.c
+++ b/drivers/net/e1000e/netdev.c
@@ -4723,14 +4723,14 @@ static void e1000_eeprom_checks(struct e1000_adapter *adapter)
4723 return; 4723 return;
4724 4724
4725 ret_val = e1000_read_nvm(hw, NVM_INIT_CONTROL2_REG, 1, &buf); 4725 ret_val = e1000_read_nvm(hw, NVM_INIT_CONTROL2_REG, 1, &buf);
4726 if (!(le16_to_cpu(buf) & (1 << 0))) { 4726 if (!ret_val && (!(le16_to_cpu(buf) & (1 << 0)))) {
4727 /* Deep Smart Power Down (DSPD) */ 4727 /* Deep Smart Power Down (DSPD) */
4728 dev_warn(&adapter->pdev->dev, 4728 dev_warn(&adapter->pdev->dev,
4729 "Warning: detected DSPD enabled in EEPROM\n"); 4729 "Warning: detected DSPD enabled in EEPROM\n");
4730 } 4730 }
4731 4731
4732 ret_val = e1000_read_nvm(hw, NVM_INIT_3GIO_3, 1, &buf); 4732 ret_val = e1000_read_nvm(hw, NVM_INIT_3GIO_3, 1, &buf);
4733 if (le16_to_cpu(buf) & (3 << 2)) { 4733 if (!ret_val && (le16_to_cpu(buf) & (3 << 2))) {
4734 /* ASPM enable */ 4734 /* ASPM enable */
4735 dev_warn(&adapter->pdev->dev, 4735 dev_warn(&adapter->pdev->dev,
4736 "Warning: detected ASPM enabled in EEPROM\n"); 4736 "Warning: detected ASPM enabled in EEPROM\n");