1177867Sjfv/****************************************************************************** 2169240Sjfv 3248292Sjfv Copyright (c) 2001-2013, Intel Corporation 4169240Sjfv All rights reserved. 5169240Sjfv 6169240Sjfv Redistribution and use in source and binary forms, with or without 7169240Sjfv modification, are permitted provided that the following conditions are met: 8169240Sjfv 9169240Sjfv 1. Redistributions of source code must retain the above copyright notice, 10169240Sjfv this list of conditions and the following disclaimer. 11169240Sjfv 12169240Sjfv 2. Redistributions in binary form must reproduce the above copyright 13169240Sjfv notice, this list of conditions and the following disclaimer in the 14169240Sjfv documentation and/or other materials provided with the distribution. 15169240Sjfv 16169240Sjfv 3. Neither the name of the Intel Corporation nor the names of its 17169240Sjfv contributors may be used to endorse or promote products derived from 18169240Sjfv this software without specific prior written permission. 19169240Sjfv 20169240Sjfv THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21169240Sjfv AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22169240Sjfv IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23169240Sjfv ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 24169240Sjfv LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25169240Sjfv CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26169240Sjfv SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27169240Sjfv INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28169240Sjfv CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29169240Sjfv ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30169240Sjfv POSSIBILITY OF SUCH DAMAGE. 31169240Sjfv 32177867Sjfv******************************************************************************/ 33177867Sjfv/*$FreeBSD$*/ 34169240Sjfv 35169589Sjfv#include "e1000_api.h" 36169240Sjfv 37190872Sjfvstatic void e1000_reload_nvm_generic(struct e1000_hw *hw); 38190872Sjfv 39169240Sjfv/** 40177867Sjfv * e1000_init_nvm_ops_generic - Initialize NVM function pointers 41177867Sjfv * @hw: pointer to the HW structure 42177867Sjfv * 43177867Sjfv * Setups up the function pointers to no-op functions 44177867Sjfv **/ 45177867Sjfvvoid e1000_init_nvm_ops_generic(struct e1000_hw *hw) 46177867Sjfv{ 47177867Sjfv struct e1000_nvm_info *nvm = &hw->nvm; 48177867Sjfv DEBUGFUNC("e1000_init_nvm_ops_generic"); 49177867Sjfv 50177867Sjfv /* Initialize function pointers */ 51177867Sjfv nvm->ops.init_params = e1000_null_ops_generic; 52177867Sjfv nvm->ops.acquire = e1000_null_ops_generic; 53177867Sjfv nvm->ops.read = e1000_null_read_nvm; 54177867Sjfv nvm->ops.release = e1000_null_nvm_generic; 55177867Sjfv nvm->ops.reload = e1000_reload_nvm_generic; 56177867Sjfv nvm->ops.update = e1000_null_ops_generic; 57177867Sjfv nvm->ops.valid_led_default = e1000_null_led_default; 58177867Sjfv nvm->ops.validate = e1000_null_ops_generic; 59177867Sjfv nvm->ops.write = e1000_null_write_nvm; 60177867Sjfv} 61177867Sjfv 62177867Sjfv/** 63177867Sjfv * e1000_null_nvm_read - No-op function, return 0 64177867Sjfv * @hw: pointer to the HW structure 65177867Sjfv **/ 66177867Sjfvs32 e1000_null_read_nvm(struct e1000_hw *hw, u16 a, u16 b, u16 *c) 67177867Sjfv{ 68177867Sjfv DEBUGFUNC("e1000_null_read_nvm"); 69177867Sjfv return E1000_SUCCESS; 70177867Sjfv} 71177867Sjfv 72177867Sjfv/** 73177867Sjfv * e1000_null_nvm_generic - No-op function, return void 74177867Sjfv * @hw: pointer to the HW structure 75177867Sjfv **/ 76177867Sjfvvoid e1000_null_nvm_generic(struct e1000_hw *hw) 77177867Sjfv{ 78177867Sjfv DEBUGFUNC("e1000_null_nvm_generic"); 79177867Sjfv return; 80177867Sjfv} 81177867Sjfv 82177867Sjfv/** 83177867Sjfv * e1000_null_led_default - No-op function, return 0 84177867Sjfv * @hw: pointer to the HW structure 85177867Sjfv **/ 86177867Sjfvs32 e1000_null_led_default(struct e1000_hw *hw, u16 *data) 87177867Sjfv{ 88177867Sjfv DEBUGFUNC("e1000_null_led_default"); 89177867Sjfv return E1000_SUCCESS; 90177867Sjfv} 91177867Sjfv 92177867Sjfv/** 93177867Sjfv * e1000_null_write_nvm - No-op function, return 0 94177867Sjfv * @hw: pointer to the HW structure 95177867Sjfv **/ 96177867Sjfvs32 e1000_null_write_nvm(struct e1000_hw *hw, u16 a, u16 b, u16 *c) 97177867Sjfv{ 98177867Sjfv DEBUGFUNC("e1000_null_write_nvm"); 99177867Sjfv return E1000_SUCCESS; 100177867Sjfv} 101177867Sjfv 102177867Sjfv/** 103169240Sjfv * e1000_raise_eec_clk - Raise EEPROM clock 104169589Sjfv * @hw: pointer to the HW structure 105169589Sjfv * @eecd: pointer to the EEPROM 106169240Sjfv * 107169240Sjfv * Enable/Raise the EEPROM clock bit. 108169240Sjfv **/ 109173788Sjfvstatic void e1000_raise_eec_clk(struct e1000_hw *hw, u32 *eecd) 110169240Sjfv{ 111169240Sjfv *eecd = *eecd | E1000_EECD_SK; 112169240Sjfv E1000_WRITE_REG(hw, E1000_EECD, *eecd); 113169240Sjfv E1000_WRITE_FLUSH(hw); 114169240Sjfv usec_delay(hw->nvm.delay_usec); 115169240Sjfv} 116169240Sjfv 117169240Sjfv/** 118169240Sjfv * e1000_lower_eec_clk - Lower EEPROM clock 119169589Sjfv * @hw: pointer to the HW structure 120169589Sjfv * @eecd: pointer to the EEPROM 121169240Sjfv * 122169240Sjfv * Clear/Lower the EEPROM clock bit. 123169240Sjfv **/ 124173788Sjfvstatic void e1000_lower_eec_clk(struct e1000_hw *hw, u32 *eecd) 125169240Sjfv{ 126169240Sjfv *eecd = *eecd & ~E1000_EECD_SK; 127169240Sjfv E1000_WRITE_REG(hw, E1000_EECD, *eecd); 128169240Sjfv E1000_WRITE_FLUSH(hw); 129169240Sjfv usec_delay(hw->nvm.delay_usec); 130169240Sjfv} 131169240Sjfv 132169240Sjfv/** 133169240Sjfv * e1000_shift_out_eec_bits - Shift data bits our to the EEPROM 134169589Sjfv * @hw: pointer to the HW structure 135169589Sjfv * @data: data to send to the EEPROM 136169589Sjfv * @count: number of bits to shift out 137169240Sjfv * 138169240Sjfv * We need to shift 'count' bits out to the EEPROM. So, the value in the 139169240Sjfv * "data" parameter will be shifted out to the EEPROM one bit at a time. 140169240Sjfv * In order to do this, "data" must be broken down into bits. 141169240Sjfv **/ 142173788Sjfvstatic void e1000_shift_out_eec_bits(struct e1000_hw *hw, u16 data, u16 count) 143169240Sjfv{ 144169240Sjfv struct e1000_nvm_info *nvm = &hw->nvm; 145169240Sjfv u32 eecd = E1000_READ_REG(hw, E1000_EECD); 146169240Sjfv u32 mask; 147169240Sjfv 148169240Sjfv DEBUGFUNC("e1000_shift_out_eec_bits"); 149169240Sjfv 150169240Sjfv mask = 0x01 << (count - 1); 151169240Sjfv if (nvm->type == e1000_nvm_eeprom_microwire) 152169240Sjfv eecd &= ~E1000_EECD_DO; 153185353Sjfv else 154185353Sjfv if (nvm->type == e1000_nvm_eeprom_spi) 155169240Sjfv eecd |= E1000_EECD_DO; 156169240Sjfv 157169240Sjfv do { 158169240Sjfv eecd &= ~E1000_EECD_DI; 159169240Sjfv 160169240Sjfv if (data & mask) 161169240Sjfv eecd |= E1000_EECD_DI; 162169240Sjfv 163169240Sjfv E1000_WRITE_REG(hw, E1000_EECD, eecd); 164169240Sjfv E1000_WRITE_FLUSH(hw); 165169240Sjfv 166169240Sjfv usec_delay(nvm->delay_usec); 167169240Sjfv 168169240Sjfv e1000_raise_eec_clk(hw, &eecd); 169169240Sjfv e1000_lower_eec_clk(hw, &eecd); 170169240Sjfv 171169240Sjfv mask >>= 1; 172169240Sjfv } while (mask); 173169240Sjfv 174169240Sjfv eecd &= ~E1000_EECD_DI; 175169240Sjfv E1000_WRITE_REG(hw, E1000_EECD, eecd); 176169240Sjfv} 177169240Sjfv 178169240Sjfv/** 179169240Sjfv * e1000_shift_in_eec_bits - Shift data bits in from the EEPROM 180169589Sjfv * @hw: pointer to the HW structure 181169589Sjfv * @count: number of bits to shift in 182169240Sjfv * 183169240Sjfv * In order to read a register from the EEPROM, we need to shift 'count' bits 184169240Sjfv * in from the EEPROM. Bits are "shifted in" by raising the clock input to 185169240Sjfv * the EEPROM (setting the SK bit), and then reading the value of the data out 186169240Sjfv * "DO" bit. During this "shifting in" process the data in "DI" bit should 187169240Sjfv * always be clear. 188169240Sjfv **/ 189173788Sjfvstatic u16 e1000_shift_in_eec_bits(struct e1000_hw *hw, u16 count) 190169240Sjfv{ 191169240Sjfv u32 eecd; 192169240Sjfv u32 i; 193169240Sjfv u16 data; 194169240Sjfv 195169240Sjfv DEBUGFUNC("e1000_shift_in_eec_bits"); 196169240Sjfv 197169240Sjfv eecd = E1000_READ_REG(hw, E1000_EECD); 198169240Sjfv 199169240Sjfv eecd &= ~(E1000_EECD_DO | E1000_EECD_DI); 200169240Sjfv data = 0; 201169240Sjfv 202169240Sjfv for (i = 0; i < count; i++) { 203169240Sjfv data <<= 1; 204169240Sjfv e1000_raise_eec_clk(hw, &eecd); 205169240Sjfv 206169240Sjfv eecd = E1000_READ_REG(hw, E1000_EECD); 207169240Sjfv 208169240Sjfv eecd &= ~E1000_EECD_DI; 209169240Sjfv if (eecd & E1000_EECD_DO) 210169240Sjfv data |= 1; 211169240Sjfv 212169240Sjfv e1000_lower_eec_clk(hw, &eecd); 213169240Sjfv } 214169240Sjfv 215169240Sjfv return data; 216169240Sjfv} 217169240Sjfv 218169240Sjfv/** 219169240Sjfv * e1000_poll_eerd_eewr_done - Poll for EEPROM read/write completion 220169589Sjfv * @hw: pointer to the HW structure 221169589Sjfv * @ee_reg: EEPROM flag for polling 222169240Sjfv * 223169240Sjfv * Polls the EEPROM status bit for either read or write completion based 224169240Sjfv * upon the value of 'ee_reg'. 225169240Sjfv **/ 226173788Sjfvs32 e1000_poll_eerd_eewr_done(struct e1000_hw *hw, int ee_reg) 227169240Sjfv{ 228169240Sjfv u32 attempts = 100000; 229169240Sjfv u32 i, reg = 0; 230169240Sjfv 231169240Sjfv DEBUGFUNC("e1000_poll_eerd_eewr_done"); 232169240Sjfv 233169240Sjfv for (i = 0; i < attempts; i++) { 234169240Sjfv if (ee_reg == E1000_NVM_POLL_READ) 235169240Sjfv reg = E1000_READ_REG(hw, E1000_EERD); 236169240Sjfv else 237169240Sjfv reg = E1000_READ_REG(hw, E1000_EEWR); 238169240Sjfv 239248292Sjfv if (reg & E1000_NVM_RW_REG_DONE) 240248292Sjfv return E1000_SUCCESS; 241169240Sjfv 242169240Sjfv usec_delay(5); 243169240Sjfv } 244169240Sjfv 245248292Sjfv return -E1000_ERR_NVM; 246169240Sjfv} 247169240Sjfv 248169240Sjfv/** 249169240Sjfv * e1000_acquire_nvm_generic - Generic request for access to EEPROM 250169589Sjfv * @hw: pointer to the HW structure 251169240Sjfv * 252169240Sjfv * Set the EEPROM access request bit and wait for EEPROM access grant bit. 253169240Sjfv * Return successful if access grant bit set, else clear the request for 254169240Sjfv * EEPROM access and return -E1000_ERR_NVM (-1). 255169240Sjfv **/ 256173788Sjfvs32 e1000_acquire_nvm_generic(struct e1000_hw *hw) 257169240Sjfv{ 258169240Sjfv u32 eecd = E1000_READ_REG(hw, E1000_EECD); 259169240Sjfv s32 timeout = E1000_NVM_GRANT_ATTEMPTS; 260169240Sjfv 261169240Sjfv DEBUGFUNC("e1000_acquire_nvm_generic"); 262169240Sjfv 263169240Sjfv E1000_WRITE_REG(hw, E1000_EECD, eecd | E1000_EECD_REQ); 264169240Sjfv eecd = E1000_READ_REG(hw, E1000_EECD); 265169240Sjfv 266169240Sjfv while (timeout) { 267169240Sjfv if (eecd & E1000_EECD_GNT) 268169240Sjfv break; 269169240Sjfv usec_delay(5); 270169240Sjfv eecd = E1000_READ_REG(hw, E1000_EECD); 271169240Sjfv timeout--; 272169240Sjfv } 273169240Sjfv 274169240Sjfv if (!timeout) { 275169240Sjfv eecd &= ~E1000_EECD_REQ; 276169240Sjfv E1000_WRITE_REG(hw, E1000_EECD, eecd); 277169240Sjfv DEBUGOUT("Could not acquire NVM grant\n"); 278248292Sjfv return -E1000_ERR_NVM; 279169240Sjfv } 280169240Sjfv 281248292Sjfv return E1000_SUCCESS; 282169240Sjfv} 283169240Sjfv 284169240Sjfv/** 285169240Sjfv * e1000_standby_nvm - Return EEPROM to standby state 286169589Sjfv * @hw: pointer to the HW structure 287169240Sjfv * 288169240Sjfv * Return the EEPROM to a standby state. 289169240Sjfv **/ 290173788Sjfvstatic void e1000_standby_nvm(struct e1000_hw *hw) 291169240Sjfv{ 292169240Sjfv struct e1000_nvm_info *nvm = &hw->nvm; 293169240Sjfv u32 eecd = E1000_READ_REG(hw, E1000_EECD); 294169240Sjfv 295169240Sjfv DEBUGFUNC("e1000_standby_nvm"); 296169240Sjfv 297169240Sjfv if (nvm->type == e1000_nvm_eeprom_microwire) { 298169240Sjfv eecd &= ~(E1000_EECD_CS | E1000_EECD_SK); 299169240Sjfv E1000_WRITE_REG(hw, E1000_EECD, eecd); 300169240Sjfv E1000_WRITE_FLUSH(hw); 301169240Sjfv usec_delay(nvm->delay_usec); 302169240Sjfv 303169240Sjfv e1000_raise_eec_clk(hw, &eecd); 304169240Sjfv 305169240Sjfv /* Select EEPROM */ 306169240Sjfv eecd |= E1000_EECD_CS; 307169240Sjfv E1000_WRITE_REG(hw, E1000_EECD, eecd); 308169240Sjfv E1000_WRITE_FLUSH(hw); 309169240Sjfv usec_delay(nvm->delay_usec); 310169240Sjfv 311169240Sjfv e1000_lower_eec_clk(hw, &eecd); 312235527Sjfv } else if (nvm->type == e1000_nvm_eeprom_spi) { 313169240Sjfv /* Toggle CS to flush commands */ 314169240Sjfv eecd |= E1000_EECD_CS; 315169240Sjfv E1000_WRITE_REG(hw, E1000_EECD, eecd); 316169240Sjfv E1000_WRITE_FLUSH(hw); 317169240Sjfv usec_delay(nvm->delay_usec); 318169240Sjfv eecd &= ~E1000_EECD_CS; 319169240Sjfv E1000_WRITE_REG(hw, E1000_EECD, eecd); 320169240Sjfv E1000_WRITE_FLUSH(hw); 321169240Sjfv usec_delay(nvm->delay_usec); 322169240Sjfv } 323169240Sjfv} 324169240Sjfv 325169240Sjfv/** 326169240Sjfv * e1000_stop_nvm - Terminate EEPROM command 327169589Sjfv * @hw: pointer to the HW structure 328169240Sjfv * 329169240Sjfv * Terminates the current command by inverting the EEPROM's chip select pin. 330169240Sjfv **/ 331173788Sjfvvoid e1000_stop_nvm(struct e1000_hw *hw) 332169240Sjfv{ 333169240Sjfv u32 eecd; 334169240Sjfv 335169240Sjfv DEBUGFUNC("e1000_stop_nvm"); 336169240Sjfv 337169240Sjfv eecd = E1000_READ_REG(hw, E1000_EECD); 338169240Sjfv if (hw->nvm.type == e1000_nvm_eeprom_spi) { 339169240Sjfv /* Pull CS high */ 340169240Sjfv eecd |= E1000_EECD_CS; 341169240Sjfv e1000_lower_eec_clk(hw, &eecd); 342169240Sjfv } else if (hw->nvm.type == e1000_nvm_eeprom_microwire) { 343176667Sjfv /* CS on Microwire is active-high */ 344169240Sjfv eecd &= ~(E1000_EECD_CS | E1000_EECD_DI); 345169240Sjfv E1000_WRITE_REG(hw, E1000_EECD, eecd); 346169240Sjfv e1000_raise_eec_clk(hw, &eecd); 347169240Sjfv e1000_lower_eec_clk(hw, &eecd); 348169240Sjfv } 349169240Sjfv} 350169240Sjfv 351169240Sjfv/** 352169240Sjfv * e1000_release_nvm_generic - Release exclusive access to EEPROM 353169589Sjfv * @hw: pointer to the HW structure 354169240Sjfv * 355169240Sjfv * Stop any current commands to the EEPROM and clear the EEPROM request bit. 356169240Sjfv **/ 357173788Sjfvvoid e1000_release_nvm_generic(struct e1000_hw *hw) 358169240Sjfv{ 359169240Sjfv u32 eecd; 360169240Sjfv 361169240Sjfv DEBUGFUNC("e1000_release_nvm_generic"); 362169240Sjfv 363169240Sjfv e1000_stop_nvm(hw); 364169240Sjfv 365169240Sjfv eecd = E1000_READ_REG(hw, E1000_EECD); 366169240Sjfv eecd &= ~E1000_EECD_REQ; 367169240Sjfv E1000_WRITE_REG(hw, E1000_EECD, eecd); 368169240Sjfv} 369169240Sjfv 370169240Sjfv/** 371169240Sjfv * e1000_ready_nvm_eeprom - Prepares EEPROM for read/write 372169589Sjfv * @hw: pointer to the HW structure 373169240Sjfv * 374169240Sjfv * Setups the EEPROM for reading and writing. 375169240Sjfv **/ 376173788Sjfvstatic s32 e1000_ready_nvm_eeprom(struct e1000_hw *hw) 377169240Sjfv{ 378169240Sjfv struct e1000_nvm_info *nvm = &hw->nvm; 379169240Sjfv u32 eecd = E1000_READ_REG(hw, E1000_EECD); 380169240Sjfv u8 spi_stat_reg; 381169240Sjfv 382169240Sjfv DEBUGFUNC("e1000_ready_nvm_eeprom"); 383169240Sjfv 384169240Sjfv if (nvm->type == e1000_nvm_eeprom_microwire) { 385169240Sjfv /* Clear SK and DI */ 386169240Sjfv eecd &= ~(E1000_EECD_DI | E1000_EECD_SK); 387169240Sjfv E1000_WRITE_REG(hw, E1000_EECD, eecd); 388169240Sjfv /* Set CS */ 389169240Sjfv eecd |= E1000_EECD_CS; 390169240Sjfv E1000_WRITE_REG(hw, E1000_EECD, eecd); 391235527Sjfv } else if (nvm->type == e1000_nvm_eeprom_spi) { 392218530Sjfv u16 timeout = NVM_MAX_RETRY_SPI; 393218530Sjfv 394169240Sjfv /* Clear SK and CS */ 395169240Sjfv eecd &= ~(E1000_EECD_CS | E1000_EECD_SK); 396169240Sjfv E1000_WRITE_REG(hw, E1000_EECD, eecd); 397235527Sjfv E1000_WRITE_FLUSH(hw); 398169240Sjfv usec_delay(1); 399169240Sjfv 400248292Sjfv /* Read "Status Register" repeatedly until the LSB is cleared. 401169240Sjfv * The EEPROM will signal that the command has been completed 402169240Sjfv * by clearing bit 0 of the internal status register. If it's 403173788Sjfv * not cleared within 'timeout', then error out. 404173788Sjfv */ 405169240Sjfv while (timeout) { 406169240Sjfv e1000_shift_out_eec_bits(hw, NVM_RDSR_OPCODE_SPI, 407235527Sjfv hw->nvm.opcode_bits); 408169240Sjfv spi_stat_reg = (u8)e1000_shift_in_eec_bits(hw, 8); 409169240Sjfv if (!(spi_stat_reg & NVM_STATUS_RDY_SPI)) 410169240Sjfv break; 411169240Sjfv 412169240Sjfv usec_delay(5); 413169240Sjfv e1000_standby_nvm(hw); 414169240Sjfv timeout--; 415169240Sjfv } 416169240Sjfv 417169240Sjfv if (!timeout) { 418169240Sjfv DEBUGOUT("SPI NVM Status error\n"); 419248292Sjfv return -E1000_ERR_NVM; 420169240Sjfv } 421169240Sjfv } 422169240Sjfv 423248292Sjfv return E1000_SUCCESS; 424169240Sjfv} 425169240Sjfv 426169240Sjfv/** 427169240Sjfv * e1000_read_nvm_spi - Read EEPROM's using SPI 428169589Sjfv * @hw: pointer to the HW structure 429169589Sjfv * @offset: offset of word in the EEPROM to read 430169589Sjfv * @words: number of words to read 431169589Sjfv * @data: word read from the EEPROM 432169240Sjfv * 433169240Sjfv * Reads a 16 bit word from the EEPROM. 434169240Sjfv **/ 435173788Sjfvs32 e1000_read_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data) 436169240Sjfv{ 437169240Sjfv struct e1000_nvm_info *nvm = &hw->nvm; 438169240Sjfv u32 i = 0; 439169240Sjfv s32 ret_val; 440169240Sjfv u16 word_in; 441169240Sjfv u8 read_opcode = NVM_READ_OPCODE_SPI; 442169240Sjfv 443169240Sjfv DEBUGFUNC("e1000_read_nvm_spi"); 444169240Sjfv 445248292Sjfv /* A check for invalid values: offset too large, too many words, 446173788Sjfv * and not enough words. 447173788Sjfv */ 448169240Sjfv if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) || 449169240Sjfv (words == 0)) { 450169240Sjfv DEBUGOUT("nvm parameter(s) out of bounds\n"); 451248292Sjfv return -E1000_ERR_NVM; 452169240Sjfv } 453169240Sjfv 454177867Sjfv ret_val = nvm->ops.acquire(hw); 455169240Sjfv if (ret_val) 456248292Sjfv return ret_val; 457169240Sjfv 458169240Sjfv ret_val = e1000_ready_nvm_eeprom(hw); 459169240Sjfv if (ret_val) 460169240Sjfv goto release; 461169240Sjfv 462169240Sjfv e1000_standby_nvm(hw); 463169240Sjfv 464169240Sjfv if ((nvm->address_bits == 8) && (offset >= 128)) 465169240Sjfv read_opcode |= NVM_A8_OPCODE_SPI; 466169240Sjfv 467169240Sjfv /* Send the READ command (opcode + addr) */ 468169240Sjfv e1000_shift_out_eec_bits(hw, read_opcode, nvm->opcode_bits); 469169240Sjfv e1000_shift_out_eec_bits(hw, (u16)(offset*2), nvm->address_bits); 470169240Sjfv 471248292Sjfv /* Read the data. SPI NVMs increment the address with each byte 472169240Sjfv * read and will roll over if reading beyond the end. This allows 473173788Sjfv * us to read the whole NVM from any offset 474173788Sjfv */ 475169240Sjfv for (i = 0; i < words; i++) { 476169240Sjfv word_in = e1000_shift_in_eec_bits(hw, 16); 477169240Sjfv data[i] = (word_in >> 8) | (word_in << 8); 478169240Sjfv } 479169240Sjfv 480169240Sjfvrelease: 481177867Sjfv nvm->ops.release(hw); 482169240Sjfv 483169240Sjfv return ret_val; 484169240Sjfv} 485169240Sjfv 486169240Sjfv/** 487169240Sjfv * e1000_read_nvm_microwire - Reads EEPROM's using microwire 488169589Sjfv * @hw: pointer to the HW structure 489169589Sjfv * @offset: offset of word in the EEPROM to read 490169589Sjfv * @words: number of words to read 491169589Sjfv * @data: word read from the EEPROM 492169240Sjfv * 493169240Sjfv * Reads a 16 bit word from the EEPROM. 494169240Sjfv **/ 495173788Sjfvs32 e1000_read_nvm_microwire(struct e1000_hw *hw, u16 offset, u16 words, 496235527Sjfv u16 *data) 497169240Sjfv{ 498169240Sjfv struct e1000_nvm_info *nvm = &hw->nvm; 499169240Sjfv u32 i = 0; 500169240Sjfv s32 ret_val; 501169240Sjfv u8 read_opcode = NVM_READ_OPCODE_MICROWIRE; 502169240Sjfv 503169240Sjfv DEBUGFUNC("e1000_read_nvm_microwire"); 504169240Sjfv 505248292Sjfv /* A check for invalid values: offset too large, too many words, 506173788Sjfv * and not enough words. 507173788Sjfv */ 508169240Sjfv if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) || 509169240Sjfv (words == 0)) { 510169240Sjfv DEBUGOUT("nvm parameter(s) out of bounds\n"); 511248292Sjfv return -E1000_ERR_NVM; 512169240Sjfv } 513169240Sjfv 514177867Sjfv ret_val = nvm->ops.acquire(hw); 515169240Sjfv if (ret_val) 516248292Sjfv return ret_val; 517169240Sjfv 518169240Sjfv ret_val = e1000_ready_nvm_eeprom(hw); 519169240Sjfv if (ret_val) 520169240Sjfv goto release; 521169240Sjfv 522169240Sjfv for (i = 0; i < words; i++) { 523169240Sjfv /* Send the READ command (opcode + addr) */ 524169240Sjfv e1000_shift_out_eec_bits(hw, read_opcode, nvm->opcode_bits); 525169240Sjfv e1000_shift_out_eec_bits(hw, (u16)(offset + i), 526169240Sjfv nvm->address_bits); 527169240Sjfv 528248292Sjfv /* Read the data. For microwire, each word requires the 529173788Sjfv * overhead of setup and tear-down. 530173788Sjfv */ 531169240Sjfv data[i] = e1000_shift_in_eec_bits(hw, 16); 532169240Sjfv e1000_standby_nvm(hw); 533169240Sjfv } 534169240Sjfv 535169240Sjfvrelease: 536177867Sjfv nvm->ops.release(hw); 537169240Sjfv 538169240Sjfv return ret_val; 539169240Sjfv} 540169240Sjfv 541169240Sjfv/** 542169240Sjfv * e1000_read_nvm_eerd - Reads EEPROM using EERD register 543169589Sjfv * @hw: pointer to the HW structure 544169589Sjfv * @offset: offset of word in the EEPROM to read 545169589Sjfv * @words: number of words to read 546169589Sjfv * @data: word read from the EEPROM 547169240Sjfv * 548169240Sjfv * Reads a 16 bit word from the EEPROM using the EERD register. 549169240Sjfv **/ 550173788Sjfvs32 e1000_read_nvm_eerd(struct e1000_hw *hw, u16 offset, u16 words, u16 *data) 551169240Sjfv{ 552169240Sjfv struct e1000_nvm_info *nvm = &hw->nvm; 553169240Sjfv u32 i, eerd = 0; 554169240Sjfv s32 ret_val = E1000_SUCCESS; 555169240Sjfv 556169240Sjfv DEBUGFUNC("e1000_read_nvm_eerd"); 557169240Sjfv 558248292Sjfv /* A check for invalid values: offset too large, too many words, 559173788Sjfv * too many words for the offset, and not enough words. 560173788Sjfv */ 561169240Sjfv if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) || 562169240Sjfv (words == 0)) { 563169240Sjfv DEBUGOUT("nvm parameter(s) out of bounds\n"); 564248292Sjfv return -E1000_ERR_NVM; 565169240Sjfv } 566169240Sjfv 567169240Sjfv for (i = 0; i < words; i++) { 568169240Sjfv eerd = ((offset+i) << E1000_NVM_RW_ADDR_SHIFT) + 569169240Sjfv E1000_NVM_RW_REG_START; 570169240Sjfv 571169240Sjfv E1000_WRITE_REG(hw, E1000_EERD, eerd); 572169240Sjfv ret_val = e1000_poll_eerd_eewr_done(hw, E1000_NVM_POLL_READ); 573169240Sjfv if (ret_val) 574169240Sjfv break; 575169240Sjfv 576173788Sjfv data[i] = (E1000_READ_REG(hw, E1000_EERD) >> 577235527Sjfv E1000_NVM_RW_REG_DATA); 578169240Sjfv } 579169240Sjfv 580169240Sjfv return ret_val; 581169240Sjfv} 582169240Sjfv 583169240Sjfv/** 584169240Sjfv * e1000_write_nvm_spi - Write to EEPROM using SPI 585169589Sjfv * @hw: pointer to the HW structure 586169589Sjfv * @offset: offset within the EEPROM to be written to 587169589Sjfv * @words: number of words to write 588169589Sjfv * @data: 16 bit word(s) to be written to the EEPROM 589169240Sjfv * 590169240Sjfv * Writes data to EEPROM at offset using SPI interface. 591169240Sjfv * 592169240Sjfv * If e1000_update_nvm_checksum is not called after this function , the 593176667Sjfv * EEPROM will most likely contain an invalid checksum. 594169240Sjfv **/ 595173788Sjfvs32 e1000_write_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data) 596169240Sjfv{ 597169240Sjfv struct e1000_nvm_info *nvm = &hw->nvm; 598248292Sjfv s32 ret_val = -E1000_ERR_NVM; 599169240Sjfv u16 widx = 0; 600169240Sjfv 601169240Sjfv DEBUGFUNC("e1000_write_nvm_spi"); 602169240Sjfv 603248292Sjfv /* A check for invalid values: offset too large, too many words, 604173788Sjfv * and not enough words. 605173788Sjfv */ 606169240Sjfv if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) || 607169240Sjfv (words == 0)) { 608169240Sjfv DEBUGOUT("nvm parameter(s) out of bounds\n"); 609248292Sjfv return -E1000_ERR_NVM; 610169240Sjfv } 611169240Sjfv 612169240Sjfv while (widx < words) { 613169240Sjfv u8 write_opcode = NVM_WRITE_OPCODE_SPI; 614169240Sjfv 615248292Sjfv ret_val = nvm->ops.acquire(hw); 616169240Sjfv if (ret_val) 617248292Sjfv return ret_val; 618169240Sjfv 619248292Sjfv ret_val = e1000_ready_nvm_eeprom(hw); 620248292Sjfv if (ret_val) { 621248292Sjfv nvm->ops.release(hw); 622248292Sjfv return ret_val; 623248292Sjfv } 624248292Sjfv 625169240Sjfv e1000_standby_nvm(hw); 626169240Sjfv 627169240Sjfv /* Send the WRITE ENABLE command (8 bit opcode) */ 628169240Sjfv e1000_shift_out_eec_bits(hw, NVM_WREN_OPCODE_SPI, 629235527Sjfv nvm->opcode_bits); 630169240Sjfv 631169240Sjfv e1000_standby_nvm(hw); 632169240Sjfv 633248292Sjfv /* Some SPI eeproms use the 8th address bit embedded in the 634173788Sjfv * opcode 635173788Sjfv */ 636169240Sjfv if ((nvm->address_bits == 8) && (offset >= 128)) 637169240Sjfv write_opcode |= NVM_A8_OPCODE_SPI; 638169240Sjfv 639169240Sjfv /* Send the Write command (8-bit opcode + addr) */ 640169240Sjfv e1000_shift_out_eec_bits(hw, write_opcode, nvm->opcode_bits); 641169240Sjfv e1000_shift_out_eec_bits(hw, (u16)((offset + widx) * 2), 642235527Sjfv nvm->address_bits); 643169240Sjfv 644169240Sjfv /* Loop to allow for up to whole page write of eeprom */ 645169240Sjfv while (widx < words) { 646169240Sjfv u16 word_out = data[widx]; 647169240Sjfv word_out = (word_out >> 8) | (word_out << 8); 648169240Sjfv e1000_shift_out_eec_bits(hw, word_out, 16); 649169240Sjfv widx++; 650169240Sjfv 651169240Sjfv if ((((offset + widx) * 2) % nvm->page_size) == 0) { 652169240Sjfv e1000_standby_nvm(hw); 653169240Sjfv break; 654169240Sjfv } 655169240Sjfv } 656248292Sjfv msec_delay(10); 657248292Sjfv nvm->ops.release(hw); 658169240Sjfv } 659169240Sjfv 660169240Sjfv return ret_val; 661169240Sjfv} 662169240Sjfv 663169240Sjfv/** 664169240Sjfv * e1000_write_nvm_microwire - Writes EEPROM using microwire 665169589Sjfv * @hw: pointer to the HW structure 666169589Sjfv * @offset: offset within the EEPROM to be written to 667169589Sjfv * @words: number of words to write 668169589Sjfv * @data: 16 bit word(s) to be written to the EEPROM 669169240Sjfv * 670169240Sjfv * Writes data to EEPROM at offset using microwire interface. 671169240Sjfv * 672169240Sjfv * If e1000_update_nvm_checksum is not called after this function , the 673176667Sjfv * EEPROM will most likely contain an invalid checksum. 674169240Sjfv **/ 675173788Sjfvs32 e1000_write_nvm_microwire(struct e1000_hw *hw, u16 offset, u16 words, 676235527Sjfv u16 *data) 677169240Sjfv{ 678169240Sjfv struct e1000_nvm_info *nvm = &hw->nvm; 679169240Sjfv s32 ret_val; 680169240Sjfv u32 eecd; 681169240Sjfv u16 words_written = 0; 682169240Sjfv u16 widx = 0; 683169240Sjfv 684169240Sjfv DEBUGFUNC("e1000_write_nvm_microwire"); 685169240Sjfv 686248292Sjfv /* A check for invalid values: offset too large, too many words, 687173788Sjfv * and not enough words. 688173788Sjfv */ 689169240Sjfv if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) || 690169240Sjfv (words == 0)) { 691169240Sjfv DEBUGOUT("nvm parameter(s) out of bounds\n"); 692248292Sjfv return -E1000_ERR_NVM; 693169240Sjfv } 694169240Sjfv 695177867Sjfv ret_val = nvm->ops.acquire(hw); 696169240Sjfv if (ret_val) 697248292Sjfv return ret_val; 698169240Sjfv 699169240Sjfv ret_val = e1000_ready_nvm_eeprom(hw); 700169240Sjfv if (ret_val) 701169240Sjfv goto release; 702169240Sjfv 703169240Sjfv e1000_shift_out_eec_bits(hw, NVM_EWEN_OPCODE_MICROWIRE, 704235527Sjfv (u16)(nvm->opcode_bits + 2)); 705169240Sjfv 706169240Sjfv e1000_shift_out_eec_bits(hw, 0, (u16)(nvm->address_bits - 2)); 707169240Sjfv 708169240Sjfv e1000_standby_nvm(hw); 709169240Sjfv 710169240Sjfv while (words_written < words) { 711169240Sjfv e1000_shift_out_eec_bits(hw, NVM_WRITE_OPCODE_MICROWIRE, 712235527Sjfv nvm->opcode_bits); 713169240Sjfv 714169240Sjfv e1000_shift_out_eec_bits(hw, (u16)(offset + words_written), 715235527Sjfv nvm->address_bits); 716169240Sjfv 717169240Sjfv e1000_shift_out_eec_bits(hw, data[words_written], 16); 718169240Sjfv 719169240Sjfv e1000_standby_nvm(hw); 720169240Sjfv 721169240Sjfv for (widx = 0; widx < 200; widx++) { 722169240Sjfv eecd = E1000_READ_REG(hw, E1000_EECD); 723169240Sjfv if (eecd & E1000_EECD_DO) 724169240Sjfv break; 725169240Sjfv usec_delay(50); 726169240Sjfv } 727169240Sjfv 728169240Sjfv if (widx == 200) { 729169240Sjfv DEBUGOUT("NVM Write did not complete\n"); 730169240Sjfv ret_val = -E1000_ERR_NVM; 731169240Sjfv goto release; 732169240Sjfv } 733169240Sjfv 734169240Sjfv e1000_standby_nvm(hw); 735169240Sjfv 736169240Sjfv words_written++; 737169240Sjfv } 738169240Sjfv 739169240Sjfv e1000_shift_out_eec_bits(hw, NVM_EWDS_OPCODE_MICROWIRE, 740235527Sjfv (u16)(nvm->opcode_bits + 2)); 741169240Sjfv 742169240Sjfv e1000_shift_out_eec_bits(hw, 0, (u16)(nvm->address_bits - 2)); 743169240Sjfv 744169240Sjfvrelease: 745177867Sjfv nvm->ops.release(hw); 746169240Sjfv 747169240Sjfv return ret_val; 748169240Sjfv} 749169240Sjfv 750169240Sjfv/** 751213234Sjfv * e1000_read_pba_string_generic - Read device part number 752213234Sjfv * @hw: pointer to the HW structure 753213234Sjfv * @pba_num: pointer to device part number 754213234Sjfv * @pba_num_size: size of part number buffer 755213234Sjfv * 756213234Sjfv * Reads the product board assembly (PBA) number from the EEPROM and stores 757213234Sjfv * the value in pba_num. 758213234Sjfv **/ 759218530Sjfvs32 e1000_read_pba_string_generic(struct e1000_hw *hw, u8 *pba_num, 760235527Sjfv u32 pba_num_size) 761213234Sjfv{ 762213234Sjfv s32 ret_val; 763213234Sjfv u16 nvm_data; 764213234Sjfv u16 pba_ptr; 765213234Sjfv u16 offset; 766213234Sjfv u16 length; 767213234Sjfv 768213234Sjfv DEBUGFUNC("e1000_read_pba_string_generic"); 769213234Sjfv 770213234Sjfv if (pba_num == NULL) { 771213234Sjfv DEBUGOUT("PBA string buffer was null\n"); 772248292Sjfv return -E1000_ERR_INVALID_ARGUMENT; 773213234Sjfv } 774213234Sjfv 775213234Sjfv ret_val = hw->nvm.ops.read(hw, NVM_PBA_OFFSET_0, 1, &nvm_data); 776213234Sjfv if (ret_val) { 777213234Sjfv DEBUGOUT("NVM Read Error\n"); 778248292Sjfv return ret_val; 779213234Sjfv } 780213234Sjfv 781213234Sjfv ret_val = hw->nvm.ops.read(hw, NVM_PBA_OFFSET_1, 1, &pba_ptr); 782213234Sjfv if (ret_val) { 783213234Sjfv DEBUGOUT("NVM Read Error\n"); 784248292Sjfv return ret_val; 785213234Sjfv } 786213234Sjfv 787248292Sjfv /* if nvm_data is not ptr guard the PBA must be in legacy format which 788213234Sjfv * means pba_ptr is actually our second data word for the PBA number 789213234Sjfv * and we can decode it into an ascii string 790213234Sjfv */ 791213234Sjfv if (nvm_data != NVM_PBA_PTR_GUARD) { 792213234Sjfv DEBUGOUT("NVM PBA number is not stored as string\n"); 793213234Sjfv 794248292Sjfv /* make sure callers buffer is big enough to store the PBA */ 795248292Sjfv if (pba_num_size < E1000_PBANUM_LENGTH) { 796213234Sjfv DEBUGOUT("PBA string buffer too small\n"); 797213234Sjfv return E1000_ERR_NO_SPACE; 798213234Sjfv } 799213234Sjfv 800213234Sjfv /* extract hex string from data and pba_ptr */ 801213234Sjfv pba_num[0] = (nvm_data >> 12) & 0xF; 802213234Sjfv pba_num[1] = (nvm_data >> 8) & 0xF; 803213234Sjfv pba_num[2] = (nvm_data >> 4) & 0xF; 804213234Sjfv pba_num[3] = nvm_data & 0xF; 805213234Sjfv pba_num[4] = (pba_ptr >> 12) & 0xF; 806213234Sjfv pba_num[5] = (pba_ptr >> 8) & 0xF; 807213234Sjfv pba_num[6] = '-'; 808213234Sjfv pba_num[7] = 0; 809213234Sjfv pba_num[8] = (pba_ptr >> 4) & 0xF; 810213234Sjfv pba_num[9] = pba_ptr & 0xF; 811213234Sjfv 812213234Sjfv /* put a null character on the end of our string */ 813213234Sjfv pba_num[10] = '\0'; 814213234Sjfv 815213234Sjfv /* switch all the data but the '-' to hex char */ 816213234Sjfv for (offset = 0; offset < 10; offset++) { 817213234Sjfv if (pba_num[offset] < 0xA) 818213234Sjfv pba_num[offset] += '0'; 819213234Sjfv else if (pba_num[offset] < 0x10) 820213234Sjfv pba_num[offset] += 'A' - 0xA; 821213234Sjfv } 822213234Sjfv 823248292Sjfv return E1000_SUCCESS; 824213234Sjfv } 825213234Sjfv 826213234Sjfv ret_val = hw->nvm.ops.read(hw, pba_ptr, 1, &length); 827213234Sjfv if (ret_val) { 828213234Sjfv DEBUGOUT("NVM Read Error\n"); 829248292Sjfv return ret_val; 830213234Sjfv } 831213234Sjfv 832213234Sjfv if (length == 0xFFFF || length == 0) { 833213234Sjfv DEBUGOUT("NVM PBA number section invalid length\n"); 834248292Sjfv return -E1000_ERR_NVM_PBA_SECTION; 835213234Sjfv } 836213234Sjfv /* check if pba_num buffer is big enough */ 837213234Sjfv if (pba_num_size < (((u32)length * 2) - 1)) { 838213234Sjfv DEBUGOUT("PBA string buffer too small\n"); 839248292Sjfv return -E1000_ERR_NO_SPACE; 840213234Sjfv } 841213234Sjfv 842213234Sjfv /* trim pba length from start of string */ 843213234Sjfv pba_ptr++; 844213234Sjfv length--; 845213234Sjfv 846213234Sjfv for (offset = 0; offset < length; offset++) { 847213234Sjfv ret_val = hw->nvm.ops.read(hw, pba_ptr + offset, 1, &nvm_data); 848213234Sjfv if (ret_val) { 849213234Sjfv DEBUGOUT("NVM Read Error\n"); 850248292Sjfv return ret_val; 851213234Sjfv } 852213234Sjfv pba_num[offset * 2] = (u8)(nvm_data >> 8); 853213234Sjfv pba_num[(offset * 2) + 1] = (u8)(nvm_data & 0xFF); 854213234Sjfv } 855213234Sjfv pba_num[offset * 2] = '\0'; 856213234Sjfv 857248292Sjfv return E1000_SUCCESS; 858213234Sjfv} 859213234Sjfv 860213234Sjfv/** 861213234Sjfv * e1000_read_pba_length_generic - Read device part number length 862213234Sjfv * @hw: pointer to the HW structure 863213234Sjfv * @pba_num_size: size of part number buffer 864213234Sjfv * 865213234Sjfv * Reads the product board assembly (PBA) number length from the EEPROM and 866213234Sjfv * stores the value in pba_num_size. 867213234Sjfv **/ 868213234Sjfvs32 e1000_read_pba_length_generic(struct e1000_hw *hw, u32 *pba_num_size) 869213234Sjfv{ 870213234Sjfv s32 ret_val; 871213234Sjfv u16 nvm_data; 872213234Sjfv u16 pba_ptr; 873213234Sjfv u16 length; 874213234Sjfv 875213234Sjfv DEBUGFUNC("e1000_read_pba_length_generic"); 876213234Sjfv 877213234Sjfv if (pba_num_size == NULL) { 878213234Sjfv DEBUGOUT("PBA buffer size was null\n"); 879248292Sjfv return -E1000_ERR_INVALID_ARGUMENT; 880213234Sjfv } 881213234Sjfv 882213234Sjfv ret_val = hw->nvm.ops.read(hw, NVM_PBA_OFFSET_0, 1, &nvm_data); 883213234Sjfv if (ret_val) { 884213234Sjfv DEBUGOUT("NVM Read Error\n"); 885248292Sjfv return ret_val; 886213234Sjfv } 887213234Sjfv 888213234Sjfv ret_val = hw->nvm.ops.read(hw, NVM_PBA_OFFSET_1, 1, &pba_ptr); 889213234Sjfv if (ret_val) { 890213234Sjfv DEBUGOUT("NVM Read Error\n"); 891248292Sjfv return ret_val; 892213234Sjfv } 893213234Sjfv 894213234Sjfv /* if data is not ptr guard the PBA must be in legacy format */ 895213234Sjfv if (nvm_data != NVM_PBA_PTR_GUARD) { 896248292Sjfv *pba_num_size = E1000_PBANUM_LENGTH; 897248292Sjfv return E1000_SUCCESS; 898213234Sjfv } 899213234Sjfv 900213234Sjfv ret_val = hw->nvm.ops.read(hw, pba_ptr, 1, &length); 901213234Sjfv if (ret_val) { 902213234Sjfv DEBUGOUT("NVM Read Error\n"); 903248292Sjfv return ret_val; 904213234Sjfv } 905213234Sjfv 906213234Sjfv if (length == 0xFFFF || length == 0) { 907213234Sjfv DEBUGOUT("NVM PBA number section invalid length\n"); 908248292Sjfv return -E1000_ERR_NVM_PBA_SECTION; 909213234Sjfv } 910213234Sjfv 911248292Sjfv /* Convert from length in u16 values to u8 chars, add 1 for NULL, 912213234Sjfv * and subtract 2 because length field is included in length. 913213234Sjfv */ 914213234Sjfv *pba_num_size = ((u32)length * 2) - 1; 915213234Sjfv 916248292Sjfv return E1000_SUCCESS; 917213234Sjfv} 918213234Sjfv 919248292Sjfv 920213234Sjfv/** 921248292Sjfv * e1000_read_pba_raw 922248292Sjfv * @hw: pointer to the HW structure 923248292Sjfv * @eeprom_buf: optional pointer to EEPROM image 924248292Sjfv * @eeprom_buf_size: size of EEPROM image in words 925248292Sjfv * @max_pba_block_size: PBA block size limit 926248292Sjfv * @pba: pointer to output PBA structure 927248292Sjfv * 928248292Sjfv * Reads PBA from EEPROM image when eeprom_buf is not NULL. 929248292Sjfv * Reads PBA from physical EEPROM device when eeprom_buf is NULL. 930248292Sjfv * 931248292Sjfv **/ 932248292Sjfvs32 e1000_read_pba_raw(struct e1000_hw *hw, u16 *eeprom_buf, 933248292Sjfv u32 eeprom_buf_size, u16 max_pba_block_size, 934248292Sjfv struct e1000_pba *pba) 935248292Sjfv{ 936248292Sjfv s32 ret_val; 937248292Sjfv u16 pba_block_size; 938248292Sjfv 939248292Sjfv if (pba == NULL) 940248292Sjfv return -E1000_ERR_PARAM; 941248292Sjfv 942248292Sjfv if (eeprom_buf == NULL) { 943248292Sjfv ret_val = e1000_read_nvm(hw, NVM_PBA_OFFSET_0, 2, 944248292Sjfv &pba->word[0]); 945248292Sjfv if (ret_val) 946248292Sjfv return ret_val; 947248292Sjfv } else { 948248292Sjfv if (eeprom_buf_size > NVM_PBA_OFFSET_1) { 949248292Sjfv pba->word[0] = eeprom_buf[NVM_PBA_OFFSET_0]; 950248292Sjfv pba->word[1] = eeprom_buf[NVM_PBA_OFFSET_1]; 951248292Sjfv } else { 952248292Sjfv return -E1000_ERR_PARAM; 953248292Sjfv } 954248292Sjfv } 955248292Sjfv 956248292Sjfv if (pba->word[0] == NVM_PBA_PTR_GUARD) { 957248292Sjfv if (pba->pba_block == NULL) 958248292Sjfv return -E1000_ERR_PARAM; 959248292Sjfv 960248292Sjfv ret_val = e1000_get_pba_block_size(hw, eeprom_buf, 961248292Sjfv eeprom_buf_size, 962248292Sjfv &pba_block_size); 963248292Sjfv if (ret_val) 964248292Sjfv return ret_val; 965248292Sjfv 966248292Sjfv if (pba_block_size > max_pba_block_size) 967248292Sjfv return -E1000_ERR_PARAM; 968248292Sjfv 969248292Sjfv if (eeprom_buf == NULL) { 970248292Sjfv ret_val = e1000_read_nvm(hw, pba->word[1], 971248292Sjfv pba_block_size, 972248292Sjfv pba->pba_block); 973248292Sjfv if (ret_val) 974248292Sjfv return ret_val; 975248292Sjfv } else { 976248292Sjfv if (eeprom_buf_size > (u32)(pba->word[1] + 977248292Sjfv pba->pba_block[0])) { 978248292Sjfv memcpy(pba->pba_block, 979248292Sjfv &eeprom_buf[pba->word[1]], 980248292Sjfv pba_block_size * sizeof(u16)); 981248292Sjfv } else { 982248292Sjfv return -E1000_ERR_PARAM; 983248292Sjfv } 984248292Sjfv } 985248292Sjfv } 986248292Sjfv 987248292Sjfv return E1000_SUCCESS; 988248292Sjfv} 989248292Sjfv 990248292Sjfv/** 991248292Sjfv * e1000_write_pba_raw 992248292Sjfv * @hw: pointer to the HW structure 993248292Sjfv * @eeprom_buf: optional pointer to EEPROM image 994248292Sjfv * @eeprom_buf_size: size of EEPROM image in words 995248292Sjfv * @pba: pointer to PBA structure 996248292Sjfv * 997248292Sjfv * Writes PBA to EEPROM image when eeprom_buf is not NULL. 998248292Sjfv * Writes PBA to physical EEPROM device when eeprom_buf is NULL. 999248292Sjfv * 1000248292Sjfv **/ 1001248292Sjfvs32 e1000_write_pba_raw(struct e1000_hw *hw, u16 *eeprom_buf, 1002248292Sjfv u32 eeprom_buf_size, struct e1000_pba *pba) 1003248292Sjfv{ 1004248292Sjfv s32 ret_val; 1005248292Sjfv 1006248292Sjfv if (pba == NULL) 1007248292Sjfv return -E1000_ERR_PARAM; 1008248292Sjfv 1009248292Sjfv if (eeprom_buf == NULL) { 1010248292Sjfv ret_val = e1000_write_nvm(hw, NVM_PBA_OFFSET_0, 2, 1011248292Sjfv &pba->word[0]); 1012248292Sjfv if (ret_val) 1013248292Sjfv return ret_val; 1014248292Sjfv } else { 1015248292Sjfv if (eeprom_buf_size > NVM_PBA_OFFSET_1) { 1016248292Sjfv eeprom_buf[NVM_PBA_OFFSET_0] = pba->word[0]; 1017248292Sjfv eeprom_buf[NVM_PBA_OFFSET_1] = pba->word[1]; 1018248292Sjfv } else { 1019248292Sjfv return -E1000_ERR_PARAM; 1020248292Sjfv } 1021248292Sjfv } 1022248292Sjfv 1023248292Sjfv if (pba->word[0] == NVM_PBA_PTR_GUARD) { 1024248292Sjfv if (pba->pba_block == NULL) 1025248292Sjfv return -E1000_ERR_PARAM; 1026248292Sjfv 1027248292Sjfv if (eeprom_buf == NULL) { 1028248292Sjfv ret_val = e1000_write_nvm(hw, pba->word[1], 1029248292Sjfv pba->pba_block[0], 1030248292Sjfv pba->pba_block); 1031248292Sjfv if (ret_val) 1032248292Sjfv return ret_val; 1033248292Sjfv } else { 1034248292Sjfv if (eeprom_buf_size > (u32)(pba->word[1] + 1035248292Sjfv pba->pba_block[0])) { 1036248292Sjfv memcpy(&eeprom_buf[pba->word[1]], 1037248292Sjfv pba->pba_block, 1038248292Sjfv pba->pba_block[0] * sizeof(u16)); 1039248292Sjfv } else { 1040248292Sjfv return -E1000_ERR_PARAM; 1041248292Sjfv } 1042248292Sjfv } 1043248292Sjfv } 1044248292Sjfv 1045248292Sjfv return E1000_SUCCESS; 1046248292Sjfv} 1047248292Sjfv 1048248292Sjfv/** 1049248292Sjfv * e1000_get_pba_block_size 1050248292Sjfv * @hw: pointer to the HW structure 1051248292Sjfv * @eeprom_buf: optional pointer to EEPROM image 1052248292Sjfv * @eeprom_buf_size: size of EEPROM image in words 1053248292Sjfv * @pba_data_size: pointer to output variable 1054248292Sjfv * 1055248292Sjfv * Returns the size of the PBA block in words. Function operates on EEPROM 1056248292Sjfv * image if the eeprom_buf pointer is not NULL otherwise it accesses physical 1057248292Sjfv * EEPROM device. 1058248292Sjfv * 1059248292Sjfv **/ 1060248292Sjfvs32 e1000_get_pba_block_size(struct e1000_hw *hw, u16 *eeprom_buf, 1061248292Sjfv u32 eeprom_buf_size, u16 *pba_block_size) 1062248292Sjfv{ 1063248292Sjfv s32 ret_val; 1064248292Sjfv u16 pba_word[2]; 1065248292Sjfv u16 length; 1066248292Sjfv 1067248292Sjfv DEBUGFUNC("e1000_get_pba_block_size"); 1068248292Sjfv 1069248292Sjfv if (eeprom_buf == NULL) { 1070248292Sjfv ret_val = e1000_read_nvm(hw, NVM_PBA_OFFSET_0, 2, &pba_word[0]); 1071248292Sjfv if (ret_val) 1072248292Sjfv return ret_val; 1073248292Sjfv } else { 1074248292Sjfv if (eeprom_buf_size > NVM_PBA_OFFSET_1) { 1075248292Sjfv pba_word[0] = eeprom_buf[NVM_PBA_OFFSET_0]; 1076248292Sjfv pba_word[1] = eeprom_buf[NVM_PBA_OFFSET_1]; 1077248292Sjfv } else { 1078248292Sjfv return -E1000_ERR_PARAM; 1079248292Sjfv } 1080248292Sjfv } 1081248292Sjfv 1082248292Sjfv if (pba_word[0] == NVM_PBA_PTR_GUARD) { 1083248292Sjfv if (eeprom_buf == NULL) { 1084248292Sjfv ret_val = e1000_read_nvm(hw, pba_word[1] + 0, 1, 1085248292Sjfv &length); 1086248292Sjfv if (ret_val) 1087248292Sjfv return ret_val; 1088248292Sjfv } else { 1089248292Sjfv if (eeprom_buf_size > pba_word[1]) 1090248292Sjfv length = eeprom_buf[pba_word[1] + 0]; 1091248292Sjfv else 1092248292Sjfv return -E1000_ERR_PARAM; 1093248292Sjfv } 1094248292Sjfv 1095248292Sjfv if (length == 0xFFFF || length == 0) 1096248292Sjfv return -E1000_ERR_NVM_PBA_SECTION; 1097248292Sjfv } else { 1098248292Sjfv /* PBA number in legacy format, there is no PBA Block. */ 1099248292Sjfv length = 0; 1100248292Sjfv } 1101248292Sjfv 1102248292Sjfv if (pba_block_size != NULL) 1103248292Sjfv *pba_block_size = length; 1104248292Sjfv 1105248292Sjfv return E1000_SUCCESS; 1106248292Sjfv} 1107248292Sjfv 1108248292Sjfv/** 1109169240Sjfv * e1000_read_mac_addr_generic - Read device MAC address 1110169589Sjfv * @hw: pointer to the HW structure 1111169240Sjfv * 1112169240Sjfv * Reads the device MAC address from the EEPROM and stores the value. 1113169240Sjfv * Since devices with two ports use the same EEPROM, we increment the 1114169240Sjfv * last bit in the MAC address for the second port. 1115169240Sjfv **/ 1116173788Sjfvs32 e1000_read_mac_addr_generic(struct e1000_hw *hw) 1117169240Sjfv{ 1118190872Sjfv u32 rar_high; 1119190872Sjfv u32 rar_low; 1120190872Sjfv u16 i; 1121169240Sjfv 1122190872Sjfv rar_high = E1000_READ_REG(hw, E1000_RAH(0)); 1123190872Sjfv rar_low = E1000_READ_REG(hw, E1000_RAL(0)); 1124169240Sjfv 1125190872Sjfv for (i = 0; i < E1000_RAL_MAC_ADDR_LEN; i++) 1126190872Sjfv hw->mac.perm_addr[i] = (u8)(rar_low >> (i*8)); 1127169240Sjfv 1128190872Sjfv for (i = 0; i < E1000_RAH_MAC_ADDR_LEN; i++) 1129190872Sjfv hw->mac.perm_addr[i+4] = (u8)(rar_high >> (i*8)); 1130169240Sjfv 1131169240Sjfv for (i = 0; i < ETH_ADDR_LEN; i++) 1132169240Sjfv hw->mac.addr[i] = hw->mac.perm_addr[i]; 1133169240Sjfv 1134190872Sjfv return E1000_SUCCESS; 1135169240Sjfv} 1136169240Sjfv 1137169240Sjfv/** 1138169240Sjfv * e1000_validate_nvm_checksum_generic - Validate EEPROM checksum 1139169589Sjfv * @hw: pointer to the HW structure 1140169240Sjfv * 1141169240Sjfv * Calculates the EEPROM checksum by reading/adding each word of the EEPROM 1142169240Sjfv * and then verifies that the sum of the EEPROM is equal to 0xBABA. 1143169240Sjfv **/ 1144173788Sjfvs32 e1000_validate_nvm_checksum_generic(struct e1000_hw *hw) 1145169240Sjfv{ 1146248292Sjfv s32 ret_val; 1147169240Sjfv u16 checksum = 0; 1148169240Sjfv u16 i, nvm_data; 1149169240Sjfv 1150169240Sjfv DEBUGFUNC("e1000_validate_nvm_checksum_generic"); 1151169240Sjfv 1152169240Sjfv for (i = 0; i < (NVM_CHECKSUM_REG + 1); i++) { 1153177867Sjfv ret_val = hw->nvm.ops.read(hw, i, 1, &nvm_data); 1154169240Sjfv if (ret_val) { 1155169240Sjfv DEBUGOUT("NVM Read Error\n"); 1156248292Sjfv return ret_val; 1157169240Sjfv } 1158169240Sjfv checksum += nvm_data; 1159169240Sjfv } 1160169240Sjfv 1161169240Sjfv if (checksum != (u16) NVM_SUM) { 1162169240Sjfv DEBUGOUT("NVM Checksum Invalid\n"); 1163248292Sjfv return -E1000_ERR_NVM; 1164169240Sjfv } 1165169240Sjfv 1166248292Sjfv return E1000_SUCCESS; 1167169240Sjfv} 1168169240Sjfv 1169169240Sjfv/** 1170169240Sjfv * e1000_update_nvm_checksum_generic - Update EEPROM checksum 1171169589Sjfv * @hw: pointer to the HW structure 1172169240Sjfv * 1173169240Sjfv * Updates the EEPROM checksum by reading/adding each word of the EEPROM 1174169240Sjfv * up to the checksum. Then calculates the EEPROM checksum and writes the 1175169240Sjfv * value to the EEPROM. 1176169240Sjfv **/ 1177173788Sjfvs32 e1000_update_nvm_checksum_generic(struct e1000_hw *hw) 1178169240Sjfv{ 1179213234Sjfv s32 ret_val; 1180169240Sjfv u16 checksum = 0; 1181169240Sjfv u16 i, nvm_data; 1182169240Sjfv 1183169240Sjfv DEBUGFUNC("e1000_update_nvm_checksum"); 1184169240Sjfv 1185169240Sjfv for (i = 0; i < NVM_CHECKSUM_REG; i++) { 1186177867Sjfv ret_val = hw->nvm.ops.read(hw, i, 1, &nvm_data); 1187169240Sjfv if (ret_val) { 1188169240Sjfv DEBUGOUT("NVM Read Error while updating checksum.\n"); 1189248292Sjfv return ret_val; 1190169240Sjfv } 1191169240Sjfv checksum += nvm_data; 1192169240Sjfv } 1193169240Sjfv checksum = (u16) NVM_SUM - checksum; 1194177867Sjfv ret_val = hw->nvm.ops.write(hw, NVM_CHECKSUM_REG, 1, &checksum); 1195185353Sjfv if (ret_val) 1196169240Sjfv DEBUGOUT("NVM Write Error while updating checksum.\n"); 1197169240Sjfv 1198169240Sjfv return ret_val; 1199169240Sjfv} 1200169240Sjfv 1201169240Sjfv/** 1202169240Sjfv * e1000_reload_nvm_generic - Reloads EEPROM 1203169589Sjfv * @hw: pointer to the HW structure 1204169240Sjfv * 1205169240Sjfv * Reloads the EEPROM by setting the "Reinitialize from EEPROM" bit in the 1206169240Sjfv * extended control register. 1207169240Sjfv **/ 1208190872Sjfvstatic void e1000_reload_nvm_generic(struct e1000_hw *hw) 1209169240Sjfv{ 1210169240Sjfv u32 ctrl_ext; 1211169240Sjfv 1212169240Sjfv DEBUGFUNC("e1000_reload_nvm_generic"); 1213169240Sjfv 1214169240Sjfv usec_delay(10); 1215169240Sjfv ctrl_ext = E1000_READ_REG(hw, E1000_CTRL_EXT); 1216169240Sjfv ctrl_ext |= E1000_CTRL_EXT_EE_RST; 1217169240Sjfv E1000_WRITE_REG(hw, E1000_CTRL_EXT, ctrl_ext); 1218169240Sjfv E1000_WRITE_FLUSH(hw); 1219169240Sjfv} 1220169240Sjfv 1221248292Sjfv 1222