Re: [U-Boot] [PATCH 02/16] net: e1000: add support for writing to EEPROM

2017-12-05 Thread Joe Hershberger
On Wed, Nov 8, 2017 at 9:59 AM, Martyn Welch
 wrote:
> From: Hannu Lounento 
>
> Port functions for writing to EEPROM, updating the checksum and
> committing data to flash from the Linux kernel igb driver.
>
> Functions were ported from Linux 4.8-rc2 (694d0d0bb20).
>
> Signed-off-by: Hannu Lounento 
> CC: Joe Hershberger 
> Signed-off-by: Martyn Welch 

Acked-by: Joe Hershberger 
___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


Re: [U-Boot] [PATCH 02/16] net: e1000: add support for writing to EEPROM

2017-11-20 Thread Stefano Babic
On 08/11/2017 16:59, Martyn Welch wrote:
> From: Hannu Lounento 
> 
> Port functions for writing to EEPROM, updating the checksum and
> committing data to flash from the Linux kernel igb driver.
> 
> Functions were ported from Linux 4.8-rc2 (694d0d0bb20).
> 
> Signed-off-by: Hannu Lounento 
> CC: Joe Hershberger 
> Signed-off-by: Martyn Welch 
> ---
>  drivers/net/e1000.c | 171 
> +++-
>  drivers/net/e1000.h |   3 +
>  2 files changed, 172 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/net/e1000.c b/drivers/net/e1000.c
> index 875682b..7aecdb9 100644
> --- a/drivers/net/e1000.c
> +++ b/drivers/net/e1000.c
> @@ -150,6 +150,7 @@ static int32_t e1000_check_phy_reset_block(struct 
> e1000_hw *hw);
>  
>  #ifndef CONFIG_E1000_NO_NVM
>  static void e1000_put_hw_eeprom_semaphore(struct e1000_hw *hw);
> +static int32_t e1000_get_hw_eeprom_semaphore(struct e1000_hw *hw);
>  static int32_t e1000_read_eeprom(struct e1000_hw *hw, uint16_t offset,
>   uint16_t words,
>   uint16_t *data);
> @@ -862,6 +863,62 @@ e1000_read_eeprom(struct e1000_hw *hw, uint16_t offset,
>  }
>  
>  
> /**
> + *  e1000_write_eeprom_srwr - Write to Shadow Ram using EEWR
> + *  @hw: pointer to the HW structure
> + *  @offset: offset within the Shadow Ram to be written to
> + *  @words: number of words to write
> + *  @data: 16 bit word(s) to be written to the Shadow Ram
> + *
> + *  Writes data to Shadow Ram at offset using EEWR register.
> + *
> + *  If e1000_update_eeprom_checksum_i210 is not called after this function, 
> the
> + *  Shadow Ram will most likely contain an invalid checksum.
> + 
> */
> +static int32_t e1000_write_eeprom_srwr(struct e1000_hw *hw, uint16_t offset,
> +uint16_t words, uint16_t *data)
> +{
> + struct e1000_eeprom_info *eeprom = >eeprom;
> + uint32_t i, k, eewr = 0;
> + uint32_t attempts = 10;
> + int32_t ret_val = 0;
> +
> + /* A check for invalid values:  offset too large, too many words,
> +  * too many words for the offset, and not enough words.
> +  */
> + if ((offset >= eeprom->word_size) ||
> + (words > (eeprom->word_size - offset)) || (words == 0)) {
> + DEBUGOUT("nvm parameter(s) out of bounds\n");
> + ret_val = -E1000_ERR_EEPROM;
> + goto out;
> + }
> +
> + for (i = 0; i < words; i++) {
> + eewr = ((offset + i) << E1000_EEPROM_RW_ADDR_SHIFT)
> + | (data[i] << E1000_EEPROM_RW_REG_DATA) |
> + E1000_EEPROM_RW_REG_START;
> +
> + E1000_WRITE_REG(hw, I210_EEWR, eewr);
> +
> + for (k = 0; k < attempts; k++) {
> + if (E1000_EEPROM_RW_REG_DONE &
> + E1000_READ_REG(hw, I210_EEWR)) {
> + ret_val = 0;
> + break;
> + }
> + udelay(5);
> + }
> +
> + if (ret_val) {
> + DEBUGOUT("Shadow RAM write EEWR timed out\n");
> + break;
> + }
> + }
> +
> +out:
> + return ret_val;
> +}
> +
> +/**
>   * Verifies that the EEPROM has a valid checksum
>   *
>   * hw - Struct containing variables accessed by shared code
> @@ -907,6 +964,116 @@ static int e1000_validate_eeprom_checksum(struct 
> e1000_hw *hw)
>  
>   return -E1000_ERR_EEPROM;
>  }
> +
> +/**
> + *  e1000_pool_flash_update_done_i210 - Pool FLUDONE status.
> + *  @hw: pointer to the HW structure
> + *
> + 
> */
> +static int32_t e1000_pool_flash_update_done_i210(struct e1000_hw *hw)
> +{
> + int32_t ret_val = -E1000_ERR_EEPROM;
> + uint32_t i, reg;
> +
> + for (i = 0; i < E1000_FLUDONE_ATTEMPTS; i++) {
> + reg = E1000_READ_REG(hw, EECD);
> + if (reg & E1000_EECD_FLUDONE_I210) {
> + ret_val = 0;
> + break;
> + }
> + udelay(5);
> + }
> +
> + return ret_val;
> +}
> +
> +/**
> + *  e1000_update_flash_i210 - Commit EEPROM to the flash
> + *  @hw: pointer to the HW structure
> + *
> + 
> */
> +static int32_t e1000_update_flash_i210(struct e1000_hw *hw)
> +{
> + int32_t ret_val = 0;
> + uint32_t flup;
> +
> + ret_val = 

[U-Boot] [PATCH 02/16] net: e1000: add support for writing to EEPROM

2017-11-08 Thread Martyn Welch
From: Hannu Lounento 

Port functions for writing to EEPROM, updating the checksum and
committing data to flash from the Linux kernel igb driver.

Functions were ported from Linux 4.8-rc2 (694d0d0bb20).

Signed-off-by: Hannu Lounento 
CC: Joe Hershberger 
Signed-off-by: Martyn Welch 
---
 drivers/net/e1000.c | 171 +++-
 drivers/net/e1000.h |   3 +
 2 files changed, 172 insertions(+), 2 deletions(-)

diff --git a/drivers/net/e1000.c b/drivers/net/e1000.c
index 875682b..7aecdb9 100644
--- a/drivers/net/e1000.c
+++ b/drivers/net/e1000.c
@@ -150,6 +150,7 @@ static int32_t e1000_check_phy_reset_block(struct e1000_hw 
*hw);
 
 #ifndef CONFIG_E1000_NO_NVM
 static void e1000_put_hw_eeprom_semaphore(struct e1000_hw *hw);
+static int32_t e1000_get_hw_eeprom_semaphore(struct e1000_hw *hw);
 static int32_t e1000_read_eeprom(struct e1000_hw *hw, uint16_t offset,
uint16_t words,
uint16_t *data);
@@ -862,6 +863,62 @@ e1000_read_eeprom(struct e1000_hw *hw, uint16_t offset,
 }
 
 /**
+ *  e1000_write_eeprom_srwr - Write to Shadow Ram using EEWR
+ *  @hw: pointer to the HW structure
+ *  @offset: offset within the Shadow Ram to be written to
+ *  @words: number of words to write
+ *  @data: 16 bit word(s) to be written to the Shadow Ram
+ *
+ *  Writes data to Shadow Ram at offset using EEWR register.
+ *
+ *  If e1000_update_eeprom_checksum_i210 is not called after this function, the
+ *  Shadow Ram will most likely contain an invalid checksum.
+ */
+static int32_t e1000_write_eeprom_srwr(struct e1000_hw *hw, uint16_t offset,
+  uint16_t words, uint16_t *data)
+{
+   struct e1000_eeprom_info *eeprom = >eeprom;
+   uint32_t i, k, eewr = 0;
+   uint32_t attempts = 10;
+   int32_t ret_val = 0;
+
+   /* A check for invalid values:  offset too large, too many words,
+* too many words for the offset, and not enough words.
+*/
+   if ((offset >= eeprom->word_size) ||
+   (words > (eeprom->word_size - offset)) || (words == 0)) {
+   DEBUGOUT("nvm parameter(s) out of bounds\n");
+   ret_val = -E1000_ERR_EEPROM;
+   goto out;
+   }
+
+   for (i = 0; i < words; i++) {
+   eewr = ((offset + i) << E1000_EEPROM_RW_ADDR_SHIFT)
+   | (data[i] << E1000_EEPROM_RW_REG_DATA) |
+   E1000_EEPROM_RW_REG_START;
+
+   E1000_WRITE_REG(hw, I210_EEWR, eewr);
+
+   for (k = 0; k < attempts; k++) {
+   if (E1000_EEPROM_RW_REG_DONE &
+   E1000_READ_REG(hw, I210_EEWR)) {
+   ret_val = 0;
+   break;
+   }
+   udelay(5);
+   }
+
+   if (ret_val) {
+   DEBUGOUT("Shadow RAM write EEWR timed out\n");
+   break;
+   }
+   }
+
+out:
+   return ret_val;
+}
+
+/**
  * Verifies that the EEPROM has a valid checksum
  *
  * hw - Struct containing variables accessed by shared code
@@ -907,6 +964,116 @@ static int e1000_validate_eeprom_checksum(struct e1000_hw 
*hw)
 
return -E1000_ERR_EEPROM;
 }
+
+/**
+ *  e1000_pool_flash_update_done_i210 - Pool FLUDONE status.
+ *  @hw: pointer to the HW structure
+ *
+ */
+static int32_t e1000_pool_flash_update_done_i210(struct e1000_hw *hw)
+{
+   int32_t ret_val = -E1000_ERR_EEPROM;
+   uint32_t i, reg;
+
+   for (i = 0; i < E1000_FLUDONE_ATTEMPTS; i++) {
+   reg = E1000_READ_REG(hw, EECD);
+   if (reg & E1000_EECD_FLUDONE_I210) {
+   ret_val = 0;
+   break;
+   }
+   udelay(5);
+   }
+
+   return ret_val;
+}
+
+/**
+ *  e1000_update_flash_i210 - Commit EEPROM to the flash
+ *  @hw: pointer to the HW structure
+ *
+ */
+static int32_t e1000_update_flash_i210(struct e1000_hw *hw)
+{
+   int32_t ret_val = 0;
+   uint32_t flup;
+
+   ret_val = e1000_pool_flash_update_done_i210(hw);
+   if (ret_val == -E1000_ERR_EEPROM) {
+   DEBUGOUT("Flash update time out\n");
+   goto out;
+   }
+
+   flup = E1000_READ_REG(hw, EECD) |