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
From 768ca008dcf796a9d1cea85d215797996d0edbf6 Mon Sep 17 00:00:00 2001
From: Matthias Teege <[email protected]>
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

_______________________________________________
ipxe-devel mailing list
[email protected]
https://lists.ipxe.org/mailman/listinfo/ipxe-devel

Reply via email to