[ipxe-devel] ifopen net0 not enough space
Matthias Teege
matthias-ipxe at mteege.de
Wed May 4 07:07:37 UTC 2011
On Tue, 3 May 2011, Michael Brown wrote:
Hello,
> The attached patch (compile-tested only) removes all references to this
> shadowed RAM. Let me know if it fixes your problem.
it does not compile against 987b825b7f046e844a332d27497b4846cb23ba43. I've
remade the patch. It works now as expected.
Many thanks
Matthias
-------------- next part --------------
From 768ca008dcf796a9d1cea85d215797996d0edbf6 Mon Sep 17 00:00:00 2001
From: Matthias Teege <matthias-git at mteege.de>
Date: Wed, 4 May 2011 09:02:48 +0200
Subject: [PATCH] img e1000e kill shadow ram again
---
src/drivers/net/e1000e/e1000e_hw.h | 8 -
src/drivers/net/e1000e/e1000e_ich8lan.c | 465 +-----------------------------
2 files changed, 16 insertions(+), 457 deletions(-)
diff --git a/src/drivers/net/e1000e/e1000e_hw.h b/src/drivers/net/e1000e/e1000e_hw.h
index 03ed35c..07b506a 100644
--- a/src/drivers/net/e1000e/e1000e_hw.h
+++ b/src/drivers/net/e1000e/e1000e_hw.h
@@ -666,16 +666,8 @@ struct e1000_dev_spec_80003es2lan {
bool mdic_wa_enable;
};
-struct e1000_shadow_ram {
- u16 value;
- bool modified;
-};
-
-#define E1000_ICH8_SHADOW_RAM_WORDS 2048
-
struct e1000_dev_spec_ich8lan {
bool kmrn_lock_loss_workaround_enabled;
- struct e1000_shadow_ram shadow_ram[E1000_ICH8_SHADOW_RAM_WORDS];
bool nvm_k1_enabled;
};
diff --git a/src/drivers/net/e1000e/e1000e_ich8lan.c b/src/drivers/net/e1000e/e1000e_ich8lan.c
index 7b9a49b..dd6c6da 100644
--- a/src/drivers/net/e1000e/e1000e_ich8lan.c
+++ b/src/drivers/net/e1000e/e1000e_ich8lan.c
@@ -100,7 +100,6 @@ static s32 e1000e_cleanup_led_pchlan(struct e1000_hw *hw);
static s32 e1000e_led_on_pchlan(struct e1000_hw *hw);
static s32 e1000e_led_off_pchlan(struct e1000_hw *hw);
static void e1000e_clear_hw_cntrs_ich8lan(struct e1000_hw *hw);
-static s32 e1000e_erase_flash_bank_ich8lan(struct e1000_hw *hw, u32 bank);
static s32 e1000e_flash_cycle_ich8lan(struct e1000_hw *hw, u32 timeout);
static s32 e1000e_flash_cycle_init_ich8lan(struct e1000_hw *hw);
static s32 e1000e_get_phy_info_ife_ich8lan(struct e1000_hw *hw);
@@ -112,12 +111,6 @@ static s32 e1000e_read_flash_data_ich8lan(struct e1000_hw *hw, u32 offset,
u8 size, u16 *data);
static s32 e1000e_read_flash_word_ich8lan(struct e1000_hw *hw,
u32 offset, u16 *data);
-static s32 e1000e_retry_write_flash_byte_ich8lan(struct e1000_hw *hw,
- u32 offset, u8 byte);
-static s32 e1000e_write_flash_byte_ich8lan(struct e1000_hw *hw,
- u32 offset, u8 data);
-static s32 e1000e_write_flash_data_ich8lan(struct e1000_hw *hw, u32 offset,
- u8 size, u16 data);
static s32 e1000e_get_cfg_done_ich8lan(struct e1000_hw *hw);
static void e1000e_power_down_phy_copper_ich8lan(struct e1000_hw *hw);
static s32 e1000e_check_for_copper_link_ich8lan(struct e1000_hw *hw);
@@ -321,10 +314,9 @@ out:
static s32 e1000e_init_nvm_params_ich8lan(struct e1000_hw *hw)
{
struct e1000_nvm_info *nvm = &hw->nvm;
- struct e1000_dev_spec_ich8lan *dev_spec = &hw->dev_spec.ich8lan;
+ struct e1000_dev_spec_ich8lan;
u32 gfpreg, sector_base_addr, sector_end_addr;
s32 ret_val = E1000_SUCCESS;
- u16 i;
/* Can't read flash registers if the register set isn't mapped. */
if (!hw->flash_address) {
@@ -358,14 +350,6 @@ static s32 e1000e_init_nvm_params_ich8lan(struct e1000_hw *hw)
/* Adjust to word count */
nvm->flash_bank_size /= sizeof(u16);
- nvm->word_size = E1000_ICH8_SHADOW_RAM_WORDS;
-
- /* Clear shadow ram */
- for (i = 0; i < nvm->word_size; i++) {
- dev_spec->shadow_ram[i].modified = false;
- dev_spec->shadow_ram[i].value = 0xFFFF;
- }
-
/* Function Pointers */
nvm->ops.acquire = e1000e_acquire_nvm_ich8lan;
nvm->ops.release = e1000e_release_nvm_ich8lan;
@@ -1573,7 +1557,7 @@ static s32 e1000e_read_nvm_ich8lan(struct e1000_hw *hw, u16 offset, u16 words,
u16 *data)
{
struct e1000_nvm_info *nvm = &hw->nvm;
- struct e1000_dev_spec_ich8lan *dev_spec = &hw->dev_spec.ich8lan;
+ struct e1000_dev_spec_ich8lan;
u32 act_offset;
s32 ret_val = E1000_SUCCESS;
u32 bank = 0;
@@ -1599,17 +1583,12 @@ static s32 e1000e_read_nvm_ich8lan(struct e1000_hw *hw, u16 offset, u16 words,
ret_val = E1000_SUCCESS;
for (i = 0; i < words; i++) {
- if ((dev_spec->shadow_ram) &&
- (dev_spec->shadow_ram[offset+i].modified)) {
- data[i] = dev_spec->shadow_ram[offset+i].value;
- } else {
- ret_val = e1000e_read_flash_word_ich8lan(hw,
- act_offset + i,
- &word);
- if (ret_val)
- break;
- data[i] = word;
- }
+ ret_val = e1000e_read_flash_word_ich8lan(hw,
+ act_offset + i,
+ &word);
+ if (ret_val)
+ break;
+ data[i] = word;
}
nvm->ops.release(hw);
@@ -1871,32 +1850,12 @@ out:
*
* Writes a byte or word to the NVM using the flash access registers.
**/
-static s32 e1000e_write_nvm_ich8lan(struct e1000_hw *hw, u16 offset, u16 words,
- u16 *data)
+static s32 e1000e_write_nvm_ich8lan(struct e1000_hw *hw __unused,
+ u16 offset __unused, u16 words __unused,
+ u16 *data __unused)
{
- struct e1000_nvm_info *nvm = &hw->nvm;
- struct e1000_dev_spec_ich8lan *dev_spec = &hw->dev_spec.ich8lan;
- s32 ret_val = E1000_SUCCESS;
- u16 i;
-
- if ((offset >= nvm->word_size) || (words > nvm->word_size - offset) ||
- (words == 0)) {
- e_dbg("nvm parameter(s) out of bounds\n");
- ret_val = -E1000_ERR_NVM;
- goto out;
- }
-
- nvm->ops.acquire(hw);
-
- for (i = 0; i < words; i++) {
- dev_spec->shadow_ram[offset+i].modified = true;
- dev_spec->shadow_ram[offset+i].value = data[i];
- }
-
- nvm->ops.release(hw);
-
-out:
- return ret_val;
+ e_dbg("nvm write not supported\n");
+ return E1000_SUCCESS;
}
/**
@@ -1910,163 +1869,10 @@ out:
* After a successful commit, the shadow ram is cleared and is ready for
* future writes.
**/
-static s32 e1000e_update_nvm_checksum_ich8lan(struct e1000_hw *hw)
+static s32 e1000e_update_nvm_checksum_ich8lan(struct e1000_hw *hw __unused)
{
- struct e1000_nvm_info *nvm = &hw->nvm;
- struct e1000_dev_spec_ich8lan *dev_spec = &hw->dev_spec.ich8lan;
- u32 i, act_offset, new_bank_offset, old_bank_offset, bank;
- s32 ret_val;
- u16 data;
-
- ret_val = e1000e_update_nvm_checksum_generic(hw);
- if (ret_val)
- goto out;
-
- if (nvm->type != e1000_nvm_flash_sw)
- goto out;
-
- nvm->ops.acquire(hw);
-
- /*
- * 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 = e1000e_valid_nvm_bank_detect_ich8lan(hw, &bank);
- if (ret_val != E1000_SUCCESS) {
- e_dbg("Could not detect valid bank, assuming bank 0\n");
- bank = 0;
- }
-
- if (bank == 0) {
- new_bank_offset = nvm->flash_bank_size;
- old_bank_offset = 0;
- ret_val = e1000e_erase_flash_bank_ich8lan(hw, 1);
- if (ret_val) {
- nvm->ops.release(hw);
- goto out;
- }
- } else {
- old_bank_offset = nvm->flash_bank_size;
- new_bank_offset = 0;
- ret_val = e1000e_erase_flash_bank_ich8lan(hw, 0);
- if (ret_val) {
- nvm->ops.release(hw);
- goto out;
- }
- }
-
- for (i = 0; i < E1000_ICH8_SHADOW_RAM_WORDS; i++) {
- /*
- * Determine whether to write the value stored
- * in the other NVM bank or a modified value stored
- * in the shadow RAM
- */
- if (dev_spec->shadow_ram[i].modified) {
- data = dev_spec->shadow_ram[i].value;
- } else {
- ret_val = e1000e_read_flash_word_ich8lan(hw, i +
- old_bank_offset,
- &data);
- if (ret_val)
- break;
- }
-
- /*
- * If the word is 0x13, then make sure the signature bits
- * (15:14) are 11b until the commit has completed.
- * This will allow us to write 10b which indicates the
- * signature is valid. We want to do this after the write
- * has completed so that we don't mark the segment valid
- * while the write is still in progress
- */
- if (i == E1000_ICH_NVM_SIG_WORD)
- data |= E1000_ICH_NVM_SIG_MASK;
-
- /* Convert offset to bytes. */
- act_offset = (i + new_bank_offset) << 1;
-
- udelay(100);
- /* Write the bytes to the new bank. */
- ret_val = e1000e_retry_write_flash_byte_ich8lan(hw,
- act_offset,
- (u8)data);
- if (ret_val)
- break;
-
- udelay(100);
- ret_val = e1000e_retry_write_flash_byte_ich8lan(hw,
- act_offset + 1,
- (u8)(data >> 8));
- if (ret_val)
- break;
- }
-
- /*
- * Don't bother writing the segment valid bits if sector
- * programming failed.
- */
- if (ret_val) {
- e_dbg("Flash commit failed.\n");
- nvm->ops.release(hw);
- goto out;
- }
-
- /*
- * Finally validate the new segment by setting bit 15:14
- * to 10b in word 0x13 , this can be done without an
- * erase as well since these bits are 11 to start with
- * and we need to change bit 14 to 0b
- */
- act_offset = new_bank_offset + E1000_ICH_NVM_SIG_WORD;
- ret_val = e1000e_read_flash_word_ich8lan(hw, act_offset, &data);
- if (ret_val) {
- nvm->ops.release(hw);
- goto out;
- }
-
- data &= 0xBFFF;
- ret_val = e1000e_retry_write_flash_byte_ich8lan(hw,
- act_offset * 2 + 1,
- (u8)(data >> 8));
- if (ret_val) {
- nvm->ops.release(hw);
- goto out;
- }
-
- /*
- * And invalidate the previously valid segment by setting
- * its signature word (0x13) high_byte to 0b. This can be
- * done without an erase because flash erase sets all bits
- * to 1's. We can write 1's to 0's without an erase
- */
- act_offset = (old_bank_offset + E1000_ICH_NVM_SIG_WORD) * 2 + 1;
- ret_val = e1000e_retry_write_flash_byte_ich8lan(hw, act_offset, 0);
- if (ret_val) {
- nvm->ops.release(hw);
- goto out;
- }
-
- /* Great! Everything worked, we can now clear the cached entries. */
- for (i = 0; i < E1000_ICH8_SHADOW_RAM_WORDS; i++) {
- dev_spec->shadow_ram[i].modified = false;
- dev_spec->shadow_ram[i].value = 0xFFFF;
- }
-
- nvm->ops.release(hw);
-
- /*
- * Reload the EEPROM, or else modifications will not appear
- * until after the next adapter reset.
- */
- nvm->ops.reload(hw);
- msleep(10);
-
-out:
- if (ret_val)
- e_dbg("NVM update error: %d\n", ret_val);
-
- return ret_val;
+ e_dbg("nvm write not supported\n");
+ return E1000_SUCCESS;
}
/**
@@ -2108,246 +1914,7 @@ out:
return ret_val;
}
-/**
- * e1000e_write_flash_data_ich8lan - Writes bytes to the NVM
- * @hw: pointer to the HW structure
- * @offset: The offset (in bytes) of the byte/word to read.
- * @size: Size of data to read, 1=byte 2=word
- * @data: The byte(s) to write to the NVM.
- *
- * Writes one/two bytes to the NVM using the flash access registers.
- **/
-static s32 e1000e_write_flash_data_ich8lan(struct e1000_hw *hw, u32 offset,
- u8 size, u16 data)
-{
- union ich8_hws_flash_status hsfsts;
- union ich8_hws_flash_ctrl hsflctl;
- u32 flash_linear_addr;
- u32 flash_data = 0;
- s32 ret_val = -E1000_ERR_NVM;
- u8 count = 0;
-
- if (size < 1 || size > 2 || data > size * 0xff ||
- offset > ICH_FLASH_LINEAR_ADDR_MASK)
- goto out;
-
- flash_linear_addr = (ICH_FLASH_LINEAR_ADDR_MASK & offset) +
- hw->nvm.flash_base_addr;
-
- do {
- udelay(1);
- /* Steps */
- ret_val = e1000e_flash_cycle_init_ich8lan(hw);
- if (ret_val != E1000_SUCCESS)
- break;
-
- hsflctl.regval = er16flash(ICH_FLASH_HSFCTL);
- /* 0b/1b corresponds to 1 or 2 byte size, respectively. */
- hsflctl.hsf_ctrl.fldbcount = size - 1;
- hsflctl.hsf_ctrl.flcycle = ICH_CYCLE_WRITE;
- ew16flash(ICH_FLASH_HSFCTL, hsflctl.regval);
-
- ew32flash(ICH_FLASH_FADDR, flash_linear_addr);
-
- if (size == 1)
- flash_data = (u32)data & 0x00FF;
- else
- flash_data = (u32)data;
-
- ew32flash(ICH_FLASH_FDATA0, flash_data);
-
- /*
- * check if FCERR is set to 1 , if set to 1, clear it
- * and try the whole sequence a few more times else done
- */
- ret_val = e1000e_flash_cycle_ich8lan(hw,
- ICH_FLASH_WRITE_COMMAND_TIMEOUT);
- if (ret_val == E1000_SUCCESS)
- break;
-
- /*
- * If we're here, then things are most likely
- * completely hosed, but if the error condition
- * is detected, it won't hurt to give it another
- * try...ICH_FLASH_CYCLE_REPEAT_COUNT times.
- */
- hsfsts.regval = er16flash(ICH_FLASH_HSFSTS);
- if (hsfsts.hsf_status.flcerr == 1) {
- /* Repeat for some time before giving up. */
- continue;
- } else if (hsfsts.hsf_status.flcdone == 0) {
- e_dbg("Timeout error - flash cycle "
- "did not complete.");
- break;
- }
- } while (count++ < ICH_FLASH_CYCLE_REPEAT_COUNT);
-
-out:
- return ret_val;
-}
-
-/**
- * e1000e_write_flash_byte_ich8lan - Write a single byte to NVM
- * @hw: pointer to the HW structure
- * @offset: The index of the byte to read.
- * @data: The byte to write to the NVM.
- *
- * Writes a single byte to the NVM using the flash access registers.
- **/
-static s32 e1000e_write_flash_byte_ich8lan(struct e1000_hw *hw, u32 offset,
- u8 data)
-{
- u16 word = (u16)data;
-
- return e1000e_write_flash_data_ich8lan(hw, offset, 1, word);
-}
-
-/**
- * e1000e_retry_write_flash_byte_ich8lan - Writes a single byte to NVM
- * @hw: pointer to the HW structure
- * @offset: The offset of the byte to write.
- * @byte: The byte to write to the NVM.
- *
- * Writes a single byte to the NVM using the flash access registers.
- * Goes through a retry algorithm before giving up.
- **/
-static s32 e1000e_retry_write_flash_byte_ich8lan(struct e1000_hw *hw,
- u32 offset, u8 byte)
-{
- s32 ret_val;
- u16 program_retries;
-
- ret_val = e1000e_write_flash_byte_ich8lan(hw, offset, byte);
- if (ret_val == E1000_SUCCESS)
- goto out;
-
- for (program_retries = 0; program_retries < 100; program_retries++) {
- e_dbg("Retrying Byte %2.2X at offset %u\n", byte, offset);
- udelay(100);
- ret_val = e1000e_write_flash_byte_ich8lan(hw, offset, byte);
- if (ret_val == E1000_SUCCESS)
- break;
- }
- if (program_retries == 100) {
- ret_val = -E1000_ERR_NVM;
- goto out;
- }
-
-out:
- return ret_val;
-}
-
-/**
- * e1000e_erase_flash_bank_ich8lan - Erase a bank (4k) from NVM
- * @hw: pointer to the HW structure
- * @bank: 0 for first bank, 1 for second bank, etc.
- *
- * Erases the bank specified. Each bank is a 4k block. Banks are 0 based.
- * bank N is 4096 * N + flash_reg_addr.
- **/
-static s32 e1000e_erase_flash_bank_ich8lan(struct e1000_hw *hw, u32 bank)
-{
- struct e1000_nvm_info *nvm = &hw->nvm;
- union ich8_hws_flash_status hsfsts;
- union ich8_hws_flash_ctrl hsflctl;
- u32 flash_linear_addr;
- /* bank size is in 16bit words - adjust to bytes */
- u32 flash_bank_size = nvm->flash_bank_size * 2;
- s32 ret_val = E1000_SUCCESS;
- s32 count = 0;
- s32 j, iteration, sector_size;
-
- hsfsts.regval = er16flash(ICH_FLASH_HSFSTS);
-
- /*
- * Determine HW Sector size: Read BERASE bits of hw flash status
- * register
- * 00: The Hw sector is 256 bytes, hence we need to erase 16
- * consecutive sectors. The start index for the nth Hw sector
- * can be calculated as = bank * 4096 + n * 256
- * 01: The Hw sector is 4K bytes, hence we need to erase 1 sector.
- * The start index for the nth Hw sector can be calculated
- * as = bank * 4096
- * 10: The Hw sector is 8K bytes, nth sector = bank * 8192
- * (ich9 only, otherwise error condition)
- * 11: The Hw sector is 64K bytes, nth sector = bank * 65536
- */
- switch (hsfsts.hsf_status.berasesz) {
- case 0:
- /* Hw sector size 256 */
- sector_size = ICH_FLASH_SEG_SIZE_256;
- iteration = flash_bank_size / ICH_FLASH_SEG_SIZE_256;
- break;
- case 1:
- sector_size = ICH_FLASH_SEG_SIZE_4K;
- iteration = 1;
- break;
- case 2:
- sector_size = ICH_FLASH_SEG_SIZE_8K;
- iteration = 1;
- break;
- case 3:
- sector_size = ICH_FLASH_SEG_SIZE_64K;
- iteration = 1;
- break;
- default:
- ret_val = -E1000_ERR_NVM;
- goto out;
- }
-
- /* Start with the base address, then add the sector offset. */
- flash_linear_addr = hw->nvm.flash_base_addr;
- flash_linear_addr += (bank) ? flash_bank_size : 0;
-
- for (j = 0; j < iteration ; j++) {
- do {
- /* Steps */
- ret_val = e1000e_flash_cycle_init_ich8lan(hw);
- if (ret_val)
- goto out;
-
- /*
- * Write a value 11 (block Erase) in Flash
- * Cycle field in hw flash control
- */
- hsflctl.regval = er16flash(
- ICH_FLASH_HSFCTL);
- hsflctl.hsf_ctrl.flcycle = ICH_CYCLE_ERASE;
- ew16flash(ICH_FLASH_HSFCTL,
- hsflctl.regval);
- /*
- * Write the last 24 bits of an index within the
- * block into Flash Linear address field in Flash
- * Address.
- */
- flash_linear_addr += (j * sector_size);
- ew32flash(ICH_FLASH_FADDR,
- flash_linear_addr);
-
- ret_val = e1000e_flash_cycle_ich8lan(hw,
- ICH_FLASH_ERASE_COMMAND_TIMEOUT);
- if (ret_val == E1000_SUCCESS)
- break;
-
- /*
- * Check if FCERR is set to 1. If 1,
- * clear it and try the whole sequence
- * a few more times else Done
- */
- hsfsts.regval = er16flash(
- ICH_FLASH_HSFSTS);
- if (hsfsts.hsf_status.flcerr == 1)
- /* repeat for some time before giving up */
- continue;
- else if (hsfsts.hsf_status.flcdone == 0)
- goto out;
- } while (++count < ICH_FLASH_CYCLE_REPEAT_COUNT);
- }
-
-out:
- return ret_val;
-}
/**
* e1000e_valid_led_default_ich8lan - Set the default LED settings
--
1.7.3.4
More information about the ipxe-devel
mailing list