175eba5b6SRobert Mustacchi /****************************************************************************** 275eba5b6SRobert Mustacchi 3*42cc51e0SRobert Mustacchi Copyright (c) 2001-2015, Intel Corporation 475eba5b6SRobert Mustacchi All rights reserved. 575eba5b6SRobert Mustacchi 675eba5b6SRobert Mustacchi Redistribution and use in source and binary forms, with or without 775eba5b6SRobert Mustacchi modification, are permitted provided that the following conditions are met: 875eba5b6SRobert Mustacchi 975eba5b6SRobert Mustacchi 1. Redistributions of source code must retain the above copyright notice, 1075eba5b6SRobert Mustacchi this list of conditions and the following disclaimer. 1175eba5b6SRobert Mustacchi 1275eba5b6SRobert Mustacchi 2. Redistributions in binary form must reproduce the above copyright 1375eba5b6SRobert Mustacchi notice, this list of conditions and the following disclaimer in the 1475eba5b6SRobert Mustacchi documentation and/or other materials provided with the distribution. 1575eba5b6SRobert Mustacchi 1675eba5b6SRobert Mustacchi 3. Neither the name of the Intel Corporation nor the names of its 1775eba5b6SRobert Mustacchi contributors may be used to endorse or promote products derived from 1875eba5b6SRobert Mustacchi this software without specific prior written permission. 1975eba5b6SRobert Mustacchi 2075eba5b6SRobert Mustacchi THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 2175eba5b6SRobert Mustacchi AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2275eba5b6SRobert Mustacchi IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2375eba5b6SRobert Mustacchi ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 2475eba5b6SRobert Mustacchi LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 2575eba5b6SRobert Mustacchi CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 2675eba5b6SRobert Mustacchi SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 2775eba5b6SRobert Mustacchi INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 2875eba5b6SRobert Mustacchi CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 2975eba5b6SRobert Mustacchi ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 3075eba5b6SRobert Mustacchi POSSIBILITY OF SUCH DAMAGE. 3175eba5b6SRobert Mustacchi 3275eba5b6SRobert Mustacchi ******************************************************************************/ 3375eba5b6SRobert Mustacchi /*$FreeBSD$*/ 3475eba5b6SRobert Mustacchi 3575eba5b6SRobert Mustacchi #include "e1000_api.h" 3675eba5b6SRobert Mustacchi 3775eba5b6SRobert Mustacchi static void e1000_reload_nvm_generic(struct e1000_hw *hw); 3875eba5b6SRobert Mustacchi 3975eba5b6SRobert Mustacchi /** 4075eba5b6SRobert Mustacchi * e1000_init_nvm_ops_generic - Initialize NVM function pointers 4175eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 4275eba5b6SRobert Mustacchi * 4375eba5b6SRobert Mustacchi * Setups up the function pointers to no-op functions 4475eba5b6SRobert Mustacchi **/ 4575eba5b6SRobert Mustacchi void e1000_init_nvm_ops_generic(struct e1000_hw *hw) 4675eba5b6SRobert Mustacchi { 4775eba5b6SRobert Mustacchi struct e1000_nvm_info *nvm = &hw->nvm; 4875eba5b6SRobert Mustacchi DEBUGFUNC("e1000_init_nvm_ops_generic"); 4975eba5b6SRobert Mustacchi 5075eba5b6SRobert Mustacchi /* Initialize function pointers */ 5175eba5b6SRobert Mustacchi nvm->ops.init_params = e1000_null_ops_generic; 5275eba5b6SRobert Mustacchi nvm->ops.acquire = e1000_null_ops_generic; 5375eba5b6SRobert Mustacchi nvm->ops.read = e1000_null_read_nvm; 5475eba5b6SRobert Mustacchi nvm->ops.release = e1000_null_nvm_generic; 5575eba5b6SRobert Mustacchi nvm->ops.reload = e1000_reload_nvm_generic; 5675eba5b6SRobert Mustacchi nvm->ops.update = e1000_null_ops_generic; 5775eba5b6SRobert Mustacchi nvm->ops.valid_led_default = e1000_null_led_default; 5875eba5b6SRobert Mustacchi nvm->ops.validate = e1000_null_ops_generic; 5975eba5b6SRobert Mustacchi nvm->ops.write = e1000_null_write_nvm; 6075eba5b6SRobert Mustacchi } 6175eba5b6SRobert Mustacchi 6275eba5b6SRobert Mustacchi /** 6375eba5b6SRobert Mustacchi * e1000_null_nvm_read - No-op function, return 0 6475eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 6575eba5b6SRobert Mustacchi **/ 66c124a83eSRobert Mustacchi s32 e1000_null_read_nvm(struct e1000_hw E1000_UNUSEDARG *hw, 67c124a83eSRobert Mustacchi u16 E1000_UNUSEDARG a, u16 E1000_UNUSEDARG b, 68c124a83eSRobert Mustacchi u16 E1000_UNUSEDARG *c) 6975eba5b6SRobert Mustacchi { 7075eba5b6SRobert Mustacchi DEBUGFUNC("e1000_null_read_nvm"); 7175eba5b6SRobert Mustacchi return E1000_SUCCESS; 7275eba5b6SRobert Mustacchi } 7375eba5b6SRobert Mustacchi 7475eba5b6SRobert Mustacchi /** 7575eba5b6SRobert Mustacchi * e1000_null_nvm_generic - No-op function, return void 7675eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 7775eba5b6SRobert Mustacchi **/ 78c124a83eSRobert Mustacchi void e1000_null_nvm_generic(struct e1000_hw E1000_UNUSEDARG *hw) 7975eba5b6SRobert Mustacchi { 8075eba5b6SRobert Mustacchi DEBUGFUNC("e1000_null_nvm_generic"); 8175eba5b6SRobert Mustacchi return; 8275eba5b6SRobert Mustacchi } 8375eba5b6SRobert Mustacchi 8475eba5b6SRobert Mustacchi /** 8575eba5b6SRobert Mustacchi * e1000_null_led_default - No-op function, return 0 8675eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 8775eba5b6SRobert Mustacchi **/ 88c124a83eSRobert Mustacchi s32 e1000_null_led_default(struct e1000_hw E1000_UNUSEDARG *hw, 89c124a83eSRobert Mustacchi u16 E1000_UNUSEDARG *data) 9075eba5b6SRobert Mustacchi { 9175eba5b6SRobert Mustacchi DEBUGFUNC("e1000_null_led_default"); 9275eba5b6SRobert Mustacchi return E1000_SUCCESS; 9375eba5b6SRobert Mustacchi } 9475eba5b6SRobert Mustacchi 9575eba5b6SRobert Mustacchi /** 9675eba5b6SRobert Mustacchi * e1000_null_write_nvm - No-op function, return 0 9775eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 9875eba5b6SRobert Mustacchi **/ 99c124a83eSRobert Mustacchi s32 e1000_null_write_nvm(struct e1000_hw E1000_UNUSEDARG *hw, 100c124a83eSRobert Mustacchi u16 E1000_UNUSEDARG a, u16 E1000_UNUSEDARG b, 101c124a83eSRobert Mustacchi u16 E1000_UNUSEDARG *c) 10275eba5b6SRobert Mustacchi { 10375eba5b6SRobert Mustacchi DEBUGFUNC("e1000_null_write_nvm"); 10475eba5b6SRobert Mustacchi return E1000_SUCCESS; 10575eba5b6SRobert Mustacchi } 10675eba5b6SRobert Mustacchi 10775eba5b6SRobert Mustacchi /** 10875eba5b6SRobert Mustacchi * e1000_raise_eec_clk - Raise EEPROM clock 10975eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 11075eba5b6SRobert Mustacchi * @eecd: pointer to the EEPROM 11175eba5b6SRobert Mustacchi * 11275eba5b6SRobert Mustacchi * Enable/Raise the EEPROM clock bit. 11375eba5b6SRobert Mustacchi **/ 11475eba5b6SRobert Mustacchi static void e1000_raise_eec_clk(struct e1000_hw *hw, u32 *eecd) 11575eba5b6SRobert Mustacchi { 11675eba5b6SRobert Mustacchi *eecd = *eecd | E1000_EECD_SK; 11775eba5b6SRobert Mustacchi E1000_WRITE_REG(hw, E1000_EECD, *eecd); 11875eba5b6SRobert Mustacchi E1000_WRITE_FLUSH(hw); 11975eba5b6SRobert Mustacchi usec_delay(hw->nvm.delay_usec); 12075eba5b6SRobert Mustacchi } 12175eba5b6SRobert Mustacchi 12275eba5b6SRobert Mustacchi /** 12375eba5b6SRobert Mustacchi * e1000_lower_eec_clk - Lower EEPROM clock 12475eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 12575eba5b6SRobert Mustacchi * @eecd: pointer to the EEPROM 12675eba5b6SRobert Mustacchi * 12775eba5b6SRobert Mustacchi * Clear/Lower the EEPROM clock bit. 12875eba5b6SRobert Mustacchi **/ 12975eba5b6SRobert Mustacchi static void e1000_lower_eec_clk(struct e1000_hw *hw, u32 *eecd) 13075eba5b6SRobert Mustacchi { 13175eba5b6SRobert Mustacchi *eecd = *eecd & ~E1000_EECD_SK; 13275eba5b6SRobert Mustacchi E1000_WRITE_REG(hw, E1000_EECD, *eecd); 13375eba5b6SRobert Mustacchi E1000_WRITE_FLUSH(hw); 13475eba5b6SRobert Mustacchi usec_delay(hw->nvm.delay_usec); 13575eba5b6SRobert Mustacchi } 13675eba5b6SRobert Mustacchi 13775eba5b6SRobert Mustacchi /** 13875eba5b6SRobert Mustacchi * e1000_shift_out_eec_bits - Shift data bits our to the EEPROM 13975eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 14075eba5b6SRobert Mustacchi * @data: data to send to the EEPROM 14175eba5b6SRobert Mustacchi * @count: number of bits to shift out 14275eba5b6SRobert Mustacchi * 14375eba5b6SRobert Mustacchi * We need to shift 'count' bits out to the EEPROM. So, the value in the 14475eba5b6SRobert Mustacchi * "data" parameter will be shifted out to the EEPROM one bit at a time. 14575eba5b6SRobert Mustacchi * In order to do this, "data" must be broken down into bits. 14675eba5b6SRobert Mustacchi **/ 14775eba5b6SRobert Mustacchi static void e1000_shift_out_eec_bits(struct e1000_hw *hw, u16 data, u16 count) 14875eba5b6SRobert Mustacchi { 14975eba5b6SRobert Mustacchi struct e1000_nvm_info *nvm = &hw->nvm; 15075eba5b6SRobert Mustacchi u32 eecd = E1000_READ_REG(hw, E1000_EECD); 15175eba5b6SRobert Mustacchi u32 mask; 15275eba5b6SRobert Mustacchi 15375eba5b6SRobert Mustacchi DEBUGFUNC("e1000_shift_out_eec_bits"); 15475eba5b6SRobert Mustacchi 15575eba5b6SRobert Mustacchi mask = 0x01 << (count - 1); 15675eba5b6SRobert Mustacchi if (nvm->type == e1000_nvm_eeprom_microwire) 15775eba5b6SRobert Mustacchi eecd &= ~E1000_EECD_DO; 15875eba5b6SRobert Mustacchi else 15975eba5b6SRobert Mustacchi if (nvm->type == e1000_nvm_eeprom_spi) 16075eba5b6SRobert Mustacchi eecd |= E1000_EECD_DO; 16175eba5b6SRobert Mustacchi 16275eba5b6SRobert Mustacchi do { 16375eba5b6SRobert Mustacchi eecd &= ~E1000_EECD_DI; 16475eba5b6SRobert Mustacchi 16575eba5b6SRobert Mustacchi if (data & mask) 16675eba5b6SRobert Mustacchi eecd |= E1000_EECD_DI; 16775eba5b6SRobert Mustacchi 16875eba5b6SRobert Mustacchi E1000_WRITE_REG(hw, E1000_EECD, eecd); 16975eba5b6SRobert Mustacchi E1000_WRITE_FLUSH(hw); 17075eba5b6SRobert Mustacchi 17175eba5b6SRobert Mustacchi usec_delay(nvm->delay_usec); 17275eba5b6SRobert Mustacchi 17375eba5b6SRobert Mustacchi e1000_raise_eec_clk(hw, &eecd); 17475eba5b6SRobert Mustacchi e1000_lower_eec_clk(hw, &eecd); 17575eba5b6SRobert Mustacchi 17675eba5b6SRobert Mustacchi mask >>= 1; 17775eba5b6SRobert Mustacchi } while (mask); 17875eba5b6SRobert Mustacchi 17975eba5b6SRobert Mustacchi eecd &= ~E1000_EECD_DI; 18075eba5b6SRobert Mustacchi E1000_WRITE_REG(hw, E1000_EECD, eecd); 18175eba5b6SRobert Mustacchi } 18275eba5b6SRobert Mustacchi 18375eba5b6SRobert Mustacchi /** 18475eba5b6SRobert Mustacchi * e1000_shift_in_eec_bits - Shift data bits in from the EEPROM 18575eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 18675eba5b6SRobert Mustacchi * @count: number of bits to shift in 18775eba5b6SRobert Mustacchi * 18875eba5b6SRobert Mustacchi * In order to read a register from the EEPROM, we need to shift 'count' bits 18975eba5b6SRobert Mustacchi * in from the EEPROM. Bits are "shifted in" by raising the clock input to 19075eba5b6SRobert Mustacchi * the EEPROM (setting the SK bit), and then reading the value of the data out 19175eba5b6SRobert Mustacchi * "DO" bit. During this "shifting in" process the data in "DI" bit should 19275eba5b6SRobert Mustacchi * always be clear. 19375eba5b6SRobert Mustacchi **/ 19475eba5b6SRobert Mustacchi static u16 e1000_shift_in_eec_bits(struct e1000_hw *hw, u16 count) 19575eba5b6SRobert Mustacchi { 19675eba5b6SRobert Mustacchi u32 eecd; 19775eba5b6SRobert Mustacchi u32 i; 19875eba5b6SRobert Mustacchi u16 data; 19975eba5b6SRobert Mustacchi 20075eba5b6SRobert Mustacchi DEBUGFUNC("e1000_shift_in_eec_bits"); 20175eba5b6SRobert Mustacchi 20275eba5b6SRobert Mustacchi eecd = E1000_READ_REG(hw, E1000_EECD); 20375eba5b6SRobert Mustacchi 20475eba5b6SRobert Mustacchi eecd &= ~(E1000_EECD_DO | E1000_EECD_DI); 20575eba5b6SRobert Mustacchi data = 0; 20675eba5b6SRobert Mustacchi 20775eba5b6SRobert Mustacchi for (i = 0; i < count; i++) { 20875eba5b6SRobert Mustacchi data <<= 1; 20975eba5b6SRobert Mustacchi e1000_raise_eec_clk(hw, &eecd); 21075eba5b6SRobert Mustacchi 21175eba5b6SRobert Mustacchi eecd = E1000_READ_REG(hw, E1000_EECD); 21275eba5b6SRobert Mustacchi 21375eba5b6SRobert Mustacchi eecd &= ~E1000_EECD_DI; 21475eba5b6SRobert Mustacchi if (eecd & E1000_EECD_DO) 21575eba5b6SRobert Mustacchi data |= 1; 21675eba5b6SRobert Mustacchi 21775eba5b6SRobert Mustacchi e1000_lower_eec_clk(hw, &eecd); 21875eba5b6SRobert Mustacchi } 21975eba5b6SRobert Mustacchi 22075eba5b6SRobert Mustacchi return data; 22175eba5b6SRobert Mustacchi } 22275eba5b6SRobert Mustacchi 22375eba5b6SRobert Mustacchi /** 22475eba5b6SRobert Mustacchi * e1000_poll_eerd_eewr_done - Poll for EEPROM read/write completion 22575eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 22675eba5b6SRobert Mustacchi * @ee_reg: EEPROM flag for polling 22775eba5b6SRobert Mustacchi * 22875eba5b6SRobert Mustacchi * Polls the EEPROM status bit for either read or write completion based 22975eba5b6SRobert Mustacchi * upon the value of 'ee_reg'. 23075eba5b6SRobert Mustacchi **/ 23175eba5b6SRobert Mustacchi s32 e1000_poll_eerd_eewr_done(struct e1000_hw *hw, int ee_reg) 23275eba5b6SRobert Mustacchi { 23375eba5b6SRobert Mustacchi u32 attempts = 100000; 23475eba5b6SRobert Mustacchi u32 i, reg = 0; 23575eba5b6SRobert Mustacchi 23675eba5b6SRobert Mustacchi DEBUGFUNC("e1000_poll_eerd_eewr_done"); 23775eba5b6SRobert Mustacchi 23875eba5b6SRobert Mustacchi for (i = 0; i < attempts; i++) { 23975eba5b6SRobert Mustacchi if (ee_reg == E1000_NVM_POLL_READ) 24075eba5b6SRobert Mustacchi reg = E1000_READ_REG(hw, E1000_EERD); 24175eba5b6SRobert Mustacchi else 24275eba5b6SRobert Mustacchi reg = E1000_READ_REG(hw, E1000_EEWR); 24375eba5b6SRobert Mustacchi 24475eba5b6SRobert Mustacchi if (reg & E1000_NVM_RW_REG_DONE) 24575eba5b6SRobert Mustacchi return E1000_SUCCESS; 24675eba5b6SRobert Mustacchi 24775eba5b6SRobert Mustacchi usec_delay(5); 24875eba5b6SRobert Mustacchi } 24975eba5b6SRobert Mustacchi 25075eba5b6SRobert Mustacchi return -E1000_ERR_NVM; 25175eba5b6SRobert Mustacchi } 25275eba5b6SRobert Mustacchi 25375eba5b6SRobert Mustacchi /** 25475eba5b6SRobert Mustacchi * e1000_acquire_nvm_generic - Generic request for access to EEPROM 25575eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 25675eba5b6SRobert Mustacchi * 25775eba5b6SRobert Mustacchi * Set the EEPROM access request bit and wait for EEPROM access grant bit. 25875eba5b6SRobert Mustacchi * Return successful if access grant bit set, else clear the request for 25975eba5b6SRobert Mustacchi * EEPROM access and return -E1000_ERR_NVM (-1). 26075eba5b6SRobert Mustacchi **/ 26175eba5b6SRobert Mustacchi s32 e1000_acquire_nvm_generic(struct e1000_hw *hw) 26275eba5b6SRobert Mustacchi { 26375eba5b6SRobert Mustacchi u32 eecd = E1000_READ_REG(hw, E1000_EECD); 26475eba5b6SRobert Mustacchi s32 timeout = E1000_NVM_GRANT_ATTEMPTS; 26575eba5b6SRobert Mustacchi 26675eba5b6SRobert Mustacchi DEBUGFUNC("e1000_acquire_nvm_generic"); 26775eba5b6SRobert Mustacchi 26875eba5b6SRobert Mustacchi E1000_WRITE_REG(hw, E1000_EECD, eecd | E1000_EECD_REQ); 26975eba5b6SRobert Mustacchi eecd = E1000_READ_REG(hw, E1000_EECD); 27075eba5b6SRobert Mustacchi 27175eba5b6SRobert Mustacchi while (timeout) { 27275eba5b6SRobert Mustacchi if (eecd & E1000_EECD_GNT) 27375eba5b6SRobert Mustacchi break; 27475eba5b6SRobert Mustacchi usec_delay(5); 27575eba5b6SRobert Mustacchi eecd = E1000_READ_REG(hw, E1000_EECD); 27675eba5b6SRobert Mustacchi timeout--; 27775eba5b6SRobert Mustacchi } 27875eba5b6SRobert Mustacchi 27975eba5b6SRobert Mustacchi if (!timeout) { 28075eba5b6SRobert Mustacchi eecd &= ~E1000_EECD_REQ; 28175eba5b6SRobert Mustacchi E1000_WRITE_REG(hw, E1000_EECD, eecd); 28275eba5b6SRobert Mustacchi DEBUGOUT("Could not acquire NVM grant\n"); 28375eba5b6SRobert Mustacchi return -E1000_ERR_NVM; 28475eba5b6SRobert Mustacchi } 28575eba5b6SRobert Mustacchi 28675eba5b6SRobert Mustacchi return E1000_SUCCESS; 28775eba5b6SRobert Mustacchi } 28875eba5b6SRobert Mustacchi 28975eba5b6SRobert Mustacchi /** 29075eba5b6SRobert Mustacchi * e1000_standby_nvm - Return EEPROM to standby state 29175eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 29275eba5b6SRobert Mustacchi * 29375eba5b6SRobert Mustacchi * Return the EEPROM to a standby state. 29475eba5b6SRobert Mustacchi **/ 29575eba5b6SRobert Mustacchi static void e1000_standby_nvm(struct e1000_hw *hw) 29675eba5b6SRobert Mustacchi { 29775eba5b6SRobert Mustacchi struct e1000_nvm_info *nvm = &hw->nvm; 29875eba5b6SRobert Mustacchi u32 eecd = E1000_READ_REG(hw, E1000_EECD); 29975eba5b6SRobert Mustacchi 30075eba5b6SRobert Mustacchi DEBUGFUNC("e1000_standby_nvm"); 30175eba5b6SRobert Mustacchi 30275eba5b6SRobert Mustacchi if (nvm->type == e1000_nvm_eeprom_microwire) { 30375eba5b6SRobert Mustacchi eecd &= ~(E1000_EECD_CS | E1000_EECD_SK); 30475eba5b6SRobert Mustacchi E1000_WRITE_REG(hw, E1000_EECD, eecd); 30575eba5b6SRobert Mustacchi E1000_WRITE_FLUSH(hw); 30675eba5b6SRobert Mustacchi usec_delay(nvm->delay_usec); 30775eba5b6SRobert Mustacchi 30875eba5b6SRobert Mustacchi e1000_raise_eec_clk(hw, &eecd); 30975eba5b6SRobert Mustacchi 31075eba5b6SRobert Mustacchi /* Select EEPROM */ 31175eba5b6SRobert Mustacchi eecd |= E1000_EECD_CS; 31275eba5b6SRobert Mustacchi E1000_WRITE_REG(hw, E1000_EECD, eecd); 31375eba5b6SRobert Mustacchi E1000_WRITE_FLUSH(hw); 31475eba5b6SRobert Mustacchi usec_delay(nvm->delay_usec); 31575eba5b6SRobert Mustacchi 31675eba5b6SRobert Mustacchi e1000_lower_eec_clk(hw, &eecd); 31775eba5b6SRobert Mustacchi } else if (nvm->type == e1000_nvm_eeprom_spi) { 31875eba5b6SRobert Mustacchi /* Toggle CS to flush commands */ 31975eba5b6SRobert Mustacchi eecd |= E1000_EECD_CS; 32075eba5b6SRobert Mustacchi E1000_WRITE_REG(hw, E1000_EECD, eecd); 32175eba5b6SRobert Mustacchi E1000_WRITE_FLUSH(hw); 32275eba5b6SRobert Mustacchi usec_delay(nvm->delay_usec); 32375eba5b6SRobert Mustacchi eecd &= ~E1000_EECD_CS; 32475eba5b6SRobert Mustacchi E1000_WRITE_REG(hw, E1000_EECD, eecd); 32575eba5b6SRobert Mustacchi E1000_WRITE_FLUSH(hw); 32675eba5b6SRobert Mustacchi usec_delay(nvm->delay_usec); 32775eba5b6SRobert Mustacchi } 32875eba5b6SRobert Mustacchi } 32975eba5b6SRobert Mustacchi 33075eba5b6SRobert Mustacchi /** 33175eba5b6SRobert Mustacchi * e1000_stop_nvm - Terminate EEPROM command 33275eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 33375eba5b6SRobert Mustacchi * 33475eba5b6SRobert Mustacchi * Terminates the current command by inverting the EEPROM's chip select pin. 33575eba5b6SRobert Mustacchi **/ 33675eba5b6SRobert Mustacchi void e1000_stop_nvm(struct e1000_hw *hw) 33775eba5b6SRobert Mustacchi { 33875eba5b6SRobert Mustacchi u32 eecd; 33975eba5b6SRobert Mustacchi 34075eba5b6SRobert Mustacchi DEBUGFUNC("e1000_stop_nvm"); 34175eba5b6SRobert Mustacchi 34275eba5b6SRobert Mustacchi eecd = E1000_READ_REG(hw, E1000_EECD); 34375eba5b6SRobert Mustacchi if (hw->nvm.type == e1000_nvm_eeprom_spi) { 34475eba5b6SRobert Mustacchi /* Pull CS high */ 34575eba5b6SRobert Mustacchi eecd |= E1000_EECD_CS; 34675eba5b6SRobert Mustacchi e1000_lower_eec_clk(hw, &eecd); 34775eba5b6SRobert Mustacchi } else if (hw->nvm.type == e1000_nvm_eeprom_microwire) { 34875eba5b6SRobert Mustacchi /* CS on Microwire is active-high */ 34975eba5b6SRobert Mustacchi eecd &= ~(E1000_EECD_CS | E1000_EECD_DI); 35075eba5b6SRobert Mustacchi E1000_WRITE_REG(hw, E1000_EECD, eecd); 35175eba5b6SRobert Mustacchi e1000_raise_eec_clk(hw, &eecd); 35275eba5b6SRobert Mustacchi e1000_lower_eec_clk(hw, &eecd); 35375eba5b6SRobert Mustacchi } 35475eba5b6SRobert Mustacchi } 35575eba5b6SRobert Mustacchi 35675eba5b6SRobert Mustacchi /** 35775eba5b6SRobert Mustacchi * e1000_release_nvm_generic - Release exclusive access to EEPROM 35875eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 35975eba5b6SRobert Mustacchi * 36075eba5b6SRobert Mustacchi * Stop any current commands to the EEPROM and clear the EEPROM request bit. 36175eba5b6SRobert Mustacchi **/ 36275eba5b6SRobert Mustacchi void e1000_release_nvm_generic(struct e1000_hw *hw) 36375eba5b6SRobert Mustacchi { 36475eba5b6SRobert Mustacchi u32 eecd; 36575eba5b6SRobert Mustacchi 36675eba5b6SRobert Mustacchi DEBUGFUNC("e1000_release_nvm_generic"); 36775eba5b6SRobert Mustacchi 36875eba5b6SRobert Mustacchi e1000_stop_nvm(hw); 36975eba5b6SRobert Mustacchi 37075eba5b6SRobert Mustacchi eecd = E1000_READ_REG(hw, E1000_EECD); 37175eba5b6SRobert Mustacchi eecd &= ~E1000_EECD_REQ; 37275eba5b6SRobert Mustacchi E1000_WRITE_REG(hw, E1000_EECD, eecd); 37375eba5b6SRobert Mustacchi } 37475eba5b6SRobert Mustacchi 37575eba5b6SRobert Mustacchi /** 37675eba5b6SRobert Mustacchi * e1000_ready_nvm_eeprom - Prepares EEPROM for read/write 37775eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 37875eba5b6SRobert Mustacchi * 37975eba5b6SRobert Mustacchi * Setups the EEPROM for reading and writing. 38075eba5b6SRobert Mustacchi **/ 38175eba5b6SRobert Mustacchi static s32 e1000_ready_nvm_eeprom(struct e1000_hw *hw) 38275eba5b6SRobert Mustacchi { 38375eba5b6SRobert Mustacchi struct e1000_nvm_info *nvm = &hw->nvm; 38475eba5b6SRobert Mustacchi u32 eecd = E1000_READ_REG(hw, E1000_EECD); 38575eba5b6SRobert Mustacchi u8 spi_stat_reg; 38675eba5b6SRobert Mustacchi 38775eba5b6SRobert Mustacchi DEBUGFUNC("e1000_ready_nvm_eeprom"); 38875eba5b6SRobert Mustacchi 38975eba5b6SRobert Mustacchi if (nvm->type == e1000_nvm_eeprom_microwire) { 39075eba5b6SRobert Mustacchi /* Clear SK and DI */ 39175eba5b6SRobert Mustacchi eecd &= ~(E1000_EECD_DI | E1000_EECD_SK); 39275eba5b6SRobert Mustacchi E1000_WRITE_REG(hw, E1000_EECD, eecd); 39375eba5b6SRobert Mustacchi /* Set CS */ 39475eba5b6SRobert Mustacchi eecd |= E1000_EECD_CS; 39575eba5b6SRobert Mustacchi E1000_WRITE_REG(hw, E1000_EECD, eecd); 39675eba5b6SRobert Mustacchi } else if (nvm->type == e1000_nvm_eeprom_spi) { 39775eba5b6SRobert Mustacchi u16 timeout = NVM_MAX_RETRY_SPI; 39875eba5b6SRobert Mustacchi 39975eba5b6SRobert Mustacchi /* Clear SK and CS */ 40075eba5b6SRobert Mustacchi eecd &= ~(E1000_EECD_CS | E1000_EECD_SK); 40175eba5b6SRobert Mustacchi E1000_WRITE_REG(hw, E1000_EECD, eecd); 40275eba5b6SRobert Mustacchi E1000_WRITE_FLUSH(hw); 40375eba5b6SRobert Mustacchi usec_delay(1); 40475eba5b6SRobert Mustacchi 40575eba5b6SRobert Mustacchi /* Read "Status Register" repeatedly until the LSB is cleared. 40675eba5b6SRobert Mustacchi * The EEPROM will signal that the command has been completed 40775eba5b6SRobert Mustacchi * by clearing bit 0 of the internal status register. If it's 40875eba5b6SRobert Mustacchi * not cleared within 'timeout', then error out. 40975eba5b6SRobert Mustacchi */ 41075eba5b6SRobert Mustacchi while (timeout) { 41175eba5b6SRobert Mustacchi e1000_shift_out_eec_bits(hw, NVM_RDSR_OPCODE_SPI, 41275eba5b6SRobert Mustacchi hw->nvm.opcode_bits); 41375eba5b6SRobert Mustacchi spi_stat_reg = (u8)e1000_shift_in_eec_bits(hw, 8); 41475eba5b6SRobert Mustacchi if (!(spi_stat_reg & NVM_STATUS_RDY_SPI)) 41575eba5b6SRobert Mustacchi break; 41675eba5b6SRobert Mustacchi 41775eba5b6SRobert Mustacchi usec_delay(5); 41875eba5b6SRobert Mustacchi e1000_standby_nvm(hw); 41975eba5b6SRobert Mustacchi timeout--; 42075eba5b6SRobert Mustacchi } 42175eba5b6SRobert Mustacchi 42275eba5b6SRobert Mustacchi if (!timeout) { 42375eba5b6SRobert Mustacchi DEBUGOUT("SPI NVM Status error\n"); 42475eba5b6SRobert Mustacchi return -E1000_ERR_NVM; 42575eba5b6SRobert Mustacchi } 42675eba5b6SRobert Mustacchi } 42775eba5b6SRobert Mustacchi 42875eba5b6SRobert Mustacchi return E1000_SUCCESS; 42975eba5b6SRobert Mustacchi } 43075eba5b6SRobert Mustacchi 43175eba5b6SRobert Mustacchi /** 43275eba5b6SRobert Mustacchi * e1000_read_nvm_spi - Read EEPROM's using SPI 43375eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 43475eba5b6SRobert Mustacchi * @offset: offset of word in the EEPROM to read 43575eba5b6SRobert Mustacchi * @words: number of words to read 43675eba5b6SRobert Mustacchi * @data: word read from the EEPROM 43775eba5b6SRobert Mustacchi * 43875eba5b6SRobert Mustacchi * Reads a 16 bit word from the EEPROM. 43975eba5b6SRobert Mustacchi **/ 44075eba5b6SRobert Mustacchi s32 e1000_read_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data) 44175eba5b6SRobert Mustacchi { 44275eba5b6SRobert Mustacchi struct e1000_nvm_info *nvm = &hw->nvm; 44375eba5b6SRobert Mustacchi u32 i = 0; 44475eba5b6SRobert Mustacchi s32 ret_val; 44575eba5b6SRobert Mustacchi u16 word_in; 44675eba5b6SRobert Mustacchi u8 read_opcode = NVM_READ_OPCODE_SPI; 44775eba5b6SRobert Mustacchi 44875eba5b6SRobert Mustacchi DEBUGFUNC("e1000_read_nvm_spi"); 44975eba5b6SRobert Mustacchi 45075eba5b6SRobert Mustacchi /* A check for invalid values: offset too large, too many words, 45175eba5b6SRobert Mustacchi * and not enough words. 45275eba5b6SRobert Mustacchi */ 45375eba5b6SRobert Mustacchi if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) || 45475eba5b6SRobert Mustacchi (words == 0)) { 45575eba5b6SRobert Mustacchi DEBUGOUT("nvm parameter(s) out of bounds\n"); 45675eba5b6SRobert Mustacchi return -E1000_ERR_NVM; 45775eba5b6SRobert Mustacchi } 45875eba5b6SRobert Mustacchi 45975eba5b6SRobert Mustacchi ret_val = nvm->ops.acquire(hw); 46075eba5b6SRobert Mustacchi if (ret_val) 46175eba5b6SRobert Mustacchi return ret_val; 46275eba5b6SRobert Mustacchi 46375eba5b6SRobert Mustacchi ret_val = e1000_ready_nvm_eeprom(hw); 46475eba5b6SRobert Mustacchi if (ret_val) 46575eba5b6SRobert Mustacchi goto release; 46675eba5b6SRobert Mustacchi 46775eba5b6SRobert Mustacchi e1000_standby_nvm(hw); 46875eba5b6SRobert Mustacchi 46975eba5b6SRobert Mustacchi if ((nvm->address_bits == 8) && (offset >= 128)) 47075eba5b6SRobert Mustacchi read_opcode |= NVM_A8_OPCODE_SPI; 47175eba5b6SRobert Mustacchi 47275eba5b6SRobert Mustacchi /* Send the READ command (opcode + addr) */ 47375eba5b6SRobert Mustacchi e1000_shift_out_eec_bits(hw, read_opcode, nvm->opcode_bits); 47475eba5b6SRobert Mustacchi e1000_shift_out_eec_bits(hw, (u16)(offset*2), nvm->address_bits); 47575eba5b6SRobert Mustacchi 47675eba5b6SRobert Mustacchi /* Read the data. SPI NVMs increment the address with each byte 47775eba5b6SRobert Mustacchi * read and will roll over if reading beyond the end. This allows 47875eba5b6SRobert Mustacchi * us to read the whole NVM from any offset 47975eba5b6SRobert Mustacchi */ 48075eba5b6SRobert Mustacchi for (i = 0; i < words; i++) { 48175eba5b6SRobert Mustacchi word_in = e1000_shift_in_eec_bits(hw, 16); 48275eba5b6SRobert Mustacchi data[i] = (word_in >> 8) | (word_in << 8); 48375eba5b6SRobert Mustacchi } 48475eba5b6SRobert Mustacchi 48575eba5b6SRobert Mustacchi release: 48675eba5b6SRobert Mustacchi nvm->ops.release(hw); 48775eba5b6SRobert Mustacchi 48875eba5b6SRobert Mustacchi return ret_val; 48975eba5b6SRobert Mustacchi } 49075eba5b6SRobert Mustacchi 49175eba5b6SRobert Mustacchi /** 49275eba5b6SRobert Mustacchi * e1000_read_nvm_microwire - Reads EEPROM's using microwire 49375eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 49475eba5b6SRobert Mustacchi * @offset: offset of word in the EEPROM to read 49575eba5b6SRobert Mustacchi * @words: number of words to read 49675eba5b6SRobert Mustacchi * @data: word read from the EEPROM 49775eba5b6SRobert Mustacchi * 49875eba5b6SRobert Mustacchi * Reads a 16 bit word from the EEPROM. 49975eba5b6SRobert Mustacchi **/ 50075eba5b6SRobert Mustacchi s32 e1000_read_nvm_microwire(struct e1000_hw *hw, u16 offset, u16 words, 50175eba5b6SRobert Mustacchi u16 *data) 50275eba5b6SRobert Mustacchi { 50375eba5b6SRobert Mustacchi struct e1000_nvm_info *nvm = &hw->nvm; 50475eba5b6SRobert Mustacchi u32 i = 0; 50575eba5b6SRobert Mustacchi s32 ret_val; 50675eba5b6SRobert Mustacchi u8 read_opcode = NVM_READ_OPCODE_MICROWIRE; 50775eba5b6SRobert Mustacchi 50875eba5b6SRobert Mustacchi DEBUGFUNC("e1000_read_nvm_microwire"); 50975eba5b6SRobert Mustacchi 51075eba5b6SRobert Mustacchi /* A check for invalid values: offset too large, too many words, 51175eba5b6SRobert Mustacchi * and not enough words. 51275eba5b6SRobert Mustacchi */ 51375eba5b6SRobert Mustacchi if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) || 51475eba5b6SRobert Mustacchi (words == 0)) { 51575eba5b6SRobert Mustacchi DEBUGOUT("nvm parameter(s) out of bounds\n"); 51675eba5b6SRobert Mustacchi return -E1000_ERR_NVM; 51775eba5b6SRobert Mustacchi } 51875eba5b6SRobert Mustacchi 51975eba5b6SRobert Mustacchi ret_val = nvm->ops.acquire(hw); 52075eba5b6SRobert Mustacchi if (ret_val) 52175eba5b6SRobert Mustacchi return ret_val; 52275eba5b6SRobert Mustacchi 52375eba5b6SRobert Mustacchi ret_val = e1000_ready_nvm_eeprom(hw); 52475eba5b6SRobert Mustacchi if (ret_val) 52575eba5b6SRobert Mustacchi goto release; 52675eba5b6SRobert Mustacchi 52775eba5b6SRobert Mustacchi for (i = 0; i < words; i++) { 52875eba5b6SRobert Mustacchi /* Send the READ command (opcode + addr) */ 52975eba5b6SRobert Mustacchi e1000_shift_out_eec_bits(hw, read_opcode, nvm->opcode_bits); 53075eba5b6SRobert Mustacchi e1000_shift_out_eec_bits(hw, (u16)(offset + i), 53175eba5b6SRobert Mustacchi nvm->address_bits); 53275eba5b6SRobert Mustacchi 53375eba5b6SRobert Mustacchi /* Read the data. For microwire, each word requires the 53475eba5b6SRobert Mustacchi * overhead of setup and tear-down. 53575eba5b6SRobert Mustacchi */ 53675eba5b6SRobert Mustacchi data[i] = e1000_shift_in_eec_bits(hw, 16); 53775eba5b6SRobert Mustacchi e1000_standby_nvm(hw); 53875eba5b6SRobert Mustacchi } 53975eba5b6SRobert Mustacchi 54075eba5b6SRobert Mustacchi release: 54175eba5b6SRobert Mustacchi nvm->ops.release(hw); 54275eba5b6SRobert Mustacchi 54375eba5b6SRobert Mustacchi return ret_val; 54475eba5b6SRobert Mustacchi } 54575eba5b6SRobert Mustacchi 54675eba5b6SRobert Mustacchi /** 54775eba5b6SRobert Mustacchi * e1000_read_nvm_eerd - Reads EEPROM using EERD register 54875eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 54975eba5b6SRobert Mustacchi * @offset: offset of word in the EEPROM to read 55075eba5b6SRobert Mustacchi * @words: number of words to read 55175eba5b6SRobert Mustacchi * @data: word read from the EEPROM 55275eba5b6SRobert Mustacchi * 55375eba5b6SRobert Mustacchi * Reads a 16 bit word from the EEPROM using the EERD register. 55475eba5b6SRobert Mustacchi **/ 55575eba5b6SRobert Mustacchi s32 e1000_read_nvm_eerd(struct e1000_hw *hw, u16 offset, u16 words, u16 *data) 55675eba5b6SRobert Mustacchi { 55775eba5b6SRobert Mustacchi struct e1000_nvm_info *nvm = &hw->nvm; 55875eba5b6SRobert Mustacchi u32 i, eerd = 0; 55975eba5b6SRobert Mustacchi s32 ret_val = E1000_SUCCESS; 56075eba5b6SRobert Mustacchi 56175eba5b6SRobert Mustacchi DEBUGFUNC("e1000_read_nvm_eerd"); 56275eba5b6SRobert Mustacchi 56375eba5b6SRobert Mustacchi /* A check for invalid values: offset too large, too many words, 56475eba5b6SRobert Mustacchi * too many words for the offset, and not enough words. 56575eba5b6SRobert Mustacchi */ 56675eba5b6SRobert Mustacchi if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) || 56775eba5b6SRobert Mustacchi (words == 0)) { 56875eba5b6SRobert Mustacchi DEBUGOUT("nvm parameter(s) out of bounds\n"); 56975eba5b6SRobert Mustacchi return -E1000_ERR_NVM; 57075eba5b6SRobert Mustacchi } 57175eba5b6SRobert Mustacchi 57275eba5b6SRobert Mustacchi for (i = 0; i < words; i++) { 57375eba5b6SRobert Mustacchi eerd = ((offset+i) << E1000_NVM_RW_ADDR_SHIFT) + 57475eba5b6SRobert Mustacchi E1000_NVM_RW_REG_START; 57575eba5b6SRobert Mustacchi 57675eba5b6SRobert Mustacchi E1000_WRITE_REG(hw, E1000_EERD, eerd); 57775eba5b6SRobert Mustacchi ret_val = e1000_poll_eerd_eewr_done(hw, E1000_NVM_POLL_READ); 57875eba5b6SRobert Mustacchi if (ret_val) 57975eba5b6SRobert Mustacchi break; 58075eba5b6SRobert Mustacchi 58175eba5b6SRobert Mustacchi data[i] = (E1000_READ_REG(hw, E1000_EERD) >> 58275eba5b6SRobert Mustacchi E1000_NVM_RW_REG_DATA); 58375eba5b6SRobert Mustacchi } 58475eba5b6SRobert Mustacchi 585c124a83eSRobert Mustacchi if (ret_val) 586c124a83eSRobert Mustacchi DEBUGOUT1("NVM read error: %d\n", ret_val); 587c124a83eSRobert Mustacchi 58875eba5b6SRobert Mustacchi return ret_val; 58975eba5b6SRobert Mustacchi } 59075eba5b6SRobert Mustacchi 59175eba5b6SRobert Mustacchi /** 59275eba5b6SRobert Mustacchi * e1000_write_nvm_spi - Write to EEPROM using SPI 59375eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 59475eba5b6SRobert Mustacchi * @offset: offset within the EEPROM to be written to 59575eba5b6SRobert Mustacchi * @words: number of words to write 59675eba5b6SRobert Mustacchi * @data: 16 bit word(s) to be written to the EEPROM 59775eba5b6SRobert Mustacchi * 59875eba5b6SRobert Mustacchi * Writes data to EEPROM at offset using SPI interface. 59975eba5b6SRobert Mustacchi * 60075eba5b6SRobert Mustacchi * If e1000_update_nvm_checksum is not called after this function , the 60175eba5b6SRobert Mustacchi * EEPROM will most likely contain an invalid checksum. 60275eba5b6SRobert Mustacchi **/ 60375eba5b6SRobert Mustacchi s32 e1000_write_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data) 60475eba5b6SRobert Mustacchi { 60575eba5b6SRobert Mustacchi struct e1000_nvm_info *nvm = &hw->nvm; 60675eba5b6SRobert Mustacchi s32 ret_val = -E1000_ERR_NVM; 60775eba5b6SRobert Mustacchi u16 widx = 0; 60875eba5b6SRobert Mustacchi 60975eba5b6SRobert Mustacchi DEBUGFUNC("e1000_write_nvm_spi"); 61075eba5b6SRobert Mustacchi 61175eba5b6SRobert Mustacchi /* A check for invalid values: offset too large, too many words, 61275eba5b6SRobert Mustacchi * and not enough words. 61375eba5b6SRobert Mustacchi */ 61475eba5b6SRobert Mustacchi if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) || 61575eba5b6SRobert Mustacchi (words == 0)) { 61675eba5b6SRobert Mustacchi DEBUGOUT("nvm parameter(s) out of bounds\n"); 61775eba5b6SRobert Mustacchi return -E1000_ERR_NVM; 61875eba5b6SRobert Mustacchi } 61975eba5b6SRobert Mustacchi 62075eba5b6SRobert Mustacchi while (widx < words) { 62175eba5b6SRobert Mustacchi u8 write_opcode = NVM_WRITE_OPCODE_SPI; 62275eba5b6SRobert Mustacchi 62375eba5b6SRobert Mustacchi ret_val = nvm->ops.acquire(hw); 62475eba5b6SRobert Mustacchi if (ret_val) 62575eba5b6SRobert Mustacchi return ret_val; 62675eba5b6SRobert Mustacchi 62775eba5b6SRobert Mustacchi ret_val = e1000_ready_nvm_eeprom(hw); 62875eba5b6SRobert Mustacchi if (ret_val) { 62975eba5b6SRobert Mustacchi nvm->ops.release(hw); 63075eba5b6SRobert Mustacchi return ret_val; 63175eba5b6SRobert Mustacchi } 63275eba5b6SRobert Mustacchi 63375eba5b6SRobert Mustacchi e1000_standby_nvm(hw); 63475eba5b6SRobert Mustacchi 63575eba5b6SRobert Mustacchi /* Send the WRITE ENABLE command (8 bit opcode) */ 63675eba5b6SRobert Mustacchi e1000_shift_out_eec_bits(hw, NVM_WREN_OPCODE_SPI, 63775eba5b6SRobert Mustacchi nvm->opcode_bits); 63875eba5b6SRobert Mustacchi 63975eba5b6SRobert Mustacchi e1000_standby_nvm(hw); 64075eba5b6SRobert Mustacchi 64175eba5b6SRobert Mustacchi /* Some SPI eeproms use the 8th address bit embedded in the 64275eba5b6SRobert Mustacchi * opcode 64375eba5b6SRobert Mustacchi */ 64475eba5b6SRobert Mustacchi if ((nvm->address_bits == 8) && (offset >= 128)) 64575eba5b6SRobert Mustacchi write_opcode |= NVM_A8_OPCODE_SPI; 64675eba5b6SRobert Mustacchi 64775eba5b6SRobert Mustacchi /* Send the Write command (8-bit opcode + addr) */ 64875eba5b6SRobert Mustacchi e1000_shift_out_eec_bits(hw, write_opcode, nvm->opcode_bits); 64975eba5b6SRobert Mustacchi e1000_shift_out_eec_bits(hw, (u16)((offset + widx) * 2), 65075eba5b6SRobert Mustacchi nvm->address_bits); 65175eba5b6SRobert Mustacchi 65275eba5b6SRobert Mustacchi /* Loop to allow for up to whole page write of eeprom */ 65375eba5b6SRobert Mustacchi while (widx < words) { 65475eba5b6SRobert Mustacchi u16 word_out = data[widx]; 65575eba5b6SRobert Mustacchi word_out = (word_out >> 8) | (word_out << 8); 65675eba5b6SRobert Mustacchi e1000_shift_out_eec_bits(hw, word_out, 16); 65775eba5b6SRobert Mustacchi widx++; 65875eba5b6SRobert Mustacchi 65975eba5b6SRobert Mustacchi if ((((offset + widx) * 2) % nvm->page_size) == 0) { 66075eba5b6SRobert Mustacchi e1000_standby_nvm(hw); 66175eba5b6SRobert Mustacchi break; 66275eba5b6SRobert Mustacchi } 66375eba5b6SRobert Mustacchi } 66475eba5b6SRobert Mustacchi msec_delay(10); 66575eba5b6SRobert Mustacchi nvm->ops.release(hw); 66675eba5b6SRobert Mustacchi } 66775eba5b6SRobert Mustacchi 66875eba5b6SRobert Mustacchi return ret_val; 66975eba5b6SRobert Mustacchi } 67075eba5b6SRobert Mustacchi 67175eba5b6SRobert Mustacchi /** 67275eba5b6SRobert Mustacchi * e1000_write_nvm_microwire - Writes EEPROM using microwire 67375eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 67475eba5b6SRobert Mustacchi * @offset: offset within the EEPROM to be written to 67575eba5b6SRobert Mustacchi * @words: number of words to write 67675eba5b6SRobert Mustacchi * @data: 16 bit word(s) to be written to the EEPROM 67775eba5b6SRobert Mustacchi * 67875eba5b6SRobert Mustacchi * Writes data to EEPROM at offset using microwire interface. 67975eba5b6SRobert Mustacchi * 68075eba5b6SRobert Mustacchi * If e1000_update_nvm_checksum is not called after this function , the 68175eba5b6SRobert Mustacchi * EEPROM will most likely contain an invalid checksum. 68275eba5b6SRobert Mustacchi **/ 68375eba5b6SRobert Mustacchi s32 e1000_write_nvm_microwire(struct e1000_hw *hw, u16 offset, u16 words, 68475eba5b6SRobert Mustacchi u16 *data) 68575eba5b6SRobert Mustacchi { 68675eba5b6SRobert Mustacchi struct e1000_nvm_info *nvm = &hw->nvm; 68775eba5b6SRobert Mustacchi s32 ret_val; 68875eba5b6SRobert Mustacchi u32 eecd; 68975eba5b6SRobert Mustacchi u16 words_written = 0; 69075eba5b6SRobert Mustacchi u16 widx = 0; 69175eba5b6SRobert Mustacchi 69275eba5b6SRobert Mustacchi DEBUGFUNC("e1000_write_nvm_microwire"); 69375eba5b6SRobert Mustacchi 69475eba5b6SRobert Mustacchi /* A check for invalid values: offset too large, too many words, 69575eba5b6SRobert Mustacchi * and not enough words. 69675eba5b6SRobert Mustacchi */ 69775eba5b6SRobert Mustacchi if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) || 69875eba5b6SRobert Mustacchi (words == 0)) { 69975eba5b6SRobert Mustacchi DEBUGOUT("nvm parameter(s) out of bounds\n"); 70075eba5b6SRobert Mustacchi return -E1000_ERR_NVM; 70175eba5b6SRobert Mustacchi } 70275eba5b6SRobert Mustacchi 70375eba5b6SRobert Mustacchi ret_val = nvm->ops.acquire(hw); 70475eba5b6SRobert Mustacchi if (ret_val) 70575eba5b6SRobert Mustacchi return ret_val; 70675eba5b6SRobert Mustacchi 70775eba5b6SRobert Mustacchi ret_val = e1000_ready_nvm_eeprom(hw); 70875eba5b6SRobert Mustacchi if (ret_val) 70975eba5b6SRobert Mustacchi goto release; 71075eba5b6SRobert Mustacchi 71175eba5b6SRobert Mustacchi e1000_shift_out_eec_bits(hw, NVM_EWEN_OPCODE_MICROWIRE, 71275eba5b6SRobert Mustacchi (u16)(nvm->opcode_bits + 2)); 71375eba5b6SRobert Mustacchi 71475eba5b6SRobert Mustacchi e1000_shift_out_eec_bits(hw, 0, (u16)(nvm->address_bits - 2)); 71575eba5b6SRobert Mustacchi 71675eba5b6SRobert Mustacchi e1000_standby_nvm(hw); 71775eba5b6SRobert Mustacchi 71875eba5b6SRobert Mustacchi while (words_written < words) { 71975eba5b6SRobert Mustacchi e1000_shift_out_eec_bits(hw, NVM_WRITE_OPCODE_MICROWIRE, 72075eba5b6SRobert Mustacchi nvm->opcode_bits); 72175eba5b6SRobert Mustacchi 72275eba5b6SRobert Mustacchi e1000_shift_out_eec_bits(hw, (u16)(offset + words_written), 72375eba5b6SRobert Mustacchi nvm->address_bits); 72475eba5b6SRobert Mustacchi 72575eba5b6SRobert Mustacchi e1000_shift_out_eec_bits(hw, data[words_written], 16); 72675eba5b6SRobert Mustacchi 72775eba5b6SRobert Mustacchi e1000_standby_nvm(hw); 72875eba5b6SRobert Mustacchi 72975eba5b6SRobert Mustacchi for (widx = 0; widx < 200; widx++) { 73075eba5b6SRobert Mustacchi eecd = E1000_READ_REG(hw, E1000_EECD); 73175eba5b6SRobert Mustacchi if (eecd & E1000_EECD_DO) 73275eba5b6SRobert Mustacchi break; 73375eba5b6SRobert Mustacchi usec_delay(50); 73475eba5b6SRobert Mustacchi } 73575eba5b6SRobert Mustacchi 73675eba5b6SRobert Mustacchi if (widx == 200) { 73775eba5b6SRobert Mustacchi DEBUGOUT("NVM Write did not complete\n"); 73875eba5b6SRobert Mustacchi ret_val = -E1000_ERR_NVM; 73975eba5b6SRobert Mustacchi goto release; 74075eba5b6SRobert Mustacchi } 74175eba5b6SRobert Mustacchi 74275eba5b6SRobert Mustacchi e1000_standby_nvm(hw); 74375eba5b6SRobert Mustacchi 74475eba5b6SRobert Mustacchi words_written++; 74575eba5b6SRobert Mustacchi } 74675eba5b6SRobert Mustacchi 74775eba5b6SRobert Mustacchi e1000_shift_out_eec_bits(hw, NVM_EWDS_OPCODE_MICROWIRE, 74875eba5b6SRobert Mustacchi (u16)(nvm->opcode_bits + 2)); 74975eba5b6SRobert Mustacchi 75075eba5b6SRobert Mustacchi e1000_shift_out_eec_bits(hw, 0, (u16)(nvm->address_bits - 2)); 75175eba5b6SRobert Mustacchi 75275eba5b6SRobert Mustacchi release: 75375eba5b6SRobert Mustacchi nvm->ops.release(hw); 75475eba5b6SRobert Mustacchi 75575eba5b6SRobert Mustacchi return ret_val; 75675eba5b6SRobert Mustacchi } 75775eba5b6SRobert Mustacchi 75875eba5b6SRobert Mustacchi /** 75975eba5b6SRobert Mustacchi * e1000_read_pba_string_generic - Read device part number 76075eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 76175eba5b6SRobert Mustacchi * @pba_num: pointer to device part number 76275eba5b6SRobert Mustacchi * @pba_num_size: size of part number buffer 76375eba5b6SRobert Mustacchi * 76475eba5b6SRobert Mustacchi * Reads the product board assembly (PBA) number from the EEPROM and stores 76575eba5b6SRobert Mustacchi * the value in pba_num. 76675eba5b6SRobert Mustacchi **/ 76775eba5b6SRobert Mustacchi s32 e1000_read_pba_string_generic(struct e1000_hw *hw, u8 *pba_num, 76875eba5b6SRobert Mustacchi u32 pba_num_size) 76975eba5b6SRobert Mustacchi { 77075eba5b6SRobert Mustacchi s32 ret_val; 77175eba5b6SRobert Mustacchi u16 nvm_data; 77275eba5b6SRobert Mustacchi u16 pba_ptr; 77375eba5b6SRobert Mustacchi u16 offset; 77475eba5b6SRobert Mustacchi u16 length; 77575eba5b6SRobert Mustacchi 77675eba5b6SRobert Mustacchi DEBUGFUNC("e1000_read_pba_string_generic"); 77775eba5b6SRobert Mustacchi 778c124a83eSRobert Mustacchi if ((hw->mac.type >= e1000_i210) && 779c124a83eSRobert Mustacchi !e1000_get_flash_presence_i210(hw)) { 780c124a83eSRobert Mustacchi DEBUGOUT("Flashless no PBA string\n"); 781c124a83eSRobert Mustacchi return -E1000_ERR_NVM_PBA_SECTION; 782c124a83eSRobert Mustacchi } 783c124a83eSRobert Mustacchi 78475eba5b6SRobert Mustacchi if (pba_num == NULL) { 78575eba5b6SRobert Mustacchi DEBUGOUT("PBA string buffer was null\n"); 78675eba5b6SRobert Mustacchi return -E1000_ERR_INVALID_ARGUMENT; 78775eba5b6SRobert Mustacchi } 78875eba5b6SRobert Mustacchi 78975eba5b6SRobert Mustacchi ret_val = hw->nvm.ops.read(hw, NVM_PBA_OFFSET_0, 1, &nvm_data); 79075eba5b6SRobert Mustacchi if (ret_val) { 79175eba5b6SRobert Mustacchi DEBUGOUT("NVM Read Error\n"); 79275eba5b6SRobert Mustacchi return ret_val; 79375eba5b6SRobert Mustacchi } 79475eba5b6SRobert Mustacchi 79575eba5b6SRobert Mustacchi ret_val = hw->nvm.ops.read(hw, NVM_PBA_OFFSET_1, 1, &pba_ptr); 79675eba5b6SRobert Mustacchi if (ret_val) { 79775eba5b6SRobert Mustacchi DEBUGOUT("NVM Read Error\n"); 79875eba5b6SRobert Mustacchi return ret_val; 79975eba5b6SRobert Mustacchi } 80075eba5b6SRobert Mustacchi 80175eba5b6SRobert Mustacchi /* if nvm_data is not ptr guard the PBA must be in legacy format which 80275eba5b6SRobert Mustacchi * means pba_ptr is actually our second data word for the PBA number 80375eba5b6SRobert Mustacchi * and we can decode it into an ascii string 80475eba5b6SRobert Mustacchi */ 80575eba5b6SRobert Mustacchi if (nvm_data != NVM_PBA_PTR_GUARD) { 80675eba5b6SRobert Mustacchi DEBUGOUT("NVM PBA number is not stored as string\n"); 80775eba5b6SRobert Mustacchi 80875eba5b6SRobert Mustacchi /* make sure callers buffer is big enough to store the PBA */ 80975eba5b6SRobert Mustacchi if (pba_num_size < E1000_PBANUM_LENGTH) { 81075eba5b6SRobert Mustacchi DEBUGOUT("PBA string buffer too small\n"); 81175eba5b6SRobert Mustacchi return E1000_ERR_NO_SPACE; 81275eba5b6SRobert Mustacchi } 81375eba5b6SRobert Mustacchi 81475eba5b6SRobert Mustacchi /* extract hex string from data and pba_ptr */ 81575eba5b6SRobert Mustacchi pba_num[0] = (nvm_data >> 12) & 0xF; 81675eba5b6SRobert Mustacchi pba_num[1] = (nvm_data >> 8) & 0xF; 81775eba5b6SRobert Mustacchi pba_num[2] = (nvm_data >> 4) & 0xF; 81875eba5b6SRobert Mustacchi pba_num[3] = nvm_data & 0xF; 81975eba5b6SRobert Mustacchi pba_num[4] = (pba_ptr >> 12) & 0xF; 82075eba5b6SRobert Mustacchi pba_num[5] = (pba_ptr >> 8) & 0xF; 82175eba5b6SRobert Mustacchi pba_num[6] = '-'; 82275eba5b6SRobert Mustacchi pba_num[7] = 0; 82375eba5b6SRobert Mustacchi pba_num[8] = (pba_ptr >> 4) & 0xF; 82475eba5b6SRobert Mustacchi pba_num[9] = pba_ptr & 0xF; 82575eba5b6SRobert Mustacchi 82675eba5b6SRobert Mustacchi /* put a null character on the end of our string */ 82775eba5b6SRobert Mustacchi pba_num[10] = '\0'; 82875eba5b6SRobert Mustacchi 82975eba5b6SRobert Mustacchi /* switch all the data but the '-' to hex char */ 83075eba5b6SRobert Mustacchi for (offset = 0; offset < 10; offset++) { 83175eba5b6SRobert Mustacchi if (pba_num[offset] < 0xA) 83275eba5b6SRobert Mustacchi pba_num[offset] += '0'; 83375eba5b6SRobert Mustacchi else if (pba_num[offset] < 0x10) 83475eba5b6SRobert Mustacchi pba_num[offset] += 'A' - 0xA; 83575eba5b6SRobert Mustacchi } 83675eba5b6SRobert Mustacchi 83775eba5b6SRobert Mustacchi return E1000_SUCCESS; 83875eba5b6SRobert Mustacchi } 83975eba5b6SRobert Mustacchi 84075eba5b6SRobert Mustacchi ret_val = hw->nvm.ops.read(hw, pba_ptr, 1, &length); 84175eba5b6SRobert Mustacchi if (ret_val) { 84275eba5b6SRobert Mustacchi DEBUGOUT("NVM Read Error\n"); 84375eba5b6SRobert Mustacchi return ret_val; 84475eba5b6SRobert Mustacchi } 84575eba5b6SRobert Mustacchi 84675eba5b6SRobert Mustacchi if (length == 0xFFFF || length == 0) { 84775eba5b6SRobert Mustacchi DEBUGOUT("NVM PBA number section invalid length\n"); 84875eba5b6SRobert Mustacchi return -E1000_ERR_NVM_PBA_SECTION; 84975eba5b6SRobert Mustacchi } 85075eba5b6SRobert Mustacchi /* check if pba_num buffer is big enough */ 85175eba5b6SRobert Mustacchi if (pba_num_size < (((u32)length * 2) - 1)) { 85275eba5b6SRobert Mustacchi DEBUGOUT("PBA string buffer too small\n"); 85375eba5b6SRobert Mustacchi return -E1000_ERR_NO_SPACE; 85475eba5b6SRobert Mustacchi } 85575eba5b6SRobert Mustacchi 85675eba5b6SRobert Mustacchi /* trim pba length from start of string */ 85775eba5b6SRobert Mustacchi pba_ptr++; 85875eba5b6SRobert Mustacchi length--; 85975eba5b6SRobert Mustacchi 86075eba5b6SRobert Mustacchi for (offset = 0; offset < length; offset++) { 86175eba5b6SRobert Mustacchi ret_val = hw->nvm.ops.read(hw, pba_ptr + offset, 1, &nvm_data); 86275eba5b6SRobert Mustacchi if (ret_val) { 86375eba5b6SRobert Mustacchi DEBUGOUT("NVM Read Error\n"); 86475eba5b6SRobert Mustacchi return ret_val; 86575eba5b6SRobert Mustacchi } 86675eba5b6SRobert Mustacchi pba_num[offset * 2] = (u8)(nvm_data >> 8); 86775eba5b6SRobert Mustacchi pba_num[(offset * 2) + 1] = (u8)(nvm_data & 0xFF); 86875eba5b6SRobert Mustacchi } 86975eba5b6SRobert Mustacchi pba_num[offset * 2] = '\0'; 87075eba5b6SRobert Mustacchi 87175eba5b6SRobert Mustacchi return E1000_SUCCESS; 87275eba5b6SRobert Mustacchi } 87375eba5b6SRobert Mustacchi 87475eba5b6SRobert Mustacchi /** 87575eba5b6SRobert Mustacchi * e1000_read_pba_length_generic - Read device part number length 87675eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 87775eba5b6SRobert Mustacchi * @pba_num_size: size of part number buffer 87875eba5b6SRobert Mustacchi * 87975eba5b6SRobert Mustacchi * Reads the product board assembly (PBA) number length from the EEPROM and 88075eba5b6SRobert Mustacchi * stores the value in pba_num_size. 88175eba5b6SRobert Mustacchi **/ 88275eba5b6SRobert Mustacchi s32 e1000_read_pba_length_generic(struct e1000_hw *hw, u32 *pba_num_size) 88375eba5b6SRobert Mustacchi { 88475eba5b6SRobert Mustacchi s32 ret_val; 88575eba5b6SRobert Mustacchi u16 nvm_data; 88675eba5b6SRobert Mustacchi u16 pba_ptr; 88775eba5b6SRobert Mustacchi u16 length; 88875eba5b6SRobert Mustacchi 88975eba5b6SRobert Mustacchi DEBUGFUNC("e1000_read_pba_length_generic"); 89075eba5b6SRobert Mustacchi 89175eba5b6SRobert Mustacchi if (pba_num_size == NULL) { 89275eba5b6SRobert Mustacchi DEBUGOUT("PBA buffer size was null\n"); 89375eba5b6SRobert Mustacchi return -E1000_ERR_INVALID_ARGUMENT; 89475eba5b6SRobert Mustacchi } 89575eba5b6SRobert Mustacchi 89675eba5b6SRobert Mustacchi ret_val = hw->nvm.ops.read(hw, NVM_PBA_OFFSET_0, 1, &nvm_data); 89775eba5b6SRobert Mustacchi if (ret_val) { 89875eba5b6SRobert Mustacchi DEBUGOUT("NVM Read Error\n"); 89975eba5b6SRobert Mustacchi return ret_val; 90075eba5b6SRobert Mustacchi } 90175eba5b6SRobert Mustacchi 90275eba5b6SRobert Mustacchi ret_val = hw->nvm.ops.read(hw, NVM_PBA_OFFSET_1, 1, &pba_ptr); 90375eba5b6SRobert Mustacchi if (ret_val) { 90475eba5b6SRobert Mustacchi DEBUGOUT("NVM Read Error\n"); 90575eba5b6SRobert Mustacchi return ret_val; 90675eba5b6SRobert Mustacchi } 90775eba5b6SRobert Mustacchi 90875eba5b6SRobert Mustacchi /* if data is not ptr guard the PBA must be in legacy format */ 90975eba5b6SRobert Mustacchi if (nvm_data != NVM_PBA_PTR_GUARD) { 91075eba5b6SRobert Mustacchi *pba_num_size = E1000_PBANUM_LENGTH; 91175eba5b6SRobert Mustacchi return E1000_SUCCESS; 91275eba5b6SRobert Mustacchi } 91375eba5b6SRobert Mustacchi 91475eba5b6SRobert Mustacchi ret_val = hw->nvm.ops.read(hw, pba_ptr, 1, &length); 91575eba5b6SRobert Mustacchi if (ret_val) { 91675eba5b6SRobert Mustacchi DEBUGOUT("NVM Read Error\n"); 91775eba5b6SRobert Mustacchi return ret_val; 91875eba5b6SRobert Mustacchi } 91975eba5b6SRobert Mustacchi 92075eba5b6SRobert Mustacchi if (length == 0xFFFF || length == 0) { 92175eba5b6SRobert Mustacchi DEBUGOUT("NVM PBA number section invalid length\n"); 92275eba5b6SRobert Mustacchi return -E1000_ERR_NVM_PBA_SECTION; 92375eba5b6SRobert Mustacchi } 92475eba5b6SRobert Mustacchi 92575eba5b6SRobert Mustacchi /* Convert from length in u16 values to u8 chars, add 1 for NULL, 92675eba5b6SRobert Mustacchi * and subtract 2 because length field is included in length. 92775eba5b6SRobert Mustacchi */ 92875eba5b6SRobert Mustacchi *pba_num_size = ((u32)length * 2) - 1; 92975eba5b6SRobert Mustacchi 93075eba5b6SRobert Mustacchi return E1000_SUCCESS; 93175eba5b6SRobert Mustacchi } 93275eba5b6SRobert Mustacchi 93375eba5b6SRobert Mustacchi 93475eba5b6SRobert Mustacchi /** 93575eba5b6SRobert Mustacchi * e1000_read_pba_raw 93675eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 93775eba5b6SRobert Mustacchi * @eeprom_buf: optional pointer to EEPROM image 93875eba5b6SRobert Mustacchi * @eeprom_buf_size: size of EEPROM image in words 93975eba5b6SRobert Mustacchi * @max_pba_block_size: PBA block size limit 94075eba5b6SRobert Mustacchi * @pba: pointer to output PBA structure 94175eba5b6SRobert Mustacchi * 94275eba5b6SRobert Mustacchi * Reads PBA from EEPROM image when eeprom_buf is not NULL. 94375eba5b6SRobert Mustacchi * Reads PBA from physical EEPROM device when eeprom_buf is NULL. 94475eba5b6SRobert Mustacchi * 94575eba5b6SRobert Mustacchi **/ 94675eba5b6SRobert Mustacchi s32 e1000_read_pba_raw(struct e1000_hw *hw, u16 *eeprom_buf, 94775eba5b6SRobert Mustacchi u32 eeprom_buf_size, u16 max_pba_block_size, 94875eba5b6SRobert Mustacchi struct e1000_pba *pba) 94975eba5b6SRobert Mustacchi { 95075eba5b6SRobert Mustacchi s32 ret_val; 95175eba5b6SRobert Mustacchi u16 pba_block_size; 95275eba5b6SRobert Mustacchi 95375eba5b6SRobert Mustacchi if (pba == NULL) 95475eba5b6SRobert Mustacchi return -E1000_ERR_PARAM; 95575eba5b6SRobert Mustacchi 95675eba5b6SRobert Mustacchi if (eeprom_buf == NULL) { 95775eba5b6SRobert Mustacchi ret_val = e1000_read_nvm(hw, NVM_PBA_OFFSET_0, 2, 95875eba5b6SRobert Mustacchi &pba->word[0]); 95975eba5b6SRobert Mustacchi if (ret_val) 96075eba5b6SRobert Mustacchi return ret_val; 96175eba5b6SRobert Mustacchi } else { 96275eba5b6SRobert Mustacchi if (eeprom_buf_size > NVM_PBA_OFFSET_1) { 96375eba5b6SRobert Mustacchi pba->word[0] = eeprom_buf[NVM_PBA_OFFSET_0]; 96475eba5b6SRobert Mustacchi pba->word[1] = eeprom_buf[NVM_PBA_OFFSET_1]; 96575eba5b6SRobert Mustacchi } else { 96675eba5b6SRobert Mustacchi return -E1000_ERR_PARAM; 96775eba5b6SRobert Mustacchi } 96875eba5b6SRobert Mustacchi } 96975eba5b6SRobert Mustacchi 97075eba5b6SRobert Mustacchi if (pba->word[0] == NVM_PBA_PTR_GUARD) { 97175eba5b6SRobert Mustacchi if (pba->pba_block == NULL) 97275eba5b6SRobert Mustacchi return -E1000_ERR_PARAM; 97375eba5b6SRobert Mustacchi 97475eba5b6SRobert Mustacchi ret_val = e1000_get_pba_block_size(hw, eeprom_buf, 97575eba5b6SRobert Mustacchi eeprom_buf_size, 97675eba5b6SRobert Mustacchi &pba_block_size); 97775eba5b6SRobert Mustacchi if (ret_val) 97875eba5b6SRobert Mustacchi return ret_val; 97975eba5b6SRobert Mustacchi 98075eba5b6SRobert Mustacchi if (pba_block_size > max_pba_block_size) 98175eba5b6SRobert Mustacchi return -E1000_ERR_PARAM; 98275eba5b6SRobert Mustacchi 98375eba5b6SRobert Mustacchi if (eeprom_buf == NULL) { 98475eba5b6SRobert Mustacchi ret_val = e1000_read_nvm(hw, pba->word[1], 98575eba5b6SRobert Mustacchi pba_block_size, 98675eba5b6SRobert Mustacchi pba->pba_block); 98775eba5b6SRobert Mustacchi if (ret_val) 98875eba5b6SRobert Mustacchi return ret_val; 98975eba5b6SRobert Mustacchi } else { 99075eba5b6SRobert Mustacchi if (eeprom_buf_size > (u32)(pba->word[1] + 991c124a83eSRobert Mustacchi pba_block_size)) { 99275eba5b6SRobert Mustacchi memcpy(pba->pba_block, 99375eba5b6SRobert Mustacchi &eeprom_buf[pba->word[1]], 99475eba5b6SRobert Mustacchi pba_block_size * sizeof(u16)); 99575eba5b6SRobert Mustacchi } else { 99675eba5b6SRobert Mustacchi return -E1000_ERR_PARAM; 99775eba5b6SRobert Mustacchi } 99875eba5b6SRobert Mustacchi } 99975eba5b6SRobert Mustacchi } 100075eba5b6SRobert Mustacchi 100175eba5b6SRobert Mustacchi return E1000_SUCCESS; 100275eba5b6SRobert Mustacchi } 100375eba5b6SRobert Mustacchi 100475eba5b6SRobert Mustacchi /** 100575eba5b6SRobert Mustacchi * e1000_write_pba_raw 100675eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 100775eba5b6SRobert Mustacchi * @eeprom_buf: optional pointer to EEPROM image 100875eba5b6SRobert Mustacchi * @eeprom_buf_size: size of EEPROM image in words 100975eba5b6SRobert Mustacchi * @pba: pointer to PBA structure 101075eba5b6SRobert Mustacchi * 101175eba5b6SRobert Mustacchi * Writes PBA to EEPROM image when eeprom_buf is not NULL. 101275eba5b6SRobert Mustacchi * Writes PBA to physical EEPROM device when eeprom_buf is NULL. 101375eba5b6SRobert Mustacchi * 101475eba5b6SRobert Mustacchi **/ 101575eba5b6SRobert Mustacchi s32 e1000_write_pba_raw(struct e1000_hw *hw, u16 *eeprom_buf, 101675eba5b6SRobert Mustacchi u32 eeprom_buf_size, struct e1000_pba *pba) 101775eba5b6SRobert Mustacchi { 101875eba5b6SRobert Mustacchi s32 ret_val; 101975eba5b6SRobert Mustacchi 102075eba5b6SRobert Mustacchi if (pba == NULL) 102175eba5b6SRobert Mustacchi return -E1000_ERR_PARAM; 102275eba5b6SRobert Mustacchi 102375eba5b6SRobert Mustacchi if (eeprom_buf == NULL) { 102475eba5b6SRobert Mustacchi ret_val = e1000_write_nvm(hw, NVM_PBA_OFFSET_0, 2, 102575eba5b6SRobert Mustacchi &pba->word[0]); 102675eba5b6SRobert Mustacchi if (ret_val) 102775eba5b6SRobert Mustacchi return ret_val; 102875eba5b6SRobert Mustacchi } else { 102975eba5b6SRobert Mustacchi if (eeprom_buf_size > NVM_PBA_OFFSET_1) { 103075eba5b6SRobert Mustacchi eeprom_buf[NVM_PBA_OFFSET_0] = pba->word[0]; 103175eba5b6SRobert Mustacchi eeprom_buf[NVM_PBA_OFFSET_1] = pba->word[1]; 103275eba5b6SRobert Mustacchi } else { 103375eba5b6SRobert Mustacchi return -E1000_ERR_PARAM; 103475eba5b6SRobert Mustacchi } 103575eba5b6SRobert Mustacchi } 103675eba5b6SRobert Mustacchi 103775eba5b6SRobert Mustacchi if (pba->word[0] == NVM_PBA_PTR_GUARD) { 103875eba5b6SRobert Mustacchi if (pba->pba_block == NULL) 103975eba5b6SRobert Mustacchi return -E1000_ERR_PARAM; 104075eba5b6SRobert Mustacchi 104175eba5b6SRobert Mustacchi if (eeprom_buf == NULL) { 104275eba5b6SRobert Mustacchi ret_val = e1000_write_nvm(hw, pba->word[1], 104375eba5b6SRobert Mustacchi pba->pba_block[0], 104475eba5b6SRobert Mustacchi pba->pba_block); 104575eba5b6SRobert Mustacchi if (ret_val) 104675eba5b6SRobert Mustacchi return ret_val; 104775eba5b6SRobert Mustacchi } else { 104875eba5b6SRobert Mustacchi if (eeprom_buf_size > (u32)(pba->word[1] + 104975eba5b6SRobert Mustacchi pba->pba_block[0])) { 105075eba5b6SRobert Mustacchi memcpy(&eeprom_buf[pba->word[1]], 105175eba5b6SRobert Mustacchi pba->pba_block, 105275eba5b6SRobert Mustacchi pba->pba_block[0] * sizeof(u16)); 105375eba5b6SRobert Mustacchi } else { 105475eba5b6SRobert Mustacchi return -E1000_ERR_PARAM; 105575eba5b6SRobert Mustacchi } 105675eba5b6SRobert Mustacchi } 105775eba5b6SRobert Mustacchi } 105875eba5b6SRobert Mustacchi 105975eba5b6SRobert Mustacchi return E1000_SUCCESS; 106075eba5b6SRobert Mustacchi } 106175eba5b6SRobert Mustacchi 106275eba5b6SRobert Mustacchi /** 106375eba5b6SRobert Mustacchi * e1000_get_pba_block_size 106475eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 106575eba5b6SRobert Mustacchi * @eeprom_buf: optional pointer to EEPROM image 106675eba5b6SRobert Mustacchi * @eeprom_buf_size: size of EEPROM image in words 106775eba5b6SRobert Mustacchi * @pba_data_size: pointer to output variable 106875eba5b6SRobert Mustacchi * 106975eba5b6SRobert Mustacchi * Returns the size of the PBA block in words. Function operates on EEPROM 107075eba5b6SRobert Mustacchi * image if the eeprom_buf pointer is not NULL otherwise it accesses physical 107175eba5b6SRobert Mustacchi * EEPROM device. 107275eba5b6SRobert Mustacchi * 107375eba5b6SRobert Mustacchi **/ 107475eba5b6SRobert Mustacchi s32 e1000_get_pba_block_size(struct e1000_hw *hw, u16 *eeprom_buf, 107575eba5b6SRobert Mustacchi u32 eeprom_buf_size, u16 *pba_block_size) 107675eba5b6SRobert Mustacchi { 107775eba5b6SRobert Mustacchi s32 ret_val; 107875eba5b6SRobert Mustacchi u16 pba_word[2]; 107975eba5b6SRobert Mustacchi u16 length; 108075eba5b6SRobert Mustacchi 108175eba5b6SRobert Mustacchi DEBUGFUNC("e1000_get_pba_block_size"); 108275eba5b6SRobert Mustacchi 108375eba5b6SRobert Mustacchi if (eeprom_buf == NULL) { 108475eba5b6SRobert Mustacchi ret_val = e1000_read_nvm(hw, NVM_PBA_OFFSET_0, 2, &pba_word[0]); 108575eba5b6SRobert Mustacchi if (ret_val) 108675eba5b6SRobert Mustacchi return ret_val; 108775eba5b6SRobert Mustacchi } else { 108875eba5b6SRobert Mustacchi if (eeprom_buf_size > NVM_PBA_OFFSET_1) { 108975eba5b6SRobert Mustacchi pba_word[0] = eeprom_buf[NVM_PBA_OFFSET_0]; 109075eba5b6SRobert Mustacchi pba_word[1] = eeprom_buf[NVM_PBA_OFFSET_1]; 109175eba5b6SRobert Mustacchi } else { 109275eba5b6SRobert Mustacchi return -E1000_ERR_PARAM; 109375eba5b6SRobert Mustacchi } 109475eba5b6SRobert Mustacchi } 109575eba5b6SRobert Mustacchi 109675eba5b6SRobert Mustacchi if (pba_word[0] == NVM_PBA_PTR_GUARD) { 109775eba5b6SRobert Mustacchi if (eeprom_buf == NULL) { 109875eba5b6SRobert Mustacchi ret_val = e1000_read_nvm(hw, pba_word[1] + 0, 1, 109975eba5b6SRobert Mustacchi &length); 110075eba5b6SRobert Mustacchi if (ret_val) 110175eba5b6SRobert Mustacchi return ret_val; 110275eba5b6SRobert Mustacchi } else { 110375eba5b6SRobert Mustacchi if (eeprom_buf_size > pba_word[1]) 110475eba5b6SRobert Mustacchi length = eeprom_buf[pba_word[1] + 0]; 110575eba5b6SRobert Mustacchi else 110675eba5b6SRobert Mustacchi return -E1000_ERR_PARAM; 110775eba5b6SRobert Mustacchi } 110875eba5b6SRobert Mustacchi 110975eba5b6SRobert Mustacchi if (length == 0xFFFF || length == 0) 111075eba5b6SRobert Mustacchi return -E1000_ERR_NVM_PBA_SECTION; 111175eba5b6SRobert Mustacchi } else { 111275eba5b6SRobert Mustacchi /* PBA number in legacy format, there is no PBA Block. */ 111375eba5b6SRobert Mustacchi length = 0; 111475eba5b6SRobert Mustacchi } 111575eba5b6SRobert Mustacchi 111675eba5b6SRobert Mustacchi if (pba_block_size != NULL) 111775eba5b6SRobert Mustacchi *pba_block_size = length; 111875eba5b6SRobert Mustacchi 111975eba5b6SRobert Mustacchi return E1000_SUCCESS; 112075eba5b6SRobert Mustacchi } 112175eba5b6SRobert Mustacchi 112275eba5b6SRobert Mustacchi /** 112375eba5b6SRobert Mustacchi * e1000_read_mac_addr_generic - Read device MAC address 112475eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 112575eba5b6SRobert Mustacchi * 112675eba5b6SRobert Mustacchi * Reads the device MAC address from the EEPROM and stores the value. 112775eba5b6SRobert Mustacchi * Since devices with two ports use the same EEPROM, we increment the 112875eba5b6SRobert Mustacchi * last bit in the MAC address for the second port. 112975eba5b6SRobert Mustacchi **/ 113075eba5b6SRobert Mustacchi s32 e1000_read_mac_addr_generic(struct e1000_hw *hw) 113175eba5b6SRobert Mustacchi { 113275eba5b6SRobert Mustacchi u32 rar_high; 113375eba5b6SRobert Mustacchi u32 rar_low; 113475eba5b6SRobert Mustacchi u16 i; 113575eba5b6SRobert Mustacchi 113675eba5b6SRobert Mustacchi rar_high = E1000_READ_REG(hw, E1000_RAH(0)); 113775eba5b6SRobert Mustacchi rar_low = E1000_READ_REG(hw, E1000_RAL(0)); 113875eba5b6SRobert Mustacchi 113975eba5b6SRobert Mustacchi for (i = 0; i < E1000_RAL_MAC_ADDR_LEN; i++) 114075eba5b6SRobert Mustacchi hw->mac.perm_addr[i] = (u8)(rar_low >> (i*8)); 114175eba5b6SRobert Mustacchi 114275eba5b6SRobert Mustacchi for (i = 0; i < E1000_RAH_MAC_ADDR_LEN; i++) 114375eba5b6SRobert Mustacchi hw->mac.perm_addr[i+4] = (u8)(rar_high >> (i*8)); 114475eba5b6SRobert Mustacchi 114575eba5b6SRobert Mustacchi for (i = 0; i < ETH_ADDR_LEN; i++) 114675eba5b6SRobert Mustacchi hw->mac.addr[i] = hw->mac.perm_addr[i]; 114775eba5b6SRobert Mustacchi 114875eba5b6SRobert Mustacchi return E1000_SUCCESS; 114975eba5b6SRobert Mustacchi } 115075eba5b6SRobert Mustacchi 115175eba5b6SRobert Mustacchi /** 115275eba5b6SRobert Mustacchi * e1000_validate_nvm_checksum_generic - Validate EEPROM checksum 115375eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 115475eba5b6SRobert Mustacchi * 115575eba5b6SRobert Mustacchi * Calculates the EEPROM checksum by reading/adding each word of the EEPROM 115675eba5b6SRobert Mustacchi * and then verifies that the sum of the EEPROM is equal to 0xBABA. 115775eba5b6SRobert Mustacchi **/ 115875eba5b6SRobert Mustacchi s32 e1000_validate_nvm_checksum_generic(struct e1000_hw *hw) 115975eba5b6SRobert Mustacchi { 116075eba5b6SRobert Mustacchi s32 ret_val; 116175eba5b6SRobert Mustacchi u16 checksum = 0; 116275eba5b6SRobert Mustacchi u16 i, nvm_data; 116375eba5b6SRobert Mustacchi 116475eba5b6SRobert Mustacchi DEBUGFUNC("e1000_validate_nvm_checksum_generic"); 116575eba5b6SRobert Mustacchi 116675eba5b6SRobert Mustacchi for (i = 0; i < (NVM_CHECKSUM_REG + 1); i++) { 116775eba5b6SRobert Mustacchi ret_val = hw->nvm.ops.read(hw, i, 1, &nvm_data); 116875eba5b6SRobert Mustacchi if (ret_val) { 116975eba5b6SRobert Mustacchi DEBUGOUT("NVM Read Error\n"); 117075eba5b6SRobert Mustacchi return ret_val; 117175eba5b6SRobert Mustacchi } 117275eba5b6SRobert Mustacchi checksum += nvm_data; 117375eba5b6SRobert Mustacchi } 117475eba5b6SRobert Mustacchi 117575eba5b6SRobert Mustacchi if (checksum != (u16) NVM_SUM) { 117675eba5b6SRobert Mustacchi DEBUGOUT("NVM Checksum Invalid\n"); 117775eba5b6SRobert Mustacchi return -E1000_ERR_NVM; 117875eba5b6SRobert Mustacchi } 117975eba5b6SRobert Mustacchi 118075eba5b6SRobert Mustacchi return E1000_SUCCESS; 118175eba5b6SRobert Mustacchi } 118275eba5b6SRobert Mustacchi 118375eba5b6SRobert Mustacchi /** 118475eba5b6SRobert Mustacchi * e1000_update_nvm_checksum_generic - Update EEPROM checksum 118575eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 118675eba5b6SRobert Mustacchi * 118775eba5b6SRobert Mustacchi * Updates the EEPROM checksum by reading/adding each word of the EEPROM 118875eba5b6SRobert Mustacchi * up to the checksum. Then calculates the EEPROM checksum and writes the 118975eba5b6SRobert Mustacchi * value to the EEPROM. 119075eba5b6SRobert Mustacchi **/ 119175eba5b6SRobert Mustacchi s32 e1000_update_nvm_checksum_generic(struct e1000_hw *hw) 119275eba5b6SRobert Mustacchi { 119375eba5b6SRobert Mustacchi s32 ret_val; 119475eba5b6SRobert Mustacchi u16 checksum = 0; 119575eba5b6SRobert Mustacchi u16 i, nvm_data; 119675eba5b6SRobert Mustacchi 119775eba5b6SRobert Mustacchi DEBUGFUNC("e1000_update_nvm_checksum"); 119875eba5b6SRobert Mustacchi 119975eba5b6SRobert Mustacchi for (i = 0; i < NVM_CHECKSUM_REG; i++) { 120075eba5b6SRobert Mustacchi ret_val = hw->nvm.ops.read(hw, i, 1, &nvm_data); 120175eba5b6SRobert Mustacchi if (ret_val) { 120275eba5b6SRobert Mustacchi DEBUGOUT("NVM Read Error while updating checksum.\n"); 120375eba5b6SRobert Mustacchi return ret_val; 120475eba5b6SRobert Mustacchi } 120575eba5b6SRobert Mustacchi checksum += nvm_data; 120675eba5b6SRobert Mustacchi } 120775eba5b6SRobert Mustacchi checksum = (u16) NVM_SUM - checksum; 120875eba5b6SRobert Mustacchi ret_val = hw->nvm.ops.write(hw, NVM_CHECKSUM_REG, 1, &checksum); 120975eba5b6SRobert Mustacchi if (ret_val) 121075eba5b6SRobert Mustacchi DEBUGOUT("NVM Write Error while updating checksum.\n"); 121175eba5b6SRobert Mustacchi 121275eba5b6SRobert Mustacchi return ret_val; 121375eba5b6SRobert Mustacchi } 121475eba5b6SRobert Mustacchi 121575eba5b6SRobert Mustacchi /** 121675eba5b6SRobert Mustacchi * e1000_reload_nvm_generic - Reloads EEPROM 121775eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 121875eba5b6SRobert Mustacchi * 121975eba5b6SRobert Mustacchi * Reloads the EEPROM by setting the "Reinitialize from EEPROM" bit in the 122075eba5b6SRobert Mustacchi * extended control register. 122175eba5b6SRobert Mustacchi **/ 122275eba5b6SRobert Mustacchi static void e1000_reload_nvm_generic(struct e1000_hw *hw) 122375eba5b6SRobert Mustacchi { 122475eba5b6SRobert Mustacchi u32 ctrl_ext; 122575eba5b6SRobert Mustacchi 122675eba5b6SRobert Mustacchi DEBUGFUNC("e1000_reload_nvm_generic"); 122775eba5b6SRobert Mustacchi 122875eba5b6SRobert Mustacchi usec_delay(10); 122975eba5b6SRobert Mustacchi ctrl_ext = E1000_READ_REG(hw, E1000_CTRL_EXT); 123075eba5b6SRobert Mustacchi ctrl_ext |= E1000_CTRL_EXT_EE_RST; 123175eba5b6SRobert Mustacchi E1000_WRITE_REG(hw, E1000_CTRL_EXT, ctrl_ext); 123275eba5b6SRobert Mustacchi E1000_WRITE_FLUSH(hw); 123375eba5b6SRobert Mustacchi } 1234c124a83eSRobert Mustacchi 1235c124a83eSRobert Mustacchi 1236