netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Jeff Garzik <jgarzik@pobox.com>
To: "Kok, Auke" <auke-jan.h.kok@intel.com>
Cc: netdev@vger.kernel.org, "Brandeburg,
	Jesse" <jesse.brandeburg@intel.com>,
	"Kok, Auke" <auke@foo-projects.org>,
	"Ronciak, John" <john.ronciak@intel.com>
Subject: Re: [PATCH 18/21] e1000: integrate ich8 support into driver
Date: Mon, 26 Jun 2006 21:54:36 -0400	[thread overview]
Message-ID: <44A08FDC.2080201@pobox.com> (raw)
In-Reply-To: <20060622052046.25497.11216.stgit@gitlost.site>

Kok, Auke wrote:
> @@ -4225,6 +4396,35 @@ e1000_init_eeprom_params(struct e1000_hw
>          eeprom->use_eerd = TRUE;
>          eeprom->use_eewr = FALSE;
>          break;
> +    case e1000_ich8lan:
> +    {
> +        int32_t  i = 0;
> +        uint32_t flash_size = E1000_READ_ICH8_REG(hw, ICH8_FLASH_GFPREG);
> +
> +        eeprom->type = e1000_eeprom_ich8;
> +        eeprom->use_eerd = FALSE;
> +        eeprom->use_eewr = FALSE;
> +        eeprom->word_size = E1000_SHADOW_RAM_WORDS;
> +
> +        /* Zero the shadow RAM structure. But don't load it from NVM
> +         * so as to save time for driver init */
> +        if (hw->eeprom_shadow_ram != NULL) {
> +            for (i = 0; i < E1000_SHADOW_RAM_WORDS; i++) {
> +                hw->eeprom_shadow_ram[i].modified = FALSE;
> +                hw->eeprom_shadow_ram[i].eeprom_word = 0xFFFF;
> +            }
> +        }
> +
> +        hw->flash_base_addr = (flash_size & ICH8_GFPREG_BASE_MASK) *
> +                              ICH8_FLASH_SECTOR_SIZE;
> +
> +        hw->flash_bank_size = ((flash_size >> 16) & ICH8_GFPREG_BASE_MASK) + 1;
> +        hw->flash_bank_size -= (flash_size & ICH8_GFPREG_BASE_MASK);
> +        hw->flash_bank_size *= ICH8_FLASH_SECTOR_SIZE;
> +        hw->flash_bank_size /= 2 * sizeof(uint16_t);
> +
> +        break;
> +    }

seems to warrant a separate function, called from this callsite (perhaps 
stored in e1000-ich8.c?)


> @@ -4645,7 +4845,10 @@ e1000_read_eeprom(struct e1000_hw *hw,
>          return ret_val;
>      }
>  
> -    if(eeprom->type == e1000_eeprom_spi) {
> +    if (eeprom->type == e1000_eeprom_ich8)
> +        return e1000_read_eeprom_ich8(hw, offset, words, data);
> +
> +    if (eeprom->type == e1000_eeprom_spi) {
>          uint16_t word_in;
>          uint8_t read_opcode = EEPROM_READ_OPCODE_SPI;
>  
> @@ -4812,7 +5015,10 @@ e1000_is_onboard_nvm_eeprom(struct e1000
>  
>      DEBUGFUNC("e1000_is_onboard_nvm_eeprom");
>  
> -    if(hw->mac_type == e1000_82573) {
> +    if (hw->mac_type == e1000_ich8lan)
> +        return FALSE;
> +
> +    if (hw->mac_type == e1000_82573) {
>          eecd = E1000_READ_REG(hw, EECD);
>  
>          /* Isolate bits 15 & 16 */
> @@ -4862,8 +5068,22 @@ e1000_validate_eeprom_checksum(struct e1
>          }
>      }
>  
> -    for(i = 0; i < (EEPROM_CHECKSUM_REG + 1); i++) {
> -        if(e1000_read_eeprom(hw, i, 1, &eeprom_data) < 0) {
> +    if (hw->mac_type == e1000_ich8lan) {
> +        /* Drivers must allocate the shadow ram structure for the
> +         * EEPROM checksum to be updated.  Otherwise, this bit as well
> +         * as the checksum must both be set correctly for this
> +         * validation to pass.
> +         */
> +        e1000_read_eeprom(hw, 0x19, 1, &eeprom_data);
> +        if ((eeprom_data & 0x40) == 0) {
> +            eeprom_data |= 0x40;
> +            e1000_write_eeprom(hw, 0x19, 1, &eeprom_data);
> +            e1000_update_eeprom_checksum(hw);
> +        }
> +    }
> +
> +    for (i = 0; i < (EEPROM_CHECKSUM_REG + 1); i++) {
> +        if (e1000_read_eeprom(hw, i, 1, &eeprom_data) < 0) {
>              DEBUGOUT("EEPROM Read Error\n");
>              return -E1000_ERR_EEPROM;
>          }
> @@ -4889,6 +5109,7 @@ e1000_validate_eeprom_checksum(struct e1
>  int32_t
>  e1000_update_eeprom_checksum(struct e1000_hw *hw)
>  {
> +    uint32_t ctrl_ext;
>      uint16_t checksum = 0;
>      uint16_t i, eeprom_data;
>  
> @@ -4907,6 +5128,14 @@ e1000_update_eeprom_checksum(struct e100
>          return -E1000_ERR_EEPROM;
>      } else if (hw->eeprom.type == e1000_eeprom_flash) {
>          e1000_commit_shadow_ram(hw);
> +    } else if (hw->eeprom.type == e1000_eeprom_ich8) {
> +        e1000_commit_shadow_ram(hw);
> +        /* Reload the EEPROM, or else modifications will not appear
> +         * until after next adapter reset. */
> +        ctrl_ext = E1000_READ_REG(hw, CTRL_EXT);
> +        ctrl_ext |= E1000_CTRL_EXT_EE_RST;
> +        E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext);
> +        msec_delay(10);
>      }
>      return E1000_SUCCESS;
>  }
> @@ -4946,6 +5175,9 @@ e1000_write_eeprom(struct e1000_hw *hw,
>      if(eeprom->use_eewr == TRUE)
>          return e1000_write_eeprom_eewr(hw, offset, words, data);
>  
> +    if (eeprom->type == e1000_eeprom_ich8)
> +        return e1000_write_eeprom_ich8(hw, offset, words, data);
> +
>      /* Prepare the EEPROM for writing  */
>      if (e1000_acquire_eeprom(hw) != E1000_SUCCESS)
>          return -E1000_ERR_EEPROM;
> @@ -5133,11 +5365,17 @@ e1000_commit_shadow_ram(struct e1000_hw 
>      uint32_t flop = 0;
>      uint32_t i = 0;
>      int32_t error = E1000_SUCCESS;
> -
> -    /* The flop register will be used to determine if flash type is STM */
> -    flop = E1000_READ_REG(hw, FLOP);
> +    uint32_t old_bank_offset = 0;
> +    uint32_t new_bank_offset = 0;
> +    uint32_t sector_retries = 0;
> +    uint8_t low_byte = 0;
> +    uint8_t high_byte = 0;
> +    uint8_t temp_byte = 0;
> +    boolean_t sector_write_failed = FALSE;
>  
>      if (hw->mac_type == e1000_82573) {
> +        /* The flop register will be used to determine if flash type is STM */
> +        flop = E1000_READ_REG(hw, FLOP);
>          for (i=0; i < attempts; i++) {
>              eecd = E1000_READ_REG(hw, EECD);
>              if ((eecd & E1000_EECD_FLUPD) == 0) {
> @@ -5171,6 +5409,106 @@ e1000_commit_shadow_ram(struct e1000_hw 
>          }
>      }
>  
> +    if (hw->mac_type == e1000_ich8lan && hw->eeprom_shadow_ram != NULL) {
> +        /* 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 */
> +        if (!(E1000_READ_REG(hw, EECD) & E1000_EECD_SEC1VAL)) {
> +            new_bank_offset = hw->flash_bank_size * 2;
> +            old_bank_offset = 0;
> +            e1000_erase_ich8_4k_segment(hw, 1);
> +        } else {
> +            old_bank_offset = hw->flash_bank_size * 2;
> +            new_bank_offset = 0;
> +            e1000_erase_ich8_4k_segment(hw, 0);
> +        }
> +
> +        do {
> +            sector_write_failed = FALSE;
> +            /* Loop for every byte in the shadow RAM,
> +             * which is in units of words. */
> +            for (i = 0; i < E1000_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 (hw->eeprom_shadow_ram[i].modified == TRUE) {
> +                    low_byte = (uint8_t)hw->eeprom_shadow_ram[i].eeprom_word;
> +                    e1000_read_ich8_byte(hw, (i << 1) + old_bank_offset,
> +                                         &temp_byte);
> +                    udelay(100);
> +                    error = e1000_verify_write_ich8_byte(hw,
> +                                                 (i << 1) + new_bank_offset,
> +                                                 low_byte);
> +                    if (error != E1000_SUCCESS)
> +                        sector_write_failed = TRUE;
> +                    high_byte =
> +                        (uint8_t)(hw->eeprom_shadow_ram[i].eeprom_word >> 8);
> +                    e1000_read_ich8_byte(hw, (i << 1) + old_bank_offset + 1,
> +                                         &temp_byte);
> +                    udelay(100);
> +                } else {
> +                    e1000_read_ich8_byte(hw, (i << 1) + old_bank_offset,
> +                                         &low_byte);
> +                    udelay(100);
> +                    error = e1000_verify_write_ich8_byte(hw,
> +                                 (i << 1) + new_bank_offset, low_byte);
> +                    if (error != E1000_SUCCESS)
> +                        sector_write_failed = TRUE;
> +                    e1000_read_ich8_byte(hw, (i << 1) + old_bank_offset + 1,
> +                                         &high_byte);
> +                }
> +
> +                /* 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_ICH8_NVM_SIG_WORD)
> +                    high_byte = E1000_ICH8_NVM_SIG_MASK | high_byte;
> +
> +                error = e1000_verify_write_ich8_byte(hw,
> +                             (i << 1) + new_bank_offset + 1, high_byte);
> +                if (error != E1000_SUCCESS)
> +                    sector_write_failed = TRUE;
> +
> +                if (sector_write_failed == FALSE) {
> +                    /* Clear the now not used entry in the cache */
> +                    hw->eeprom_shadow_ram[i].modified = FALSE;
> +                    hw->eeprom_shadow_ram[i].eeprom_word = 0xFFFF;
> +                }
> +            }
> +
> +            /* Don't bother writing the segment valid bits if sector
> +             * programming failed. */
> +            if (sector_write_failed == FALSE) {
> +                /* 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 */
> +                e1000_read_ich8_byte(hw,
> +                    E1000_ICH8_NVM_SIG_WORD * 2 + 1 + new_bank_offset,
> +                    &high_byte);
> +                high_byte &= 0xBF;
> +                error = e1000_verify_write_ich8_byte(hw,
> +                            E1000_ICH8_NVM_SIG_WORD * 2 + 1 + new_bank_offset,
> +                            high_byte);
> +                if (error != E1000_SUCCESS)
> +                    sector_write_failed = TRUE;
> +
> +                /* 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 */
> +                error = e1000_verify_write_ich8_byte(hw,
> +                            E1000_ICH8_NVM_SIG_WORD * 2 + 1 + old_bank_offset,
> +                            0);
> +                if (error != E1000_SUCCESS)
> +                    sector_write_failed = TRUE;
> +            }
> +        } while (++sector_retries < 10 && sector_write_failed == TRUE);
> +    }
> +

obviously warrants a separate function for new ich8 code...




  reply	other threads:[~2006-06-27  1:54 UTC|newest]

Thread overview: 47+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2006-06-22  5:18 [PATCH 00/21] e1000: driver update to 7.1.9-k2 Kok, Auke
2006-06-22  5:20 ` [PATCH 01/21] e1000: fix loopback ethtool test Kok, Auke
2006-06-22  5:20 ` [PATCH 02/21] e1000: rework driver hardware reset locking Kok, Auke
2006-06-27  1:42   ` Jeff Garzik
2006-06-27 14:42     ` Auke Kok
2006-06-22  5:20 ` [PATCH 03/21] e1000: Make PHY powerup/down a function Kok, Auke
2006-06-22  5:20 ` [PATCH 04/21] e1000: fix CONFIG_PM blocks Kok, Auke
2006-06-22  5:20 ` [PATCH 05/21] e1000: small performance tweak by removing double code Kok, Auke
2006-06-22  5:20 ` [PATCH 06/21] e1000: add smart power down code Kok, Auke
2006-06-27  1:43   ` Jeff Garzik
2006-06-27  8:49     ` Florian Reitmeir
2006-06-27 14:40     ` Auke Kok
2006-06-22  5:20 ` [PATCH 07/21] e1000: change printk into DPRINTK Kok, Auke
2006-06-22  5:20 ` [PATCH 08/21] e1000: recycle skb Kok, Auke
2006-06-22  5:20 ` [PATCH 09/21] e1000: rework module param code with uninitialized values Kok, Auke
2006-06-22  5:20 ` [PATCH 10/21] e1000: force register write flushes to circumvent broken platforms Kok, Auke
2006-06-27  1:47   ` Jeff Garzik
2006-06-27 14:36     ` Auke Kok
2006-06-27 15:41       ` Jeff Garzik
2006-06-27 15:56       ` Auke Kok
2006-06-22  5:20 ` [PATCH 11/21] e1000: disable CRC stripping workaround Kok, Auke
2006-06-22  5:31   ` Ben Greear
2006-06-22 15:36     ` Auke Kok
2006-06-22 15:39     ` Jesse Brandeburg
2006-06-22 15:55       ` Ben Greear
2006-06-22 16:01         ` Jesse Brandeburg
2006-06-22 15:57       ` Lennert Buytenhek
2006-06-27  1:48   ` Jeff Garzik
2006-06-27 14:29     ` Auke Kok
2006-06-22  5:20 ` [PATCH 12/21] e1000: fix adapter led blinking inconsistency Kok, Auke
2006-06-22  5:20 ` [PATCH 13/21] e1000: add E1000_BIG_ENDIAN symbol Kok, Auke
2006-06-27  1:49   ` Jeff Garzik
2006-06-27 14:25     ` Auke Kok
2006-06-22  5:20 ` [PATCH 14/21] e1000: M88 PHY workaround Kok, Auke
2006-06-22  5:20 ` [PATCH 15/21] e1000: check return value of _get_speed_and_duplex Kok, Auke
2006-06-22  5:20 ` [PATCH 16/21] e1000: disable ERT Kok, Auke
2006-06-22  5:20 ` [PATCH 17/21] e1000: add ich8lan core functions Kok, Auke
2006-06-27  1:52   ` Jeff Garzik
2006-06-27 16:12     ` Auke Kok
2006-06-22  5:20 ` [PATCH 18/21] e1000: integrate ich8 support into driver Kok, Auke
2006-06-27  1:54   ` Jeff Garzik [this message]
2006-06-22  5:20 ` [PATCH 19/21] e1000: allow user to disable ich8 lock loss workaround Kok, Auke
2006-06-27  1:55   ` Jeff Garzik
2006-06-27 14:21     ` Auke Kok
2006-06-22  5:20 ` [PATCH 20/21] e1000: add ich8lan device ID's Kok, Auke
2006-06-22  5:20 ` [PATCH 21/21] e1000: increase version to 7.1.9-k2 Kok, Auke
2006-06-27 22:48 ` [PATCH 00/21] e1000: driver update " Auke Kok

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=44A08FDC.2080201@pobox.com \
    --to=jgarzik@pobox.com \
    --cc=auke-jan.h.kok@intel.com \
    --cc=auke@foo-projects.org \
    --cc=jesse.brandeburg@intel.com \
    --cc=john.ronciak@intel.com \
    --cc=netdev@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).