[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