aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/e1000e/ich8lan.c
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/net/e1000e/ich8lan.c
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/net/e1000e/ich8lan.c')
-rw-r--r--drivers/net/e1000e/ich8lan.c134
1 files changed, 89 insertions, 45 deletions
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