Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 121987
b: refs/heads/master
c: e243455
h: refs/heads/master
i:
  121985: 5a239bd
  121983: 52baa54
v: v3
  • Loading branch information
Bruce Allan authored and David S. Miller committed Nov 22, 2008
1 parent 5c27c5f commit ff06f94
Show file tree
Hide file tree
Showing 6 changed files with 117 additions and 64 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: a20e4cf9e6a37e40532593e00df153d01e317baf
refs/heads/master: e243455d345ef62751723671bc2605a2f6032ceb
5 changes: 3 additions & 2 deletions trunk/drivers/net/e1000e/82571.c
Original file line number Diff line number Diff line change
Expand Up @@ -332,8 +332,9 @@ static s32 e1000_get_variants_82571(struct e1000_adapter *adapter)

case e1000_82573:
if (pdev->device == E1000_DEV_ID_82573L) {
e1000_read_nvm(&adapter->hw, NVM_INIT_3GIO_3, 1,
&eeprom_data);
if (e1000_read_nvm(&adapter->hw, NVM_INIT_3GIO_3, 1,
&eeprom_data) < 0)
break;
if (eeprom_data & NVM_WORD1A_ASPM_MASK)
adapter->flags &= ~FLAG_HAS_JUMBO_FRAMES;
}
Expand Down
1 change: 1 addition & 0 deletions trunk/drivers/net/e1000e/defines.h
Original file line number Diff line number Diff line change
Expand Up @@ -572,6 +572,7 @@
#define E1000_EECD_FLUPD 0x00080000 /* Update FLASH */
#define E1000_EECD_AUPDEN 0x00100000 /* Enable Autonomous FLASH update */
#define E1000_EECD_SEC1VAL 0x00400000 /* Sector One Valid */
#define E1000_EECD_SEC1VAL_VALID_MASK (E1000_EECD_AUTO_RD | E1000_EECD_PRES)

#define E1000_NVM_RW_REG_DATA 16 /* Offset to data in NVM read/write registers */
#define E1000_NVM_RW_REG_DONE 2 /* Offset to READ/WRITE done bit */
Expand Down
35 changes: 21 additions & 14 deletions trunk/drivers/net/e1000e/ethtool.c
Original file line number Diff line number Diff line change
Expand Up @@ -492,18 +492,19 @@ static int e1000_get_eeprom(struct net_device *netdev,
for (i = 0; i < last_word - first_word + 1; i++) {
ret_val = e1000_read_nvm(hw, first_word + i, 1,
&eeprom_buff[i]);
if (ret_val) {
/* a read error occurred, throw away the
* result */
memset(eeprom_buff, 0xff, sizeof(eeprom_buff));
if (ret_val)
break;
}
}
}

/* Device's eeprom is always little-endian, word addressable */
for (i = 0; i < last_word - first_word + 1; i++)
le16_to_cpus(&eeprom_buff[i]);
if (ret_val) {
/* a read error occurred, throw away the result */
memset(eeprom_buff, 0xff, sizeof(eeprom_buff));
} else {
/* Device's eeprom is always little-endian, word addressable */
for (i = 0; i < last_word - first_word + 1; i++)
le16_to_cpus(&eeprom_buff[i]);
}

