The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/em/e1000_nvm.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*******************************************************************************
    2 
    3   Copyright (c) 2001-2007, Intel Corporation 
    4   All rights reserved.
    5   
    6   Redistribution and use in source and binary forms, with or without 
    7   modification, are permitted provided that the following conditions are met:
    8   
    9    1. Redistributions of source code must retain the above copyright notice, 
   10       this list of conditions and the following disclaimer.
   11   
   12    2. Redistributions in binary form must reproduce the above copyright 
   13       notice, this list of conditions and the following disclaimer in the 
   14       documentation and/or other materials provided with the distribution.
   15   
   16    3. Neither the name of the Intel Corporation nor the names of its 
   17       contributors may be used to endorse or promote products derived from 
   18       this software without specific prior written permission.
   19   
   20   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
   21   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
   22   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
   23   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 
   24   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 
   25   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
   26   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
   27   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
   28   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
   29   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   30   POSSIBILITY OF SUCH DAMAGE.
   31 
   32 *******************************************************************************/
   33 /* $FreeBSD$ */
   34 
   35 
   36 #include "e1000_api.h"
   37 #include "e1000_nvm.h"
   38 
   39 /**
   40  *  e1000_raise_eec_clk - Raise EEPROM clock
   41  *  @hw: pointer to the HW structure
   42  *  @eecd: pointer to the EEPROM
   43  *
   44  *  Enable/Raise the EEPROM clock bit.
   45  **/
   46 static void e1000_raise_eec_clk(struct e1000_hw *hw, u32 *eecd)
   47 {
   48         *eecd = *eecd | E1000_EECD_SK;
   49         E1000_WRITE_REG(hw, E1000_EECD, *eecd);
   50         E1000_WRITE_FLUSH(hw);
   51         usec_delay(hw->nvm.delay_usec);
   52 }
   53 
   54 /**
   55  *  e1000_lower_eec_clk - Lower EEPROM clock
   56  *  @hw: pointer to the HW structure
   57  *  @eecd: pointer to the EEPROM
   58  *
   59  *  Clear/Lower the EEPROM clock bit.
   60  **/
   61 static void e1000_lower_eec_clk(struct e1000_hw *hw, u32 *eecd)
   62 {
   63         *eecd = *eecd & ~E1000_EECD_SK;
   64         E1000_WRITE_REG(hw, E1000_EECD, *eecd);
   65         E1000_WRITE_FLUSH(hw);
   66         usec_delay(hw->nvm.delay_usec);
   67 }
   68 
   69 /**
   70  *  e1000_shift_out_eec_bits - Shift data bits our to the EEPROM
   71  *  @hw: pointer to the HW structure
   72  *  @data: data to send to the EEPROM
   73  *  @count: number of bits to shift out
   74  *
   75  *  We need to shift 'count' bits out to the EEPROM.  So, the value in the
   76  *  "data" parameter will be shifted out to the EEPROM one bit at a time.
   77  *  In order to do this, "data" must be broken down into bits.
   78  **/
   79 static void e1000_shift_out_eec_bits(struct e1000_hw *hw, u16 data, u16 count)
   80 {
   81         struct e1000_nvm_info *nvm = &hw->nvm;
   82         u32 eecd = E1000_READ_REG(hw, E1000_EECD);
   83         u32 mask;
   84 
   85         DEBUGFUNC("e1000_shift_out_eec_bits");
   86 
   87         mask = 0x01 << (count - 1);
   88         if (nvm->type == e1000_nvm_eeprom_microwire)
   89                 eecd &= ~E1000_EECD_DO;
   90         else if (nvm->type == e1000_nvm_eeprom_spi)
   91                 eecd |= E1000_EECD_DO;
   92 
   93         do {
   94                 eecd &= ~E1000_EECD_DI;
   95 
   96                 if (data & mask)
   97                         eecd |= E1000_EECD_DI;
   98 
   99                 E1000_WRITE_REG(hw, E1000_EECD, eecd);
  100                 E1000_WRITE_FLUSH(hw);
  101 
  102                 usec_delay(nvm->delay_usec);
  103 
  104                 e1000_raise_eec_clk(hw, &eecd);
  105                 e1000_lower_eec_clk(hw, &eecd);
  106 
  107                 mask >>= 1;
  108         } while (mask);
  109 
  110         eecd &= ~E1000_EECD_DI;
  111         E1000_WRITE_REG(hw, E1000_EECD, eecd);
  112 }
  113 
  114 /**
  115  *  e1000_shift_in_eec_bits - Shift data bits in from the EEPROM
  116  *  @hw: pointer to the HW structure
  117  *  @count: number of bits to shift in
  118  *
  119  *  In order to read a register from the EEPROM, we need to shift 'count' bits
  120  *  in from the EEPROM.  Bits are "shifted in" by raising the clock input to
  121  *  the EEPROM (setting the SK bit), and then reading the value of the data out
  122  *  "DO" bit.  During this "shifting in" process the data in "DI" bit should
  123  *  always be clear.
  124  **/
  125 static u16 e1000_shift_in_eec_bits(struct e1000_hw *hw, u16 count)
  126 {
  127         u32 eecd;
  128         u32 i;
  129         u16 data;
  130 
  131         DEBUGFUNC("e1000_shift_in_eec_bits");
  132 
  133         eecd = E1000_READ_REG(hw, E1000_EECD);
  134 
  135         eecd &= ~(E1000_EECD_DO | E1000_EECD_DI);
  136         data = 0;
  137 
  138         for (i = 0; i < count; i++) {
  139                 data <<= 1;
  140                 e1000_raise_eec_clk(hw, &eecd);
  141 
  142                 eecd = E1000_READ_REG(hw, E1000_EECD);
  143 
  144                 eecd &= ~E1000_EECD_DI;
  145                 if (eecd & E1000_EECD_DO)
  146                         data |= 1;
  147 
  148                 e1000_lower_eec_clk(hw, &eecd);
  149         }
  150 
  151         return data;
  152 }
  153 
  154 /**
  155  *  e1000_poll_eerd_eewr_done - Poll for EEPROM read/write completion
  156  *  @hw: pointer to the HW structure
  157  *  @ee_reg: EEPROM flag for polling
  158  *
  159  *  Polls the EEPROM status bit for either read or write completion based
  160  *  upon the value of 'ee_reg'.
  161  **/
  162 s32 e1000_poll_eerd_eewr_done(struct e1000_hw *hw, int ee_reg)
  163 {
  164         u32 attempts = 100000;
  165         u32 i, reg = 0;
  166         s32 ret_val = -E1000_ERR_NVM;
  167 
  168         DEBUGFUNC("e1000_poll_eerd_eewr_done");
  169 
  170         for (i = 0; i < attempts; i++) {
  171                 if (ee_reg == E1000_NVM_POLL_READ)
  172                         reg = E1000_READ_REG(hw, E1000_EERD);
  173                 else
  174                         reg = E1000_READ_REG(hw, E1000_EEWR);
  175 
  176                 if (reg & E1000_NVM_RW_REG_DONE) {
  177                         ret_val = E1000_SUCCESS;
  178                         break;
  179                 }
  180 
  181                 usec_delay(5);
  182         }
  183 
  184         return ret_val;
  185 }
  186 
  187 /**
  188  *  e1000_acquire_nvm_generic - Generic request for access to EEPROM
  189  *  @hw: pointer to the HW structure
  190  *
  191  *  Set the EEPROM access request bit and wait for EEPROM access grant bit.
  192  *  Return successful if access grant bit set, else clear the request for
  193  *  EEPROM access and return -E1000_ERR_NVM (-1).
  194  **/
  195 s32 e1000_acquire_nvm_generic(struct e1000_hw *hw)
  196 {
  197         u32 eecd = E1000_READ_REG(hw, E1000_EECD);
  198         s32 timeout = E1000_NVM_GRANT_ATTEMPTS;
  199         s32 ret_val = E1000_SUCCESS;
  200 
  201         DEBUGFUNC("e1000_acquire_nvm_generic");
  202 
  203         E1000_WRITE_REG(hw, E1000_EECD, eecd | E1000_EECD_REQ);
  204         eecd = E1000_READ_REG(hw, E1000_EECD);
  205 
  206         while (timeout) {
  207                 if (eecd & E1000_EECD_GNT)
  208                         break;
  209                 usec_delay(5);
  210                 eecd = E1000_READ_REG(hw, E1000_EECD);
  211                 timeout--;
  212         }
  213 
  214         if (!timeout) {
  215                 eecd &= ~E1000_EECD_REQ;
  216                 E1000_WRITE_REG(hw, E1000_EECD, eecd);
  217                 DEBUGOUT("Could not acquire NVM grant\n");
  218                 ret_val = -E1000_ERR_NVM;
  219         }
  220 
  221         return ret_val;
  222 }
  223 
  224 /**
  225  *  e1000_standby_nvm - Return EEPROM to standby state
  226  *  @hw: pointer to the HW structure
  227  *
  228  *  Return the EEPROM to a standby state.
  229  **/
  230 static void e1000_standby_nvm(struct e1000_hw *hw)
  231 {
  232         struct e1000_nvm_info *nvm = &hw->nvm;
  233         u32 eecd = E1000_READ_REG(hw, E1000_EECD);
  234 
  235         DEBUGFUNC("e1000_standby_nvm");
  236 
  237         if (nvm->type == e1000_nvm_eeprom_microwire) {
  238                 eecd &= ~(E1000_EECD_CS | E1000_EECD_SK);
  239                 E1000_WRITE_REG(hw, E1000_EECD, eecd);
  240                 E1000_WRITE_FLUSH(hw);
  241                 usec_delay(nvm->delay_usec);
  242 
  243                 e1000_raise_eec_clk(hw, &eecd);
  244 
  245                 /* Select EEPROM */
  246                 eecd |= E1000_EECD_CS;
  247                 E1000_WRITE_REG(hw, E1000_EECD, eecd);
  248                 E1000_WRITE_FLUSH(hw);
  249                 usec_delay(nvm->delay_usec);
  250 
  251                 e1000_lower_eec_clk(hw, &eecd);
  252         } else if (nvm->type == e1000_nvm_eeprom_spi) {
  253                 /* Toggle CS to flush commands */
  254                 eecd |= E1000_EECD_CS;
  255                 E1000_WRITE_REG(hw, E1000_EECD, eecd);
  256                 E1000_WRITE_FLUSH(hw);
  257                 usec_delay(nvm->delay_usec);
  258                 eecd &= ~E1000_EECD_CS;
  259                 E1000_WRITE_REG(hw, E1000_EECD, eecd);
  260                 E1000_WRITE_FLUSH(hw);
  261                 usec_delay(nvm->delay_usec);
  262         }
  263 }
  264 
  265 /**
  266  *  e1000_stop_nvm - Terminate EEPROM command
  267  *  @hw: pointer to the HW structure
  268  *
  269  *  Terminates the current command by inverting the EEPROM's chip select pin.
  270  **/
  271 void e1000_stop_nvm(struct e1000_hw *hw)
  272 {
  273         u32 eecd;
  274 
  275         DEBUGFUNC("e1000_stop_nvm");
  276 
  277         eecd = E1000_READ_REG(hw, E1000_EECD);
  278         if (hw->nvm.type == e1000_nvm_eeprom_spi) {
  279                 /* Pull CS high */
  280                 eecd |= E1000_EECD_CS;
  281                 e1000_lower_eec_clk(hw, &eecd);
  282         } else if (hw->nvm.type == e1000_nvm_eeprom_microwire) {
  283                 /* CS on Microcwire is active-high */
  284                 eecd &= ~(E1000_EECD_CS | E1000_EECD_DI);
  285                 E1000_WRITE_REG(hw, E1000_EECD, eecd);
  286                 e1000_raise_eec_clk(hw, &eecd);
  287                 e1000_lower_eec_clk(hw, &eecd);
  288         }
  289 }
  290 
  291 /**
  292  *  e1000_release_nvm_generic - Release exclusive access to EEPROM
  293  *  @hw: pointer to the HW structure
  294  *
  295  *  Stop any current commands to the EEPROM and clear the EEPROM request bit.
  296  **/
  297 void e1000_release_nvm_generic(struct e1000_hw *hw)
  298 {
  299         u32 eecd;
  300 
  301         DEBUGFUNC("e1000_release_nvm_generic");
  302 
  303         e1000_stop_nvm(hw);
  304 
  305         eecd = E1000_READ_REG(hw, E1000_EECD);
  306         eecd &= ~E1000_EECD_REQ;
  307         E1000_WRITE_REG(hw, E1000_EECD, eecd);
  308 }
  309 
  310 /**
  311  *  e1000_ready_nvm_eeprom - Prepares EEPROM for read/write
  312  *  @hw: pointer to the HW structure
  313  *
  314  *  Setups the EEPROM for reading and writing.
  315  **/
  316 static s32 e1000_ready_nvm_eeprom(struct e1000_hw *hw)
  317 {
  318         struct e1000_nvm_info *nvm = &hw->nvm;
  319         u32 eecd = E1000_READ_REG(hw, E1000_EECD);
  320         s32 ret_val = E1000_SUCCESS;
  321         u16 timeout = 0;
  322         u8 spi_stat_reg;
  323 
  324         DEBUGFUNC("e1000_ready_nvm_eeprom");
  325 
  326         if (nvm->type == e1000_nvm_eeprom_microwire) {
  327                 /* Clear SK and DI */
  328                 eecd &= ~(E1000_EECD_DI | E1000_EECD_SK);
  329                 E1000_WRITE_REG(hw, E1000_EECD, eecd);
  330                 /* Set CS */
  331                 eecd |= E1000_EECD_CS;
  332                 E1000_WRITE_REG(hw, E1000_EECD, eecd);
  333         } else if (nvm->type == e1000_nvm_eeprom_spi) {
  334                 /* Clear SK and CS */
  335                 eecd &= ~(E1000_EECD_CS | E1000_EECD_SK);
  336                 E1000_WRITE_REG(hw, E1000_EECD, eecd);
  337                 usec_delay(1);
  338                 timeout = NVM_MAX_RETRY_SPI;
  339 
  340                 /*
  341                  * Read "Status Register" repeatedly until the LSB is cleared.
  342                  * The EEPROM will signal that the command has been completed
  343                  * by clearing bit 0 of the internal status register.  If it's
  344                  * not cleared within 'timeout', then error out.
  345                  */
  346                 while (timeout) {
  347                         e1000_shift_out_eec_bits(hw, NVM_RDSR_OPCODE_SPI,
  348                                                  hw->nvm.opcode_bits);
  349                         spi_stat_reg = (u8)e1000_shift_in_eec_bits(hw, 8);
  350                         if (!(spi_stat_reg & NVM_STATUS_RDY_SPI))
  351                                 break;
  352 
  353                         usec_delay(5);
  354                         e1000_standby_nvm(hw);
  355                         timeout--;
  356                 }
  357 
  358                 if (!timeout) {
  359                         DEBUGOUT("SPI NVM Status error\n");
  360                         ret_val = -E1000_ERR_NVM;
  361                         goto out;
  362                 }
  363         }
  364 
  365 out:
  366         return ret_val;
  367 }
  368 
  369 /**
  370  *  e1000_read_nvm_spi - Read EEPROM's using SPI
  371  *  @hw: pointer to the HW structure
  372  *  @offset: offset of word in the EEPROM to read
  373  *  @words: number of words to read
  374  *  @data: word read from the EEPROM
  375  *
  376  *  Reads a 16 bit word from the EEPROM.
  377  **/
  378 s32 e1000_read_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
  379 {
  380         struct e1000_nvm_info *nvm = &hw->nvm;
  381         u32 i = 0;
  382         s32 ret_val;
  383         u16 word_in;
  384         u8 read_opcode = NVM_READ_OPCODE_SPI;
  385 
  386         DEBUGFUNC("e1000_read_nvm_spi");
  387 
  388         /*
  389          * A check for invalid values:  offset too large, too many words,
  390          * and not enough words.
  391          */
  392         if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) ||
  393             (words == 0)) {
  394                 DEBUGOUT("nvm parameter(s) out of bounds\n");
  395                 ret_val = -E1000_ERR_NVM;
  396                 goto out;
  397         }
  398 
  399         ret_val = e1000_acquire_nvm(hw);
  400         if (ret_val)
  401                 goto out;
  402 
  403         ret_val = e1000_ready_nvm_eeprom(hw);
  404         if (ret_val)
  405                 goto release;
  406 
  407         e1000_standby_nvm(hw);
  408 
  409         if ((nvm->address_bits == 8) && (offset >= 128))
  410                 read_opcode |= NVM_A8_OPCODE_SPI;
  411 
  412         /* Send the READ command (opcode + addr) */
  413         e1000_shift_out_eec_bits(hw, read_opcode, nvm->opcode_bits);
  414         e1000_shift_out_eec_bits(hw, (u16)(offset*2), nvm->address_bits);
  415 
  416         /*
  417          * Read the data.  SPI NVMs increment the address with each byte
  418          * read and will roll over if reading beyond the end.  This allows
  419          * us to read the whole NVM from any offset
  420          */
  421         for (i = 0; i < words; i++) {
  422                 word_in = e1000_shift_in_eec_bits(hw, 16);
  423                 data[i] = (word_in >> 8) | (word_in << 8);
  424         }
  425 
  426 release:
  427         e1000_release_nvm(hw);
  428 
  429 out:
  430         return ret_val;
  431 }
  432 
  433 /**
  434  *  e1000_read_nvm_microwire - Reads EEPROM's using microwire
  435  *  @hw: pointer to the HW structure
  436  *  @offset: offset of word in the EEPROM to read
  437  *  @words: number of words to read
  438  *  @data: word read from the EEPROM
  439  *
  440  *  Reads a 16 bit word from the EEPROM.
  441  **/
  442 s32 e1000_read_nvm_microwire(struct e1000_hw *hw, u16 offset, u16 words,
  443                              u16 *data)
  444 {
  445         struct e1000_nvm_info *nvm = &hw->nvm;
  446         u32 i = 0;
  447         s32 ret_val;
  448         u8 read_opcode = NVM_READ_OPCODE_MICROWIRE;
  449 
  450         DEBUGFUNC("e1000_read_nvm_microwire");
  451 
  452         /*
  453          * A check for invalid values:  offset too large, too many words,
  454          * and not enough words.
  455          */
  456         if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) ||
  457             (words == 0)) {
  458                 DEBUGOUT("nvm parameter(s) out of bounds\n");
  459                 ret_val = -E1000_ERR_NVM;
  460                 goto out;
  461         }
  462 
  463         ret_val = e1000_acquire_nvm(hw);
  464         if (ret_val)
  465                 goto out;
  466 
  467         ret_val = e1000_ready_nvm_eeprom(hw);
  468         if (ret_val)
  469                 goto release;
  470 
  471         for (i = 0; i < words; i++) {
  472                 /* Send the READ command (opcode + addr) */
  473                 e1000_shift_out_eec_bits(hw, read_opcode, nvm->opcode_bits);
  474                 e1000_shift_out_eec_bits(hw, (u16)(offset + i),
  475                                         nvm->address_bits);
  476 
  477                 /*
  478                  * Read the data.  For microwire, each word requires the
  479                  * overhead of setup and tear-down.
  480                  */
  481                 data[i] = e1000_shift_in_eec_bits(hw, 16);
  482                 e1000_standby_nvm(hw);
  483         }
  484 
  485 release:
  486         e1000_release_nvm(hw);
  487 
  488 out:
  489         return ret_val;
  490 }
  491 
  492 /**
  493  *  e1000_read_nvm_eerd - Reads EEPROM using EERD register
  494  *  @hw: pointer to the HW structure
  495  *  @offset: offset of word in the EEPROM to read
  496  *  @words: number of words to read
  497  *  @data: word read from the EEPROM
  498  *
  499  *  Reads a 16 bit word from the EEPROM using the EERD register.
  500  **/
  501 s32 e1000_read_nvm_eerd(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
  502 {
  503         struct e1000_nvm_info *nvm = &hw->nvm;
  504         u32 i, eerd = 0;
  505         s32 ret_val = E1000_SUCCESS;
  506 
  507         DEBUGFUNC("e1000_read_nvm_eerd");
  508 
  509         /*
  510          * A check for invalid values:  offset too large, too many words,
  511          * and not enough words.
  512          */
  513         if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) ||
  514             (words == 0)) {
  515                 DEBUGOUT("nvm parameter(s) out of bounds\n");
  516                 ret_val = -E1000_ERR_NVM;
  517                 goto out;
  518         }
  519 
  520         for (i = 0; i < words; i++) {
  521                 eerd = ((offset+i) << E1000_NVM_RW_ADDR_SHIFT) +
  522                        E1000_NVM_RW_REG_START;
  523 
  524                 E1000_WRITE_REG(hw, E1000_EERD, eerd);
  525                 ret_val = e1000_poll_eerd_eewr_done(hw, E1000_NVM_POLL_READ);
  526                 if (ret_val)
  527                         break;
  528 
  529                 data[i] = (E1000_READ_REG(hw, E1000_EERD) >>
  530                            E1000_NVM_RW_REG_DATA);
  531         }
  532 
  533 out:
  534         return ret_val;
  535 }
  536 
  537 /**
  538  *  e1000_write_nvm_spi - Write to EEPROM using SPI
  539  *  @hw: pointer to the HW structure
  540  *  @offset: offset within the EEPROM to be written to
  541  *  @words: number of words to write
  542  *  @data: 16 bit word(s) to be written to the EEPROM
  543  *
  544  *  Writes data to EEPROM at offset using SPI interface.
  545  *
  546  *  If e1000_update_nvm_checksum is not called after this function , the
  547  *  EEPROM will most likley contain an invalid checksum.
  548  **/
  549 s32 e1000_write_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
  550 {
  551         struct e1000_nvm_info *nvm = &hw->nvm;
  552         s32 ret_val;
  553         u16 widx = 0;
  554 
  555         DEBUGFUNC("e1000_write_nvm_spi");
  556 
  557         /*
  558          * A check for invalid values:  offset too large, too many words,
  559          * and not enough words.
  560          */
  561         if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) ||
  562             (words == 0)) {
  563                 DEBUGOUT("nvm parameter(s) out of bounds\n");
  564                 ret_val = -E1000_ERR_NVM;
  565                 goto out;
  566         }
  567 
  568         ret_val = e1000_acquire_nvm(hw);
  569         if (ret_val)
  570                 goto out;
  571 
  572         msec_delay(10);
  573 
  574         while (widx < words) {
  575                 u8 write_opcode = NVM_WRITE_OPCODE_SPI;
  576 
  577                 ret_val = e1000_ready_nvm_eeprom(hw);
  578                 if (ret_val)
  579                         goto release;
  580 
  581                 e1000_standby_nvm(hw);
  582 
  583                 /* Send the WRITE ENABLE command (8 bit opcode) */
  584                 e1000_shift_out_eec_bits(hw, NVM_WREN_OPCODE_SPI,
  585                                          nvm->opcode_bits);
  586 
  587                 e1000_standby_nvm(hw);
  588 
  589                 /*
  590                  * Some SPI eeproms use the 8th address bit embedded in the
  591                  * opcode
  592                  */
  593                 if ((nvm->address_bits == 8) && (offset >= 128))
  594                         write_opcode |= NVM_A8_OPCODE_SPI;
  595 
  596                 /* Send the Write command (8-bit opcode + addr) */
  597                 e1000_shift_out_eec_bits(hw, write_opcode, nvm->opcode_bits);
  598                 e1000_shift_out_eec_bits(hw, (u16)((offset + widx) * 2),
  599                                          nvm->address_bits);
  600 
  601                 /* Loop to allow for up to whole page write of eeprom */
  602                 while (widx < words) {
  603                         u16 word_out = data[widx];
  604                         word_out = (word_out >> 8) | (word_out << 8);
  605                         e1000_shift_out_eec_bits(hw, word_out, 16);
  606                         widx++;
  607 
  608                         if ((((offset + widx) * 2) % nvm->page_size) == 0) {
  609                                 e1000_standby_nvm(hw);
  610                                 break;
  611                         }
  612                 }
  613         }
  614 
  615         msec_delay(10);
  616 release:
  617         e1000_release_nvm(hw);
  618 
  619 out:
  620         return ret_val;
  621 }
  622 
  623 /**
  624  *  e1000_write_nvm_microwire - Writes EEPROM using microwire
  625  *  @hw: pointer to the HW structure
  626  *  @offset: offset within the EEPROM to be written to
  627  *  @words: number of words to write
  628  *  @data: 16 bit word(s) to be written to the EEPROM
  629  *
  630  *  Writes data to EEPROM at offset using microwire interface.
  631  *
  632  *  If e1000_update_nvm_checksum is not called after this function , the
  633  *  EEPROM will most likley contain an invalid checksum.
  634  **/
  635 s32 e1000_write_nvm_microwire(struct e1000_hw *hw, u16 offset, u16 words,
  636                               u16 *data)
  637 {
  638         struct e1000_nvm_info *nvm = &hw->nvm;
  639         s32  ret_val;
  640         u32 eecd;
  641         u16 words_written = 0;
  642         u16 widx = 0;
  643 
  644         DEBUGFUNC("e1000_write_nvm_microwire");
  645 
  646         /*
  647          * A check for invalid values:  offset too large, too many words,
  648          * and not enough words.
  649          */
  650         if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) ||
  651             (words == 0)) {
  652                 DEBUGOUT("nvm parameter(s) out of bounds\n");
  653                 ret_val = -E1000_ERR_NVM;
  654                 goto out;
  655         }
  656 
  657         ret_val = e1000_acquire_nvm(hw);
  658         if (ret_val)
  659                 goto out;
  660 
  661         ret_val = e1000_ready_nvm_eeprom(hw);
  662         if (ret_val)
  663                 goto release;
  664 
  665         e1000_shift_out_eec_bits(hw, NVM_EWEN_OPCODE_MICROWIRE,
  666                                  (u16)(nvm->opcode_bits + 2));
  667 
  668         e1000_shift_out_eec_bits(hw, 0, (u16)(nvm->address_bits - 2));
  669 
  670         e1000_standby_nvm(hw);
  671 
  672         while (words_written < words) {
  673                 e1000_shift_out_eec_bits(hw, NVM_WRITE_OPCODE_MICROWIRE,
  674                                          nvm->opcode_bits);
  675 
  676                 e1000_shift_out_eec_bits(hw, (u16)(offset + words_written),
  677                                          nvm->address_bits);
  678 
  679                 e1000_shift_out_eec_bits(hw, data[words_written], 16);
  680 
  681                 e1000_standby_nvm(hw);
  682 
  683                 for (widx = 0; widx < 200; widx++) {
  684                         eecd = E1000_READ_REG(hw, E1000_EECD);
  685                         if (eecd & E1000_EECD_DO)
  686                                 break;
  687                         usec_delay(50);
  688                 }
  689 
  690                 if (widx == 200) {
  691                         DEBUGOUT("NVM Write did not complete\n");
  692                         ret_val = -E1000_ERR_NVM;
  693                         goto release;
  694                 }
  695 
  696                 e1000_standby_nvm(hw);
  697 
  698                 words_written++;
  699         }
  700 
  701         e1000_shift_out_eec_bits(hw, NVM_EWDS_OPCODE_MICROWIRE,
  702                                  (u16)(nvm->opcode_bits + 2));
  703 
  704         e1000_shift_out_eec_bits(hw, 0, (u16)(nvm->address_bits - 2));
  705 
  706 release:
  707         e1000_release_nvm(hw);
  708 
  709 out:
  710         return ret_val;
  711 }
  712 
  713 /**
  714  *  e1000_read_part_num_generic - Read device part number
  715  *  @hw: pointer to the HW structure
  716  *  @part_num: pointer to device part number
  717  *
  718  *  Reads the product board assembly (PBA) number from the EEPROM and stores
  719  *  the value in part_num.
  720  **/
  721 s32 e1000_read_part_num_generic(struct e1000_hw *hw, u32 *part_num)
  722 {
  723         s32  ret_val;
  724         u16 nvm_data;
  725 
  726         DEBUGFUNC("e1000_read_part_num_generic");
  727 
  728         ret_val = e1000_read_nvm(hw, NVM_PBA_OFFSET_0, 1, &nvm_data);
  729         if (ret_val) {
  730                 DEBUGOUT("NVM Read Error\n");
  731                 goto out;
  732         }
  733         *part_num = (u32)(nvm_data << 16);
  734 
  735         ret_val = e1000_read_nvm(hw, NVM_PBA_OFFSET_1, 1, &nvm_data);
  736         if (ret_val) {
  737                 DEBUGOUT("NVM Read Error\n");
  738                 goto out;
  739         }
  740         *part_num |= nvm_data;
  741 
  742 out:
  743         return ret_val;
  744 }
  745 
  746 /**
  747  *  e1000_read_mac_addr_generic - Read device MAC address
  748  *  @hw: pointer to the HW structure
  749  *
  750  *  Reads the device MAC address from the EEPROM and stores the value.
  751  *  Since devices with two ports use the same EEPROM, we increment the
  752  *  last bit in the MAC address for the second port.
  753  **/
  754 s32 e1000_read_mac_addr_generic(struct e1000_hw *hw)
  755 {
  756         s32  ret_val = E1000_SUCCESS;
  757         u16 offset, nvm_data, i;
  758 
  759         DEBUGFUNC("e1000_read_mac_addr");
  760 
  761         for (i = 0; i < ETH_ADDR_LEN; i += 2) {
  762                 offset = i >> 1;
  763                 ret_val = e1000_read_nvm(hw, offset, 1, &nvm_data);
  764                 if (ret_val) {
  765                         DEBUGOUT("NVM Read Error\n");
  766                         goto out;
  767                 }
  768                 hw->mac.perm_addr[i] = (u8)(nvm_data & 0xFF);
  769                 hw->mac.perm_addr[i+1] = (u8)(nvm_data >> 8);
  770         }
  771 
  772         /* Flip last bit of mac address if we're on second port */
  773         if (hw->bus.func == E1000_FUNC_1)
  774                 hw->mac.perm_addr[5] ^= 1;
  775 
  776         for (i = 0; i < ETH_ADDR_LEN; i++)
  777                 hw->mac.addr[i] = hw->mac.perm_addr[i];
  778 
  779 out:
  780         return ret_val;
  781 }
  782 
  783 /**
  784  *  e1000_validate_nvm_checksum_generic - Validate EEPROM checksum
  785  *  @hw: pointer to the HW structure
  786  *
  787  *  Calculates the EEPROM checksum by reading/adding each word of the EEPROM
  788  *  and then verifies that the sum of the EEPROM is equal to 0xBABA.
  789  **/
  790 s32 e1000_validate_nvm_checksum_generic(struct e1000_hw *hw)
  791 {
  792         s32 ret_val = E1000_SUCCESS;
  793         u16 checksum = 0;
  794         u16 i, nvm_data;
  795 
  796         DEBUGFUNC("e1000_validate_nvm_checksum_generic");
  797 
  798         for (i = 0; i < (NVM_CHECKSUM_REG + 1); i++) {
  799                 ret_val = e1000_read_nvm(hw, i, 1, &nvm_data);
  800                 if (ret_val) {
  801                         DEBUGOUT("NVM Read Error\n");
  802                         goto out;
  803                 }
  804                 checksum += nvm_data;
  805         }
  806 
  807         if (checksum != (u16) NVM_SUM) {
  808                 DEBUGOUT("NVM Checksum Invalid\n");
  809                 ret_val = -E1000_ERR_NVM;
  810                 goto out;
  811         }
  812 
  813 out:
  814         return ret_val;
  815 }
  816 
  817 /**
  818  *  e1000_update_nvm_checksum_generic - Update EEPROM checksum
  819  *  @hw: pointer to the HW structure
  820  *
  821  *  Updates the EEPROM checksum by reading/adding each word of the EEPROM
  822  *  up to the checksum.  Then calculates the EEPROM checksum and writes the
  823  *  value to the EEPROM.
  824  **/
  825 s32 e1000_update_nvm_checksum_generic(struct e1000_hw *hw)
  826 {
  827         s32  ret_val;
  828         u16 checksum = 0;
  829         u16 i, nvm_data;
  830 
  831         DEBUGFUNC("e1000_update_nvm_checksum");
  832 
  833         for (i = 0; i < NVM_CHECKSUM_REG; i++) {
  834                 ret_val = e1000_read_nvm(hw, i, 1, &nvm_data);
  835                 if (ret_val) {
  836                         DEBUGOUT("NVM Read Error while updating checksum.\n");
  837                         goto out;
  838                 }
  839                 checksum += nvm_data;
  840         }
  841         checksum = (u16) NVM_SUM - checksum;
  842         ret_val = e1000_write_nvm(hw, NVM_CHECKSUM_REG, 1, &checksum);
  843         if (ret_val) {
  844                 DEBUGOUT("NVM Write Error while updating checksum.\n");
  845         }
  846 
  847 out:
  848         return ret_val;
  849 }
  850 
  851 /**
  852  *  e1000_reload_nvm_generic - Reloads EEPROM
  853  *  @hw: pointer to the HW structure
  854  *
  855  *  Reloads the EEPROM by setting the "Reinitialize from EEPROM" bit in the
  856  *  extended control register.
  857  **/
  858 void e1000_reload_nvm_generic(struct e1000_hw *hw)
  859 {
  860         u32 ctrl_ext;
  861 
  862         DEBUGFUNC("e1000_reload_nvm_generic");
  863 
  864         usec_delay(10);
  865         ctrl_ext = E1000_READ_REG(hw, E1000_CTRL_EXT);
  866         ctrl_ext |= E1000_CTRL_EXT_EE_RST;
  867         E1000_WRITE_REG(hw, E1000_CTRL_EXT, ctrl_ext);
  868         E1000_WRITE_FLUSH(hw);
  869 }
  870 
  871 /* Function pointers local to this file and not intended for public use */
  872 
  873 /**
  874  *  e1000_acquire_nvm - Acquire exclusive access to EEPROM
  875  *  @hw: pointer to the HW structure
  876  *
  877  *  For those silicon families which have implemented a NVM acquire function,
  878  *  run the defined function else return success.
  879  **/
  880 s32 e1000_acquire_nvm(struct e1000_hw *hw)
  881 {
  882         if (hw->func.acquire_nvm)
  883                 return hw->func.acquire_nvm(hw);
  884 
  885         return E1000_SUCCESS;
  886 }
  887 
  888 /**
  889  *  e1000_release_nvm - Release exclusive access to EEPROM
  890  *  @hw: pointer to the HW structure
  891  *
  892  *  For those silicon families which have implemented a NVM release function,
  893  *  run the defined fucntion else return success.
  894  **/
  895 void e1000_release_nvm(struct e1000_hw *hw)
  896 {
  897         if (hw->func.release_nvm)
  898                 hw->func.release_nvm(hw);
  899 }
  900 

Cache object: c5bdd797c5d6161570ac37227493326f


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.