1238148Sjfv/****************************************************************************** 2238148Sjfv 3286833Ssbruno Copyright (c) 2001-2015, Intel Corporation 4238148Sjfv All rights reserved. 5238148Sjfv 6238148Sjfv Redistribution and use in source and binary forms, with or without 7238148Sjfv modification, are permitted provided that the following conditions are met: 8238148Sjfv 9238148Sjfv 1. Redistributions of source code must retain the above copyright notice, 10238148Sjfv this list of conditions and the following disclaimer. 11238148Sjfv 12238148Sjfv 2. Redistributions in binary form must reproduce the above copyright 13238148Sjfv notice, this list of conditions and the following disclaimer in the 14238148Sjfv documentation and/or other materials provided with the distribution. 15238148Sjfv 16238148Sjfv 3. Neither the name of the Intel Corporation nor the names of its 17238148Sjfv contributors may be used to endorse or promote products derived from 18238148Sjfv this software without specific prior written permission. 19238148Sjfv 20238148Sjfv THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21238148Sjfv AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22238148Sjfv IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23238148Sjfv ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 24238148Sjfv LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25238148Sjfv CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26238148Sjfv SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27238148Sjfv INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28238148Sjfv CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29238148Sjfv ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30238148Sjfv POSSIBILITY OF SUCH DAMAGE. 31238148Sjfv 32238148Sjfv******************************************************************************/ 33238148Sjfv/*$FreeBSD$*/ 34238148Sjfv 35238148Sjfv#include "e1000_api.h" 36238148Sjfv 37238148Sjfv 38238148Sjfvstatic s32 e1000_acquire_nvm_i210(struct e1000_hw *hw); 39238148Sjfvstatic void e1000_release_nvm_i210(struct e1000_hw *hw); 40238148Sjfvstatic s32 e1000_get_hw_semaphore_i210(struct e1000_hw *hw); 41238148Sjfvstatic s32 e1000_write_nvm_srwr(struct e1000_hw *hw, u16 offset, u16 words, 42238148Sjfv u16 *data); 43238148Sjfvstatic s32 e1000_pool_flash_update_done_i210(struct e1000_hw *hw); 44238148Sjfvstatic s32 e1000_valid_led_default_i210(struct e1000_hw *hw, u16 *data); 45238148Sjfv 46238148Sjfv/** 47238148Sjfv * e1000_acquire_nvm_i210 - Request for access to EEPROM 48238148Sjfv * @hw: pointer to the HW structure 49238148Sjfv * 50238148Sjfv * Acquire the necessary semaphores for exclusive access to the EEPROM. 51238148Sjfv * Set the EEPROM access request bit and wait for EEPROM access grant bit. 52238148Sjfv * Return successful if access grant bit set, else clear the request for 53238148Sjfv * EEPROM access and return -E1000_ERR_NVM (-1). 54238148Sjfv **/ 55238148Sjfvstatic s32 e1000_acquire_nvm_i210(struct e1000_hw *hw) 56238148Sjfv{ 57238148Sjfv s32 ret_val; 58238148Sjfv 59238148Sjfv DEBUGFUNC("e1000_acquire_nvm_i210"); 60238148Sjfv 61238148Sjfv ret_val = e1000_acquire_swfw_sync_i210(hw, E1000_SWFW_EEP_SM); 62238148Sjfv 63238148Sjfv return ret_val; 64238148Sjfv} 65238148Sjfv 66238148Sjfv/** 67238148Sjfv * e1000_release_nvm_i210 - Release exclusive access to EEPROM 68238148Sjfv * @hw: pointer to the HW structure 69238148Sjfv * 70238148Sjfv * Stop any current commands to the EEPROM and clear the EEPROM request bit, 71238148Sjfv * then release the semaphores acquired. 72238148Sjfv **/ 73238148Sjfvstatic void e1000_release_nvm_i210(struct e1000_hw *hw) 74238148Sjfv{ 75238148Sjfv DEBUGFUNC("e1000_release_nvm_i210"); 76238148Sjfv 77238148Sjfv e1000_release_swfw_sync_i210(hw, E1000_SWFW_EEP_SM); 78238148Sjfv} 79238148Sjfv 80238148Sjfv/** 81238148Sjfv * e1000_acquire_swfw_sync_i210 - Acquire SW/FW semaphore 82238148Sjfv * @hw: pointer to the HW structure 83238148Sjfv * @mask: specifies which semaphore to acquire 84238148Sjfv * 85238148Sjfv * Acquire the SW/FW semaphore to access the PHY or NVM. The mask 86238148Sjfv * will also specify which port we're acquiring the lock for. 87238148Sjfv **/ 88238148Sjfvs32 e1000_acquire_swfw_sync_i210(struct e1000_hw *hw, u16 mask) 89238148Sjfv{ 90238148Sjfv u32 swfw_sync; 91238148Sjfv u32 swmask = mask; 92238148Sjfv u32 fwmask = mask << 16; 93238148Sjfv s32 ret_val = E1000_SUCCESS; 94238148Sjfv s32 i = 0, timeout = 200; /* FIXME: find real value to use here */ 95238148Sjfv 96238148Sjfv DEBUGFUNC("e1000_acquire_swfw_sync_i210"); 97238148Sjfv 98238148Sjfv while (i < timeout) { 99238148Sjfv if (e1000_get_hw_semaphore_i210(hw)) { 100238148Sjfv ret_val = -E1000_ERR_SWFW_SYNC; 101238148Sjfv goto out; 102238148Sjfv } 103238148Sjfv 104238148Sjfv swfw_sync = E1000_READ_REG(hw, E1000_SW_FW_SYNC); 105247064Sjfv if (!(swfw_sync & (fwmask | swmask))) 106238148Sjfv break; 107238148Sjfv 108238148Sjfv /* 109238148Sjfv * Firmware currently using resource (fwmask) 110247064Sjfv * or other software thread using resource (swmask) 111238148Sjfv */ 112247064Sjfv e1000_put_hw_semaphore_generic(hw); 113238148Sjfv msec_delay_irq(5); 114238148Sjfv i++; 115238148Sjfv } 116238148Sjfv 117238148Sjfv if (i == timeout) { 118238148Sjfv DEBUGOUT("Driver can't access resource, SW_FW_SYNC timeout.\n"); 119238148Sjfv ret_val = -E1000_ERR_SWFW_SYNC; 120238148Sjfv goto out; 121238148Sjfv } 122238148Sjfv 123238148Sjfv swfw_sync |= swmask; 124238148Sjfv E1000_WRITE_REG(hw, E1000_SW_FW_SYNC, swfw_sync); 125238148Sjfv 126247064Sjfv e1000_put_hw_semaphore_generic(hw); 127238148Sjfv 128238148Sjfvout: 129238148Sjfv return ret_val; 130238148Sjfv} 131238148Sjfv 132238148Sjfv/** 133238148Sjfv * e1000_release_swfw_sync_i210 - Release SW/FW semaphore 134238148Sjfv * @hw: pointer to the HW structure 135238148Sjfv * @mask: specifies which semaphore to acquire 136238148Sjfv * 137238148Sjfv * Release the SW/FW semaphore used to access the PHY or NVM. The mask 138238148Sjfv * will also specify which port we're releasing the lock for. 139238148Sjfv **/ 140238148Sjfvvoid e1000_release_swfw_sync_i210(struct e1000_hw *hw, u16 mask) 141238148Sjfv{ 142238148Sjfv u32 swfw_sync; 143238148Sjfv 144238148Sjfv DEBUGFUNC("e1000_release_swfw_sync_i210"); 145238148Sjfv 146238148Sjfv while (e1000_get_hw_semaphore_i210(hw) != E1000_SUCCESS) 147238148Sjfv ; /* Empty */ 148238148Sjfv 149238148Sjfv swfw_sync = E1000_READ_REG(hw, E1000_SW_FW_SYNC); 150238148Sjfv swfw_sync &= ~mask; 151238148Sjfv E1000_WRITE_REG(hw, E1000_SW_FW_SYNC, swfw_sync); 152238148Sjfv 153247064Sjfv e1000_put_hw_semaphore_generic(hw); 154238148Sjfv} 155238148Sjfv 156238148Sjfv/** 157238148Sjfv * e1000_get_hw_semaphore_i210 - Acquire hardware semaphore 158238148Sjfv * @hw: pointer to the HW structure 159238148Sjfv * 160238148Sjfv * Acquire the HW semaphore to access the PHY or NVM 161238148Sjfv **/ 162238148Sjfvstatic s32 e1000_get_hw_semaphore_i210(struct e1000_hw *hw) 163238148Sjfv{ 164238148Sjfv u32 swsm; 165238148Sjfv s32 timeout = hw->nvm.word_size + 1; 166238148Sjfv s32 i = 0; 167238148Sjfv 168238148Sjfv DEBUGFUNC("e1000_get_hw_semaphore_i210"); 169238148Sjfv 170247064Sjfv /* Get the SW semaphore */ 171247064Sjfv while (i < timeout) { 172247064Sjfv swsm = E1000_READ_REG(hw, E1000_SWSM); 173247064Sjfv if (!(swsm & E1000_SWSM_SMBI)) 174247064Sjfv break; 175247064Sjfv 176247064Sjfv usec_delay(50); 177247064Sjfv i++; 178247064Sjfv } 179247064Sjfv 180247064Sjfv if (i == timeout) { 181256200Sjfv /* In rare circumstances, the SW semaphore may already be held 182256200Sjfv * unintentionally. Clear the semaphore once before giving up. 183247064Sjfv */ 184247064Sjfv if (hw->dev_spec._82575.clear_semaphore_once) { 185247064Sjfv hw->dev_spec._82575.clear_semaphore_once = FALSE; 186247064Sjfv e1000_put_hw_semaphore_generic(hw); 187247064Sjfv for (i = 0; i < timeout; i++) { 188247064Sjfv swsm = E1000_READ_REG(hw, E1000_SWSM); 189247064Sjfv if (!(swsm & E1000_SWSM_SMBI)) 190247064Sjfv break; 191247064Sjfv 192247064Sjfv usec_delay(50); 193247064Sjfv } 194247064Sjfv } 195247064Sjfv 196247064Sjfv /* If we do not have the semaphore here, we have to give up. */ 197247064Sjfv if (i == timeout) { 198247064Sjfv DEBUGOUT("Driver can't access device - SMBI bit is set.\n"); 199247064Sjfv return -E1000_ERR_NVM; 200247064Sjfv } 201247064Sjfv } 202247064Sjfv 203238148Sjfv /* Get the FW semaphore. */ 204238148Sjfv for (i = 0; i < timeout; i++) { 205238148Sjfv swsm = E1000_READ_REG(hw, E1000_SWSM); 206238148Sjfv E1000_WRITE_REG(hw, E1000_SWSM, swsm | E1000_SWSM_SWESMBI); 207238148Sjfv 208238148Sjfv /* Semaphore acquired if bit latched */ 209238148Sjfv if (E1000_READ_REG(hw, E1000_SWSM) & E1000_SWSM_SWESMBI) 210238148Sjfv break; 211238148Sjfv 212238148Sjfv usec_delay(50); 213238148Sjfv } 214238148Sjfv 215238148Sjfv if (i == timeout) { 216238148Sjfv /* Release semaphores */ 217238148Sjfv e1000_put_hw_semaphore_generic(hw); 218238148Sjfv DEBUGOUT("Driver can't access the NVM\n"); 219247064Sjfv return -E1000_ERR_NVM; 220238148Sjfv } 221238148Sjfv 222247064Sjfv return E1000_SUCCESS; 223238148Sjfv} 224238148Sjfv 225238148Sjfv/** 226238148Sjfv * e1000_read_nvm_srrd_i210 - Reads Shadow Ram using EERD register 227238148Sjfv * @hw: pointer to the HW structure 228238148Sjfv * @offset: offset of word in the Shadow Ram to read 229238148Sjfv * @words: number of words to read 230238148Sjfv * @data: word read from the Shadow Ram 231238148Sjfv * 232238148Sjfv * Reads a 16 bit word from the Shadow Ram using the EERD register. 233238148Sjfv * Uses necessary synchronization semaphores. 234238148Sjfv **/ 235238148Sjfvs32 e1000_read_nvm_srrd_i210(struct e1000_hw *hw, u16 offset, u16 words, 236238148Sjfv u16 *data) 237238148Sjfv{ 238238148Sjfv s32 status = E1000_SUCCESS; 239238148Sjfv u16 i, count; 240238148Sjfv 241238148Sjfv DEBUGFUNC("e1000_read_nvm_srrd_i210"); 242238148Sjfv 243238148Sjfv /* We cannot hold synchronization semaphores for too long, 244238148Sjfv * because of forceful takeover procedure. However it is more efficient 245238148Sjfv * to read in bursts than synchronizing access for each word. */ 246238148Sjfv for (i = 0; i < words; i += E1000_EERD_EEWR_MAX_COUNT) { 247238148Sjfv count = (words - i) / E1000_EERD_EEWR_MAX_COUNT > 0 ? 248238148Sjfv E1000_EERD_EEWR_MAX_COUNT : (words - i); 249238148Sjfv if (hw->nvm.ops.acquire(hw) == E1000_SUCCESS) { 250238148Sjfv status = e1000_read_nvm_eerd(hw, offset, count, 251238148Sjfv data + i); 252238148Sjfv hw->nvm.ops.release(hw); 253238148Sjfv } else { 254238148Sjfv status = E1000_ERR_SWFW_SYNC; 255238148Sjfv } 256238148Sjfv 257238148Sjfv if (status != E1000_SUCCESS) 258238148Sjfv break; 259238148Sjfv } 260238148Sjfv 261238148Sjfv return status; 262238148Sjfv} 263238148Sjfv 264238148Sjfv/** 265238148Sjfv * e1000_write_nvm_srwr_i210 - Write to Shadow RAM using EEWR 266238148Sjfv * @hw: pointer to the HW structure 267238148Sjfv * @offset: offset within the Shadow RAM to be written to 268238148Sjfv * @words: number of words to write 269238148Sjfv * @data: 16 bit word(s) to be written to the Shadow RAM 270238148Sjfv * 271238148Sjfv * Writes data to Shadow RAM at offset using EEWR register. 272238148Sjfv * 273238148Sjfv * If e1000_update_nvm_checksum is not called after this function , the 274238148Sjfv * data will not be committed to FLASH and also Shadow RAM will most likely 275238148Sjfv * contain an invalid checksum. 276238148Sjfv * 277238148Sjfv * If error code is returned, data and Shadow RAM may be inconsistent - buffer 278238148Sjfv * partially written. 279238148Sjfv **/ 280238148Sjfvs32 e1000_write_nvm_srwr_i210(struct e1000_hw *hw, u16 offset, u16 words, 281238148Sjfv u16 *data) 282238148Sjfv{ 283238148Sjfv s32 status = E1000_SUCCESS; 284238148Sjfv u16 i, count; 285238148Sjfv 286238148Sjfv DEBUGFUNC("e1000_write_nvm_srwr_i210"); 287238148Sjfv 288238148Sjfv /* We cannot hold synchronization semaphores for too long, 289238148Sjfv * because of forceful takeover procedure. However it is more efficient 290238148Sjfv * to write in bursts than synchronizing access for each word. */ 291238148Sjfv for (i = 0; i < words; i += E1000_EERD_EEWR_MAX_COUNT) { 292238148Sjfv count = (words - i) / E1000_EERD_EEWR_MAX_COUNT > 0 ? 293238148Sjfv E1000_EERD_EEWR_MAX_COUNT : (words - i); 294238148Sjfv if (hw->nvm.ops.acquire(hw) == E1000_SUCCESS) { 295238148Sjfv status = e1000_write_nvm_srwr(hw, offset, count, 296238148Sjfv data + i); 297238148Sjfv hw->nvm.ops.release(hw); 298238148Sjfv } else { 299238148Sjfv status = E1000_ERR_SWFW_SYNC; 300238148Sjfv } 301238148Sjfv 302238148Sjfv if (status != E1000_SUCCESS) 303238148Sjfv break; 304238148Sjfv } 305238148Sjfv 306238148Sjfv return status; 307238148Sjfv} 308238148Sjfv 309238148Sjfv/** 310238148Sjfv * e1000_write_nvm_srwr - Write to Shadow Ram using EEWR 311238148Sjfv * @hw: pointer to the HW structure 312238148Sjfv * @offset: offset within the Shadow Ram to be written to 313238148Sjfv * @words: number of words to write 314238148Sjfv * @data: 16 bit word(s) to be written to the Shadow Ram 315238148Sjfv * 316238148Sjfv * Writes data to Shadow Ram at offset using EEWR register. 317238148Sjfv * 318238148Sjfv * If e1000_update_nvm_checksum is not called after this function , the 319238148Sjfv * Shadow Ram will most likely contain an invalid checksum. 320238148Sjfv **/ 321238148Sjfvstatic s32 e1000_write_nvm_srwr(struct e1000_hw *hw, u16 offset, u16 words, 322238148Sjfv u16 *data) 323238148Sjfv{ 324238148Sjfv struct e1000_nvm_info *nvm = &hw->nvm; 325238148Sjfv u32 i, k, eewr = 0; 326238148Sjfv u32 attempts = 100000; 327238148Sjfv s32 ret_val = E1000_SUCCESS; 328238148Sjfv 329238148Sjfv DEBUGFUNC("e1000_write_nvm_srwr"); 330238148Sjfv 331238148Sjfv /* 332238148Sjfv * A check for invalid values: offset too large, too many words, 333238148Sjfv * too many words for the offset, and not enough words. 334238148Sjfv */ 335238148Sjfv if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) || 336238148Sjfv (words == 0)) { 337238148Sjfv DEBUGOUT("nvm parameter(s) out of bounds\n"); 338238148Sjfv ret_val = -E1000_ERR_NVM; 339238148Sjfv goto out; 340238148Sjfv } 341238148Sjfv 342238148Sjfv for (i = 0; i < words; i++) { 343238148Sjfv eewr = ((offset+i) << E1000_NVM_RW_ADDR_SHIFT) | 344238148Sjfv (data[i] << E1000_NVM_RW_REG_DATA) | 345238148Sjfv E1000_NVM_RW_REG_START; 346238148Sjfv 347238148Sjfv E1000_WRITE_REG(hw, E1000_SRWR, eewr); 348238148Sjfv 349238148Sjfv for (k = 0; k < attempts; k++) { 350238148Sjfv if (E1000_NVM_RW_REG_DONE & 351238148Sjfv E1000_READ_REG(hw, E1000_SRWR)) { 352238148Sjfv ret_val = E1000_SUCCESS; 353238148Sjfv break; 354238148Sjfv } 355238148Sjfv usec_delay(5); 356238148Sjfv } 357238148Sjfv 358238148Sjfv if (ret_val != E1000_SUCCESS) { 359238148Sjfv DEBUGOUT("Shadow RAM write EEWR timed out\n"); 360238148Sjfv break; 361238148Sjfv } 362238148Sjfv } 363238148Sjfv 364238148Sjfvout: 365238148Sjfv return ret_val; 366238148Sjfv} 367238148Sjfv 368256200Sjfv/** e1000_read_invm_word_i210 - Reads OTP 369238148Sjfv * @hw: pointer to the HW structure 370238148Sjfv * @address: the word address (aka eeprom offset) to read 371238148Sjfv * @data: pointer to the data read 372238148Sjfv * 373256200Sjfv * Reads 16-bit words from the OTP. Return error when the word is not 374256200Sjfv * stored in OTP. 375256200Sjfv **/ 376256200Sjfvstatic s32 e1000_read_invm_word_i210(struct e1000_hw *hw, u8 address, u16 *data) 377256200Sjfv{ 378256200Sjfv s32 status = -E1000_ERR_INVM_VALUE_NOT_FOUND; 379256200Sjfv u32 invm_dword; 380256200Sjfv u16 i; 381256200Sjfv u8 record_type, word_address; 382256200Sjfv 383256200Sjfv DEBUGFUNC("e1000_read_invm_word_i210"); 384256200Sjfv 385256200Sjfv for (i = 0; i < E1000_INVM_SIZE; i++) { 386256200Sjfv invm_dword = E1000_READ_REG(hw, E1000_INVM_DATA_REG(i)); 387256200Sjfv /* Get record type */ 388256200Sjfv record_type = INVM_DWORD_TO_RECORD_TYPE(invm_dword); 389256200Sjfv if (record_type == E1000_INVM_UNINITIALIZED_STRUCTURE) 390256200Sjfv break; 391256200Sjfv if (record_type == E1000_INVM_CSR_AUTOLOAD_STRUCTURE) 392256200Sjfv i += E1000_INVM_CSR_AUTOLOAD_DATA_SIZE_IN_DWORDS; 393256200Sjfv if (record_type == E1000_INVM_RSA_KEY_SHA256_STRUCTURE) 394256200Sjfv i += E1000_INVM_RSA_KEY_SHA256_DATA_SIZE_IN_DWORDS; 395256200Sjfv if (record_type == E1000_INVM_WORD_AUTOLOAD_STRUCTURE) { 396256200Sjfv word_address = INVM_DWORD_TO_WORD_ADDRESS(invm_dword); 397256200Sjfv if (word_address == address) { 398256200Sjfv *data = INVM_DWORD_TO_WORD_DATA(invm_dword); 399256200Sjfv DEBUGOUT2("Read INVM Word 0x%02x = %x", 400256200Sjfv address, *data); 401256200Sjfv status = E1000_SUCCESS; 402256200Sjfv break; 403256200Sjfv } 404256200Sjfv } 405256200Sjfv } 406256200Sjfv if (status != E1000_SUCCESS) 407256200Sjfv DEBUGOUT1("Requested word 0x%02x not found in OTP\n", address); 408256200Sjfv return status; 409256200Sjfv} 410256200Sjfv 411256200Sjfv/** e1000_read_invm_i210 - Read invm wrapper function for I210/I211 412256200Sjfv * @hw: pointer to the HW structure 413256200Sjfv * @address: the word address (aka eeprom offset) to read 414256200Sjfv * @data: pointer to the data read 415256200Sjfv * 416238148Sjfv * Wrapper function to return data formerly found in the NVM. 417238148Sjfv **/ 418256200Sjfvstatic s32 e1000_read_invm_i210(struct e1000_hw *hw, u16 offset, 419256200Sjfv u16 E1000_UNUSEDARG words, u16 *data) 420238148Sjfv{ 421238148Sjfv s32 ret_val = E1000_SUCCESS; 422238148Sjfv 423256200Sjfv DEBUGFUNC("e1000_read_invm_i210"); 424238148Sjfv 425238148Sjfv /* Only the MAC addr is required to be present in the iNVM */ 426238148Sjfv switch (offset) { 427238148Sjfv case NVM_MAC_ADDR: 428256200Sjfv ret_val = e1000_read_invm_word_i210(hw, (u8)offset, &data[0]); 429256200Sjfv ret_val |= e1000_read_invm_word_i210(hw, (u8)offset+1, 430256200Sjfv &data[1]); 431256200Sjfv ret_val |= e1000_read_invm_word_i210(hw, (u8)offset+2, 432256200Sjfv &data[2]); 433238148Sjfv if (ret_val != E1000_SUCCESS) 434238148Sjfv DEBUGOUT("MAC Addr not found in iNVM\n"); 435238148Sjfv break; 436238148Sjfv case NVM_INIT_CTRL_2: 437256200Sjfv ret_val = e1000_read_invm_word_i210(hw, (u8)offset, data); 438247064Sjfv if (ret_val != E1000_SUCCESS) { 439247064Sjfv *data = NVM_INIT_CTRL_2_DEFAULT_I211; 440247064Sjfv ret_val = E1000_SUCCESS; 441247064Sjfv } 442247064Sjfv break; 443238148Sjfv case NVM_INIT_CTRL_4: 444256200Sjfv ret_val = e1000_read_invm_word_i210(hw, (u8)offset, data); 445247064Sjfv if (ret_val != E1000_SUCCESS) { 446247064Sjfv *data = NVM_INIT_CTRL_4_DEFAULT_I211; 447247064Sjfv ret_val = E1000_SUCCESS; 448247064Sjfv } 449247064Sjfv break; 450238148Sjfv case NVM_LED_1_CFG: 451256200Sjfv ret_val = e1000_read_invm_word_i210(hw, (u8)offset, data); 452247064Sjfv if (ret_val != E1000_SUCCESS) { 453247064Sjfv *data = NVM_LED_1_CFG_DEFAULT_I211; 454247064Sjfv ret_val = E1000_SUCCESS; 455247064Sjfv } 456247064Sjfv break; 457238148Sjfv case NVM_LED_0_2_CFG: 458256200Sjfv ret_val = e1000_read_invm_word_i210(hw, (u8)offset, data); 459247064Sjfv if (ret_val != E1000_SUCCESS) { 460247064Sjfv *data = NVM_LED_0_2_CFG_DEFAULT_I211; 461247064Sjfv ret_val = E1000_SUCCESS; 462247064Sjfv } 463238148Sjfv break; 464247064Sjfv case NVM_ID_LED_SETTINGS: 465256200Sjfv ret_val = e1000_read_invm_word_i210(hw, (u8)offset, data); 466247064Sjfv if (ret_val != E1000_SUCCESS) { 467247064Sjfv *data = ID_LED_RESERVED_FFFF; 468247064Sjfv ret_val = E1000_SUCCESS; 469247064Sjfv } 470238148Sjfv break; 471238148Sjfv case NVM_SUB_DEV_ID: 472238148Sjfv *data = hw->subsystem_device_id; 473238148Sjfv break; 474238148Sjfv case NVM_SUB_VEN_ID: 475238148Sjfv *data = hw->subsystem_vendor_id; 476238148Sjfv break; 477238148Sjfv case NVM_DEV_ID: 478238148Sjfv *data = hw->device_id; 479238148Sjfv break; 480238148Sjfv case NVM_VEN_ID: 481238148Sjfv *data = hw->vendor_id; 482238148Sjfv break; 483238148Sjfv default: 484238148Sjfv DEBUGOUT1("NVM word 0x%02x is not mapped.\n", offset); 485238148Sjfv *data = NVM_RESERVED_WORD; 486238148Sjfv break; 487238148Sjfv } 488238148Sjfv return ret_val; 489238148Sjfv} 490238148Sjfv 491238148Sjfv/** 492238148Sjfv * e1000_validate_nvm_checksum_i210 - Validate EEPROM checksum 493238148Sjfv * @hw: pointer to the HW structure 494238148Sjfv * 495238148Sjfv * Calculates the EEPROM checksum by reading/adding each word of the EEPROM 496238148Sjfv * and then verifies that the sum of the EEPROM is equal to 0xBABA. 497238148Sjfv **/ 498238148Sjfvs32 e1000_validate_nvm_checksum_i210(struct e1000_hw *hw) 499238148Sjfv{ 500238148Sjfv s32 status = E1000_SUCCESS; 501238148Sjfv s32 (*read_op_ptr)(struct e1000_hw *, u16, u16, u16 *); 502238148Sjfv 503238148Sjfv DEBUGFUNC("e1000_validate_nvm_checksum_i210"); 504238148Sjfv 505238148Sjfv if (hw->nvm.ops.acquire(hw) == E1000_SUCCESS) { 506238148Sjfv 507238148Sjfv /* 508238148Sjfv * Replace the read function with semaphore grabbing with 509238148Sjfv * the one that skips this for a while. 510238148Sjfv * We have semaphore taken already here. 511238148Sjfv */ 512238148Sjfv read_op_ptr = hw->nvm.ops.read; 513238148Sjfv hw->nvm.ops.read = e1000_read_nvm_eerd; 514238148Sjfv 515238148Sjfv status = e1000_validate_nvm_checksum_generic(hw); 516238148Sjfv 517238148Sjfv /* Revert original read operation. */ 518238148Sjfv hw->nvm.ops.read = read_op_ptr; 519238148Sjfv 520238148Sjfv hw->nvm.ops.release(hw); 521238148Sjfv } else { 522238148Sjfv status = E1000_ERR_SWFW_SYNC; 523238148Sjfv } 524238148Sjfv 525238148Sjfv return status; 526238148Sjfv} 527238148Sjfv 528238148Sjfv 529238148Sjfv/** 530238148Sjfv * e1000_update_nvm_checksum_i210 - Update EEPROM checksum 531238148Sjfv * @hw: pointer to the HW structure 532238148Sjfv * 533238148Sjfv * Updates the EEPROM checksum by reading/adding each word of the EEPROM 534238148Sjfv * up to the checksum. Then calculates the EEPROM checksum and writes the 535238148Sjfv * value to the EEPROM. Next commit EEPROM data onto the Flash. 536238148Sjfv **/ 537238148Sjfvs32 e1000_update_nvm_checksum_i210(struct e1000_hw *hw) 538238148Sjfv{ 539267935Sjfv s32 ret_val; 540238148Sjfv u16 checksum = 0; 541238148Sjfv u16 i, nvm_data; 542238148Sjfv 543238148Sjfv DEBUGFUNC("e1000_update_nvm_checksum_i210"); 544238148Sjfv 545238148Sjfv /* 546238148Sjfv * Read the first word from the EEPROM. If this times out or fails, do 547238148Sjfv * not continue or we could be in for a very long wait while every 548238148Sjfv * EEPROM read fails 549238148Sjfv */ 550238148Sjfv ret_val = e1000_read_nvm_eerd(hw, 0, 1, &nvm_data); 551238148Sjfv if (ret_val != E1000_SUCCESS) { 552238148Sjfv DEBUGOUT("EEPROM read failed\n"); 553238148Sjfv goto out; 554238148Sjfv } 555238148Sjfv 556238148Sjfv if (hw->nvm.ops.acquire(hw) == E1000_SUCCESS) { 557238148Sjfv /* 558238148Sjfv * Do not use hw->nvm.ops.write, hw->nvm.ops.read 559238148Sjfv * because we do not want to take the synchronization 560238148Sjfv * semaphores twice here. 561238148Sjfv */ 562238148Sjfv 563238148Sjfv for (i = 0; i < NVM_CHECKSUM_REG; i++) { 564238148Sjfv ret_val = e1000_read_nvm_eerd(hw, i, 1, &nvm_data); 565238148Sjfv if (ret_val) { 566238148Sjfv hw->nvm.ops.release(hw); 567238148Sjfv DEBUGOUT("NVM Read Error while updating checksum.\n"); 568238148Sjfv goto out; 569238148Sjfv } 570238148Sjfv checksum += nvm_data; 571238148Sjfv } 572238148Sjfv checksum = (u16) NVM_SUM - checksum; 573238148Sjfv ret_val = e1000_write_nvm_srwr(hw, NVM_CHECKSUM_REG, 1, 574238148Sjfv &checksum); 575238148Sjfv if (ret_val != E1000_SUCCESS) { 576238148Sjfv hw->nvm.ops.release(hw); 577238148Sjfv DEBUGOUT("NVM Write Error while updating checksum.\n"); 578238148Sjfv goto out; 579238148Sjfv } 580238148Sjfv 581238148Sjfv hw->nvm.ops.release(hw); 582238148Sjfv 583238148Sjfv ret_val = e1000_update_flash_i210(hw); 584238148Sjfv } else { 585238148Sjfv ret_val = E1000_ERR_SWFW_SYNC; 586238148Sjfv } 587238148Sjfvout: 588238148Sjfv return ret_val; 589238148Sjfv} 590238148Sjfv 591238148Sjfv/** 592256200Sjfv * e1000_get_flash_presence_i210 - Check if flash device is detected. 593256200Sjfv * @hw: pointer to the HW structure 594256200Sjfv * 595256200Sjfv **/ 596256200Sjfvbool e1000_get_flash_presence_i210(struct e1000_hw *hw) 597256200Sjfv{ 598256200Sjfv u32 eec = 0; 599256200Sjfv bool ret_val = FALSE; 600256200Sjfv 601256200Sjfv DEBUGFUNC("e1000_get_flash_presence_i210"); 602256200Sjfv 603256200Sjfv eec = E1000_READ_REG(hw, E1000_EECD); 604256200Sjfv 605256200Sjfv if (eec & E1000_EECD_FLASH_DETECTED_I210) 606256200Sjfv ret_val = TRUE; 607256200Sjfv 608256200Sjfv return ret_val; 609256200Sjfv} 610256200Sjfv 611256200Sjfv/** 612238148Sjfv * e1000_update_flash_i210 - Commit EEPROM to the flash 613238148Sjfv * @hw: pointer to the HW structure 614238148Sjfv * 615238148Sjfv **/ 616238148Sjfvs32 e1000_update_flash_i210(struct e1000_hw *hw) 617238148Sjfv{ 618267935Sjfv s32 ret_val; 619238148Sjfv u32 flup; 620238148Sjfv 621238148Sjfv DEBUGFUNC("e1000_update_flash_i210"); 622238148Sjfv 623238148Sjfv ret_val = e1000_pool_flash_update_done_i210(hw); 624238148Sjfv if (ret_val == -E1000_ERR_NVM) { 625238148Sjfv DEBUGOUT("Flash update time out\n"); 626238148Sjfv goto out; 627238148Sjfv } 628238148Sjfv 629238148Sjfv flup = E1000_READ_REG(hw, E1000_EECD) | E1000_EECD_FLUPD_I210; 630238148Sjfv E1000_WRITE_REG(hw, E1000_EECD, flup); 631238148Sjfv 632238148Sjfv ret_val = e1000_pool_flash_update_done_i210(hw); 633238148Sjfv if (ret_val == E1000_SUCCESS) 634238148Sjfv DEBUGOUT("Flash update complete\n"); 635238148Sjfv else 636238148Sjfv DEBUGOUT("Flash update time out\n"); 637238148Sjfv 638238148Sjfvout: 639238148Sjfv return ret_val; 640238148Sjfv} 641238148Sjfv 642238148Sjfv/** 643238148Sjfv * e1000_pool_flash_update_done_i210 - Pool FLUDONE status. 644238148Sjfv * @hw: pointer to the HW structure 645238148Sjfv * 646238148Sjfv **/ 647238148Sjfvs32 e1000_pool_flash_update_done_i210(struct e1000_hw *hw) 648238148Sjfv{ 649238148Sjfv s32 ret_val = -E1000_ERR_NVM; 650238148Sjfv u32 i, reg; 651238148Sjfv 652238148Sjfv DEBUGFUNC("e1000_pool_flash_update_done_i210"); 653238148Sjfv 654238148Sjfv for (i = 0; i < E1000_FLUDONE_ATTEMPTS; i++) { 655238148Sjfv reg = E1000_READ_REG(hw, E1000_EECD); 656238148Sjfv if (reg & E1000_EECD_FLUDONE_I210) { 657238148Sjfv ret_val = E1000_SUCCESS; 658238148Sjfv break; 659238148Sjfv } 660238148Sjfv usec_delay(5); 661238148Sjfv } 662238148Sjfv 663238148Sjfv return ret_val; 664238148Sjfv} 665238148Sjfv 666238148Sjfv/** 667238148Sjfv * e1000_init_nvm_params_i210 - Initialize i210 NVM function pointers 668238148Sjfv * @hw: pointer to the HW structure 669238148Sjfv * 670256200Sjfv * Initialize the i210/i211 NVM parameters and function pointers. 671238148Sjfv **/ 672238148Sjfvstatic s32 e1000_init_nvm_params_i210(struct e1000_hw *hw) 673238148Sjfv{ 674267935Sjfv s32 ret_val; 675238148Sjfv struct e1000_nvm_info *nvm = &hw->nvm; 676238148Sjfv 677238148Sjfv DEBUGFUNC("e1000_init_nvm_params_i210"); 678238148Sjfv 679238148Sjfv ret_val = e1000_init_nvm_params_82575(hw); 680238148Sjfv nvm->ops.acquire = e1000_acquire_nvm_i210; 681238148Sjfv nvm->ops.release = e1000_release_nvm_i210; 682238148Sjfv nvm->ops.valid_led_default = e1000_valid_led_default_i210; 683256200Sjfv if (e1000_get_flash_presence_i210(hw)) { 684256200Sjfv hw->nvm.type = e1000_nvm_flash_hw; 685256200Sjfv nvm->ops.read = e1000_read_nvm_srrd_i210; 686256200Sjfv nvm->ops.write = e1000_write_nvm_srwr_i210; 687256200Sjfv nvm->ops.validate = e1000_validate_nvm_checksum_i210; 688256200Sjfv nvm->ops.update = e1000_update_nvm_checksum_i210; 689256200Sjfv } else { 690256200Sjfv hw->nvm.type = e1000_nvm_invm; 691256200Sjfv nvm->ops.read = e1000_read_invm_i210; 692256200Sjfv nvm->ops.write = e1000_null_write_nvm; 693256200Sjfv nvm->ops.validate = e1000_null_ops_generic; 694256200Sjfv nvm->ops.update = e1000_null_ops_generic; 695256200Sjfv } 696238148Sjfv return ret_val; 697238148Sjfv} 698238148Sjfv 699238148Sjfv/** 700238148Sjfv * e1000_init_function_pointers_i210 - Init func ptrs. 701238148Sjfv * @hw: pointer to the HW structure 702238148Sjfv * 703238148Sjfv * Called to initialize all function pointers and parameters. 704238148Sjfv **/ 705238148Sjfvvoid e1000_init_function_pointers_i210(struct e1000_hw *hw) 706238148Sjfv{ 707238148Sjfv e1000_init_function_pointers_82575(hw); 708256200Sjfv hw->nvm.ops.init_params = e1000_init_nvm_params_i210; 709238148Sjfv 710238148Sjfv return; 711238148Sjfv} 712238148Sjfv 713238148Sjfv/** 714238148Sjfv * e1000_valid_led_default_i210 - Verify a valid default LED config 715238148Sjfv * @hw: pointer to the HW structure 716238148Sjfv * @data: pointer to the NVM (EEPROM) 717238148Sjfv * 718238148Sjfv * Read the EEPROM for the current default LED configuration. If the 719238148Sjfv * LED configuration is not valid, set to a valid LED configuration. 720238148Sjfv **/ 721238148Sjfvstatic s32 e1000_valid_led_default_i210(struct e1000_hw *hw, u16 *data) 722238148Sjfv{ 723238148Sjfv s32 ret_val; 724238148Sjfv 725238148Sjfv DEBUGFUNC("e1000_valid_led_default_i210"); 726238148Sjfv 727238148Sjfv ret_val = hw->nvm.ops.read(hw, NVM_ID_LED_SETTINGS, 1, data); 728238148Sjfv if (ret_val) { 729238148Sjfv DEBUGOUT("NVM Read Error\n"); 730238148Sjfv goto out; 731238148Sjfv } 732238148Sjfv 733238148Sjfv if (*data == ID_LED_RESERVED_0000 || *data == ID_LED_RESERVED_FFFF) { 734238148Sjfv switch (hw->phy.media_type) { 735238148Sjfv case e1000_media_type_internal_serdes: 736238148Sjfv *data = ID_LED_DEFAULT_I210_SERDES; 737238148Sjfv break; 738238148Sjfv case e1000_media_type_copper: 739238148Sjfv default: 740238148Sjfv *data = ID_LED_DEFAULT_I210; 741238148Sjfv break; 742238148Sjfv } 743238148Sjfv } 744238148Sjfvout: 745238148Sjfv return ret_val; 746238148Sjfv} 747256200Sjfv 748256200Sjfv/** 749256200Sjfv * __e1000_access_xmdio_reg - Read/write XMDIO register 750256200Sjfv * @hw: pointer to the HW structure 751256200Sjfv * @address: XMDIO address to program 752256200Sjfv * @dev_addr: device address to program 753256200Sjfv * @data: pointer to value to read/write from/to the XMDIO address 754256200Sjfv * @read: boolean flag to indicate read or write 755256200Sjfv **/ 756256200Sjfvstatic s32 __e1000_access_xmdio_reg(struct e1000_hw *hw, u16 address, 757256200Sjfv u8 dev_addr, u16 *data, bool read) 758256200Sjfv{ 759267935Sjfv s32 ret_val; 760256200Sjfv 761256200Sjfv DEBUGFUNC("__e1000_access_xmdio_reg"); 762256200Sjfv 763256200Sjfv ret_val = hw->phy.ops.write_reg(hw, E1000_MMDAC, dev_addr); 764256200Sjfv if (ret_val) 765256200Sjfv return ret_val; 766256200Sjfv 767256200Sjfv ret_val = hw->phy.ops.write_reg(hw, E1000_MMDAAD, address); 768256200Sjfv if (ret_val) 769256200Sjfv return ret_val; 770256200Sjfv 771256200Sjfv ret_val = hw->phy.ops.write_reg(hw, E1000_MMDAC, E1000_MMDAC_FUNC_DATA | 772256200Sjfv dev_addr); 773256200Sjfv if (ret_val) 774256200Sjfv return ret_val; 775256200Sjfv 776256200Sjfv if (read) 777256200Sjfv ret_val = hw->phy.ops.read_reg(hw, E1000_MMDAAD, data); 778256200Sjfv else 779256200Sjfv ret_val = hw->phy.ops.write_reg(hw, E1000_MMDAAD, *data); 780256200Sjfv if (ret_val) 781256200Sjfv return ret_val; 782256200Sjfv 783256200Sjfv /* Recalibrate the device back to 0 */ 784256200Sjfv ret_val = hw->phy.ops.write_reg(hw, E1000_MMDAC, 0); 785256200Sjfv if (ret_val) 786256200Sjfv return ret_val; 787256200Sjfv 788256200Sjfv return ret_val; 789256200Sjfv} 790256200Sjfv 791256200Sjfv/** 792256200Sjfv * e1000_read_xmdio_reg - Read XMDIO register 793256200Sjfv * @hw: pointer to the HW structure 794256200Sjfv * @addr: XMDIO address to program 795256200Sjfv * @dev_addr: device address to program 796256200Sjfv * @data: value to be read from the EMI address 797256200Sjfv **/ 798256200Sjfvs32 e1000_read_xmdio_reg(struct e1000_hw *hw, u16 addr, u8 dev_addr, u16 *data) 799256200Sjfv{ 800256200Sjfv DEBUGFUNC("e1000_read_xmdio_reg"); 801256200Sjfv 802256200Sjfv return __e1000_access_xmdio_reg(hw, addr, dev_addr, data, TRUE); 803256200Sjfv} 804256200Sjfv 805256200Sjfv/** 806256200Sjfv * e1000_write_xmdio_reg - Write XMDIO register 807256200Sjfv * @hw: pointer to the HW structure 808256200Sjfv * @addr: XMDIO address to program 809256200Sjfv * @dev_addr: device address to program 810256200Sjfv * @data: value to be written to the XMDIO address 811256200Sjfv **/ 812256200Sjfvs32 e1000_write_xmdio_reg(struct e1000_hw *hw, u16 addr, u8 dev_addr, u16 data) 813256200Sjfv{ 814256200Sjfv DEBUGFUNC("e1000_read_xmdio_reg"); 815256200Sjfv 816256200Sjfv return __e1000_access_xmdio_reg(hw, addr, dev_addr, &data, FALSE); 817256200Sjfv} 818267935Sjfv 819267935Sjfv/** 820267935Sjfv * e1000_pll_workaround_i210 821267935Sjfv * @hw: pointer to the HW structure 822267935Sjfv * 823267935Sjfv * Works around an errata in the PLL circuit where it occasionally 824267935Sjfv * provides the wrong clock frequency after power up. 825267935Sjfv **/ 826267935Sjfvstatic s32 e1000_pll_workaround_i210(struct e1000_hw *hw) 827267935Sjfv{ 828267935Sjfv s32 ret_val; 829267935Sjfv u32 wuc, mdicnfg, ctrl, ctrl_ext, reg_val; 830267935Sjfv u16 nvm_word, phy_word, pci_word, tmp_nvm; 831267935Sjfv int i; 832267935Sjfv 833267935Sjfv /* Get and set needed register values */ 834267935Sjfv wuc = E1000_READ_REG(hw, E1000_WUC); 835267935Sjfv mdicnfg = E1000_READ_REG(hw, E1000_MDICNFG); 836267935Sjfv reg_val = mdicnfg & ~E1000_MDICNFG_EXT_MDIO; 837267935Sjfv E1000_WRITE_REG(hw, E1000_MDICNFG, reg_val); 838267935Sjfv 839267935Sjfv /* Get data from NVM, or set default */ 840267935Sjfv ret_val = e1000_read_invm_word_i210(hw, E1000_INVM_AUTOLOAD, 841267935Sjfv &nvm_word); 842267935Sjfv if (ret_val != E1000_SUCCESS) 843267935Sjfv nvm_word = E1000_INVM_DEFAULT_AL; 844267935Sjfv tmp_nvm = nvm_word | E1000_INVM_PLL_WO_VAL; 845267935Sjfv for (i = 0; i < E1000_MAX_PLL_TRIES; i++) { 846267935Sjfv /* check current state directly from internal PHY */ 847267935Sjfv e1000_read_phy_reg_gs40g(hw, (E1000_PHY_PLL_FREQ_PAGE | 848267935Sjfv E1000_PHY_PLL_FREQ_REG), &phy_word); 849267935Sjfv if ((phy_word & E1000_PHY_PLL_UNCONF) 850267935Sjfv != E1000_PHY_PLL_UNCONF) { 851267935Sjfv ret_val = E1000_SUCCESS; 852267935Sjfv break; 853267935Sjfv } else { 854267935Sjfv ret_val = -E1000_ERR_PHY; 855267935Sjfv } 856267935Sjfv /* directly reset the internal PHY */ 857267935Sjfv ctrl = E1000_READ_REG(hw, E1000_CTRL); 858267935Sjfv E1000_WRITE_REG(hw, E1000_CTRL, ctrl|E1000_CTRL_PHY_RST); 859267935Sjfv 860267935Sjfv ctrl_ext = E1000_READ_REG(hw, E1000_CTRL_EXT); 861267935Sjfv ctrl_ext |= (E1000_CTRL_EXT_PHYPDEN | E1000_CTRL_EXT_SDLPE); 862267935Sjfv E1000_WRITE_REG(hw, E1000_CTRL_EXT, ctrl_ext); 863267935Sjfv 864267935Sjfv E1000_WRITE_REG(hw, E1000_WUC, 0); 865267935Sjfv reg_val = (E1000_INVM_AUTOLOAD << 4) | (tmp_nvm << 16); 866267935Sjfv E1000_WRITE_REG(hw, E1000_EEARBC_I210, reg_val); 867267935Sjfv 868267935Sjfv e1000_read_pci_cfg(hw, E1000_PCI_PMCSR, &pci_word); 869267935Sjfv pci_word |= E1000_PCI_PMCSR_D3; 870267935Sjfv e1000_write_pci_cfg(hw, E1000_PCI_PMCSR, &pci_word); 871267935Sjfv msec_delay(1); 872267935Sjfv pci_word &= ~E1000_PCI_PMCSR_D3; 873267935Sjfv e1000_write_pci_cfg(hw, E1000_PCI_PMCSR, &pci_word); 874267935Sjfv reg_val = (E1000_INVM_AUTOLOAD << 4) | (nvm_word << 16); 875267935Sjfv E1000_WRITE_REG(hw, E1000_EEARBC_I210, reg_val); 876267935Sjfv 877267935Sjfv /* restore WUC register */ 878267935Sjfv E1000_WRITE_REG(hw, E1000_WUC, wuc); 879267935Sjfv } 880267935Sjfv /* restore MDICNFG setting */ 881267935Sjfv E1000_WRITE_REG(hw, E1000_MDICNFG, mdicnfg); 882267935Sjfv return ret_val; 883267935Sjfv} 884267935Sjfv 885267935Sjfv/** 886295323Serj * e1000_get_cfg_done_i210 - Read config done bit 887295323Serj * @hw: pointer to the HW structure 888295323Serj * 889295323Serj * Read the management control register for the config done bit for 890295323Serj * completion status. NOTE: silicon which is EEPROM-less will fail trying 891295323Serj * to read the config done bit, so an error is *ONLY* logged and returns 892295323Serj * E1000_SUCCESS. If we were to return with error, EEPROM-less silicon 893295323Serj * would not be able to be reset or change link. 894295323Serj **/ 895295323Serjstatic s32 e1000_get_cfg_done_i210(struct e1000_hw *hw) 896295323Serj{ 897295323Serj s32 timeout = PHY_CFG_TIMEOUT; 898295323Serj u32 mask = E1000_NVM_CFG_DONE_PORT_0; 899295323Serj 900295323Serj DEBUGFUNC("e1000_get_cfg_done_i210"); 901295323Serj 902295323Serj while (timeout) { 903295323Serj if (E1000_READ_REG(hw, E1000_EEMNGCTL_I210) & mask) 904295323Serj break; 905295323Serj msec_delay(1); 906295323Serj timeout--; 907295323Serj } 908295323Serj if (!timeout) 909295323Serj DEBUGOUT("MNG configuration cycle has not completed.\n"); 910295323Serj 911295323Serj return E1000_SUCCESS; 912295323Serj} 913295323Serj 914295323Serj/** 915267935Sjfv * e1000_init_hw_i210 - Init hw for I210/I211 916267935Sjfv * @hw: pointer to the HW structure 917267935Sjfv * 918267935Sjfv * Called to initialize hw for i210 hw family. 919267935Sjfv **/ 920267935Sjfvs32 e1000_init_hw_i210(struct e1000_hw *hw) 921267935Sjfv{ 922267935Sjfv s32 ret_val; 923267935Sjfv 924267935Sjfv DEBUGFUNC("e1000_init_hw_i210"); 925267935Sjfv if ((hw->mac.type >= e1000_i210) && 926267935Sjfv !(e1000_get_flash_presence_i210(hw))) { 927267935Sjfv ret_val = e1000_pll_workaround_i210(hw); 928267935Sjfv if (ret_val != E1000_SUCCESS) 929267935Sjfv return ret_val; 930267935Sjfv } 931295323Serj hw->phy.ops.get_cfg_done = e1000_get_cfg_done_i210; 932267935Sjfv ret_val = e1000_init_hw_82575(hw); 933267935Sjfv return ret_val; 934267935Sjfv} 935