memcpy(bytes, (u8 *)eeprom_buff + (eeprom->offset & 1), eeprom->len);
kfree(eeprom_buff);
Expand Down Expand Up @@ -555,6 +556,9 @@ static int e1000_set_eeprom(struct net_device *netdev,
ret_val = e1000_read_nvm(hw, last_word, 1,
&eeprom_buff[last_word - first_word]);

if (ret_val)
goto out;

/* Device's eeprom is always little-endian, word addressable */
for (i = 0; i < last_word - first_word + 1; i++)
le16_to_cpus(&eeprom_buff[i]);
Expand All @@ -567,15 +571,18 @@ static int e1000_set_eeprom(struct net_device *netdev,
ret_val = e1000_write_nvm(hw, first_word,
last_word - first_word + 1, eeprom_buff);

if (ret_val)
goto out;

/*
* Update the checksum over the first part of the EEPROM if needed
* and flush shadow RAM for 82573 controllers
* and flush shadow RAM for applicable controllers
*/
if ((ret_val == 0) && ((first_word <= NVM_CHECKSUM_REG) ||
(hw->mac.type == e1000_82574) ||
(hw->mac.type == e1000_82573)))
e1000e_update_nvm_checksum(hw);
if ((first_word <= NVM_CHECKSUM_REG) ||
(hw->mac.type == e1000_82574) || (hw->mac.type == e1000_82573))
ret_val = e1000e_update_nvm_checksum(hw);

out:
kfree(eeprom_buff);
return ret_val;
}
Expand Down Expand Up @@ -860,7 +867,7 @@ static int e1000_eeprom_test(struct e1000_adapter *adapter, u64 *data)
for (i = 0; i < (NVM_CHECKSUM_REG + 1); i++) {
if ((e1000_read_nvm(&adapter->hw, i, 1, &temp)) < 0) {
*data = 1;
break;
return *data;
}
checksum += temp;
}
Expand Down
134 changes: 89 additions & 45 deletions trunk/drivers/net/e1000e/ich8lan.c
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,8 @@

#define E1000_ICH_NVM_SIG_WORD 0x13
#define E1000_ICH_NVM_SIG_MASK 0xC000
#define E1000_ICH_NVM_VALID_SIG_MASK 0xC0
#define E1000_ICH_NVM_SIG_VALUE 0x80

#define E1000_ICH8_LAN_INIT_TIMEOUT 1500

Expand Down Expand Up @@ -958,45 +960,62 @@ static s32 e1000_set_d3_lplu_state_ich8lan(struct e1000_hw *hw, bool active)
* @bank: pointer to the variable that returns the active bank
*
* Reads signature byte from the NVM using the flash access registers.
* Word 0x13 bits 15:14 = 10b indicate a valid signature for that bank.
**/
static s32 e1000_valid_nvm_bank_detect_ich8lan(struct e1000_hw *hw, u32 *bank)
{
u32 eecd;
struct e1000_nvm_info *nvm = &hw->nvm;
/* flash bank size is in words */
u32 bank1_offset = nvm->flash_bank_size * sizeof(u16);
u32 act_offset = E1000_ICH_NVM_SIG_WORD * 2 + 1;
u8 bank_high_byte = 0;
u8 sig_byte = 0;
s32 ret_val = 0;

if (hw->mac.type != e1000_ich10lan) {
if (er32(EECD) & E1000_EECD_SEC1VAL)
*bank = 1;
else
*bank = 0;
} else {
/*
* Make sure the signature for bank 0 is valid,
* if not check for bank1
*/
e1000_read_flash_byte_ich8lan(hw, act_offset, &bank_high_byte);
if ((bank_high_byte & 0xC0) == 0x80) {
switch (hw->mac.type) {
case e1000_ich8lan:
case e1000_ich9lan:
eecd = er32(EECD);
if ((eecd & E1000_EECD_SEC1VAL_VALID_MASK) ==
E1000_EECD_SEC1VAL_VALID_MASK) {
if (eecd & E1000_EECD_SEC1VAL)
*bank = 1;
else
*bank = 0;

return 0;
}
hw_dbg(hw, "Unable to determine valid NVM bank via EEC - "
"reading flash signature\n");
/* fall-thru */
default:
/* set bank to 0 in case flash read fails */
*bank = 0;

/* Check bank 0 */
ret_val = e1000_read_flash_byte_ich8lan(hw, act_offset,
&sig_byte);
if (ret_val)
return ret_val;
if ((sig_byte & E1000_ICH_NVM_VALID_SIG_MASK) ==
E1000_ICH_NVM_SIG_VALUE) {
*bank = 0;
} else {
/*
* find if segment 1 is valid by verifying
* bit 15:14 = 10b in word 0x13
*/
e1000_read_flash_byte_ich8lan(hw,
act_offset + bank1_offset,
&bank_high_byte);
return 0;
}

/* bank1 has a valid signature equivalent to SEC1V */
if ((bank_high_byte & 0xC0) == 0x80) {
*bank = 1;
} else {
hw_dbg(hw, "ERROR: EEPROM not present\n");
return -E1000_ERR_NVM;
}
/* Check bank 1 */
ret_val = e1000_read_flash_byte_ich8lan(hw, act_offset +
bank1_offset,
&sig_byte);
if (ret_val)
return ret_val;
if ((sig_byte & E1000_ICH_NVM_VALID_SIG_MASK) ==
E1000_ICH_NVM_SIG_VALUE) {
*bank = 1;
return 0;
}

hw_dbg(hw, "ERROR: No valid NVM bank present\n");
return -E1000_ERR_NVM;
}

return 0;
Expand Down Expand Up @@ -1029,11 +1048,11 @@ static s32 e1000_read_nvm_ich8lan(struct e1000_hw *hw, u16 offset, u16 words,

ret_val = e1000_acquire_swflag_ich8lan(hw);
if (ret_val)
return ret_val;
goto out;

ret_val = e1000_valid_nvm_bank_detect_ich8lan(hw, &bank);
if (ret_val)
return ret_val;
goto release;

act_offset = (bank) ? nvm->flash_bank_size : 0;
act_offset += offset;
Expand All @@ -1052,8 +1071,13 @@ static s32 e1000_read_nvm_ich8lan(struct e1000_hw *hw, u16 offset, u16 words,
}
}

release:
e1000_release_swflag_ich8lan(hw);

out:
if (ret_val)
hw_dbg(hw, "NVM read error: %d\n", ret_val);

return ret_val;
}

Expand Down Expand Up @@ -1342,32 +1366,42 @@ static s32 e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw)

ret_val = e1000e_update_nvm_checksum_generic(hw);
if (ret_val)
return ret_val;
goto out;

if (nvm->type != e1000_nvm_flash_sw)
return ret_val;
goto out;

ret_val = e1000_acquire_swflag_ich8lan(hw);
if (ret_val)
return ret_val;
goto out;

/*
* We're writing to the opposite bank so if we're on bank 1,
* write to bank 0 etc. We also need to erase the segment that
* is going to be written
*/
ret_val = e1000_valid_nvm_bank_detect_ich8lan(hw, &bank);
if (ret_val)
return ret_val;
if (ret_val) {
e1000_release_swflag_ich8lan(hw);
goto out;
}

if (bank == 0) {
new_bank_offset = nvm->flash_bank_size;
old_bank_offset = 0;
e1000_erase_flash_bank_ich8lan(hw, 1);
ret_val = e1000_erase_flash_bank_ich8lan(hw, 1);
if (ret_val) {
e1000_release_swflag_ich8lan(hw);
goto out;
}
} else {
old_bank_offset = nvm->flash_bank_size;
new_bank_offset = 0;
e1000_erase_flash_bank_ich8lan(hw, 0);
ret_val = e1000_erase_flash_bank_ich8lan(hw, 0);
if (ret_val) {
e1000_release_swflag_ich8lan(hw);
goto out;
}
}

for (i = 0; i < E1000_ICH8_SHADOW_RAM_WORDS; i++) {
Expand All @@ -1379,9 +1413,11 @@ static s32 e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw)
if (dev_spec->shadow_ram[i].modified) {
data = dev_spec->shadow_ram[i].value;
} else {
e1000_read_flash_word_ich8lan(hw,
i + old_bank_offset,
&data);
ret_val = e1000_read_flash_word_ich8lan(hw, i +
old_bank_offset,
&data);
if (ret_val)
break;
}

/*
Expand Down Expand Up @@ -1422,7 +1458,7 @@ static s32 e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw)
/* Possibly read-only, see e1000e_write_protect_nvm_ich8lan() */
hw_dbg(hw, "Flash commit failed.\n");
e1000_release_swflag_ich8lan(hw);
return ret_val;
goto out;
}

/*
Expand All @@ -1432,14 +1468,18 @@ static s32 e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw)
* and we need to change bit 14 to 0b
*/
act_offset = new_bank_offset + E1000_ICH_NVM_SIG_WORD;
e1000_read_flash_word_ich8lan(hw, act_offset, &data);
ret_val = e1000_read_flash_word_ich8lan(hw, act_offset, &data);
if (ret_val) {
e1000_release_swflag_ich8lan(hw);
goto out;
}
data &= 0xBFFF;
ret_val = e1000_retry_write_flash_byte_ich8lan(hw,
act_offset * 2 + 1,
(u8)(data >> 8));
if (ret_val) {
e1000_release_swflag_ich8lan(hw);
return ret_val;
goto out;
}

/*
Expand All @@ -1452,7 +1492,7 @@ static s32 e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw)
ret_val = e1000_retry_write_flash_byte_ich8lan(hw, act_offset, 0);
if (ret_val) {
e1000_release_swflag_ich8lan(hw);
return ret_val;
goto out;
}

/* Great! Everything worked, we can now clear the cached entries. */
Expand All @@ -1470,6 +1510,10 @@ static s32 e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw)
e1000e_reload_nvm(hw);
msleep(10);

out:
if (ret_val)
hw_dbg(hw, "NVM update error: %d\n", ret_val);

return ret_val;
}

Expand Down
4 changes: 2 additions & 2 deletions trunk/drivers/net/e1000e/netdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -4723,14 +4723,14 @@ static void e1000_eeprom_checks(struct e1000_adapter *adapter)
return;

ret_val = e1000_read_nvm(hw, NVM_INIT_CONTROL2_REG, 1, &buf);
if (!(le16_to_cpu(buf) & (1 << 0))) {
if (!ret_val && (!(le16_to_cpu(buf) & (1 << 0)))) {
/* Deep Smart Power Down (DSPD) */
dev_warn(&adapter->pdev->dev,
"Warning: detected DSPD enabled in EEPROM\n");
}

ret_val = e1000_read_nvm(hw, NVM_INIT_3GIO_3, 1, &buf);
if (le16_to_cpu(buf) & (3 << 2)) {
if (!ret_val && (le16_to_cpu(buf) & (3 << 2))) {
/* ASPM enable */
dev_warn(&adapter->pdev->dev,
"Warning: detected ASPM enabled in EEPROM\n");
Expand Down

0 comments on commit ff06f94

Please sign in to comment.