e1000_i210.c revision ef3a009297c50876980f21060aee61e8b516a990
1f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny/******************************************************************************* 2f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny 3f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny Intel(R) Gigabit Ethernet Linux driver 44b9ea4626b52c113c367c4776c9bb11b7231393dAkeem G. Abodunrin Copyright(c) 2007-2013 Intel Corporation. 5f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny 6f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny This program is free software; you can redistribute it and/or modify it 7f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny under the terms and conditions of the GNU General Public License, 8f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny version 2, as published by the Free Software Foundation. 9f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny 10f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny This program is distributed in the hope it will be useful, but WITHOUT 11f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 13f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny more details. 14f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny 15f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny You should have received a copy of the GNU General Public License along with 16f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny this program; if not, write to the Free Software Foundation, Inc., 17f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. 18f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny 19f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny The full GNU General Public License is included in this distribution in 20f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny the file called "COPYING". 21f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny 22f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny Contact Information: 23f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny e1000-devel Mailing List <e1000-devel@lists.sourceforge.net> 24f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 25f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny 26f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny******************************************************************************/ 27f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny 28f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny/* e1000_i210 29f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * e1000_i211 30f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny */ 31f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny 32f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny#include <linux/types.h> 33f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny#include <linux/if_ether.h> 34f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny 35f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny#include "e1000_hw.h" 36f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny#include "e1000_i210.h" 37f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny 387916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny/** 397916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny * igb_get_hw_semaphore_i210 - Acquire hardware semaphore 407916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny * @hw: pointer to the HW structure 417916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny * 427916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny * Acquire the HW semaphore to access the PHY or NVM 437916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny */ 447916a53d203f12461095886cf72d58e9281240d9Carolyn Wybornystatic s32 igb_get_hw_semaphore_i210(struct e1000_hw *hw) 457916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny{ 467916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny u32 swsm; 477916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny s32 timeout = hw->nvm.word_size + 1; 487916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny s32 i = 0; 497916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny 50d44e7a9a1f1e56918f8e937dcf750626ac5ad9b4Matthew Vick /* Get the SW semaphore */ 51d44e7a9a1f1e56918f8e937dcf750626ac5ad9b4Matthew Vick while (i < timeout) { 52d44e7a9a1f1e56918f8e937dcf750626ac5ad9b4Matthew Vick swsm = rd32(E1000_SWSM); 53d44e7a9a1f1e56918f8e937dcf750626ac5ad9b4Matthew Vick if (!(swsm & E1000_SWSM_SMBI)) 54d44e7a9a1f1e56918f8e937dcf750626ac5ad9b4Matthew Vick break; 55d44e7a9a1f1e56918f8e937dcf750626ac5ad9b4Matthew Vick 56d44e7a9a1f1e56918f8e937dcf750626ac5ad9b4Matthew Vick udelay(50); 57d44e7a9a1f1e56918f8e937dcf750626ac5ad9b4Matthew Vick i++; 58d44e7a9a1f1e56918f8e937dcf750626ac5ad9b4Matthew Vick } 59d44e7a9a1f1e56918f8e937dcf750626ac5ad9b4Matthew Vick 60d44e7a9a1f1e56918f8e937dcf750626ac5ad9b4Matthew Vick if (i == timeout) { 61d44e7a9a1f1e56918f8e937dcf750626ac5ad9b4Matthew Vick /* In rare circumstances, the SW semaphore may already be held 62d44e7a9a1f1e56918f8e937dcf750626ac5ad9b4Matthew Vick * unintentionally. Clear the semaphore once before giving up. 63d44e7a9a1f1e56918f8e937dcf750626ac5ad9b4Matthew Vick */ 64d44e7a9a1f1e56918f8e937dcf750626ac5ad9b4Matthew Vick if (hw->dev_spec._82575.clear_semaphore_once) { 65d44e7a9a1f1e56918f8e937dcf750626ac5ad9b4Matthew Vick hw->dev_spec._82575.clear_semaphore_once = false; 66d44e7a9a1f1e56918f8e937dcf750626ac5ad9b4Matthew Vick igb_put_hw_semaphore(hw); 67d44e7a9a1f1e56918f8e937dcf750626ac5ad9b4Matthew Vick for (i = 0; i < timeout; i++) { 68d44e7a9a1f1e56918f8e937dcf750626ac5ad9b4Matthew Vick swsm = rd32(E1000_SWSM); 69d44e7a9a1f1e56918f8e937dcf750626ac5ad9b4Matthew Vick if (!(swsm & E1000_SWSM_SMBI)) 70d44e7a9a1f1e56918f8e937dcf750626ac5ad9b4Matthew Vick break; 71d44e7a9a1f1e56918f8e937dcf750626ac5ad9b4Matthew Vick 72d44e7a9a1f1e56918f8e937dcf750626ac5ad9b4Matthew Vick udelay(50); 73d44e7a9a1f1e56918f8e937dcf750626ac5ad9b4Matthew Vick } 74d44e7a9a1f1e56918f8e937dcf750626ac5ad9b4Matthew Vick } 75d44e7a9a1f1e56918f8e937dcf750626ac5ad9b4Matthew Vick 76d44e7a9a1f1e56918f8e937dcf750626ac5ad9b4Matthew Vick /* If we do not have the semaphore here, we have to give up. */ 77d44e7a9a1f1e56918f8e937dcf750626ac5ad9b4Matthew Vick if (i == timeout) { 78d44e7a9a1f1e56918f8e937dcf750626ac5ad9b4Matthew Vick hw_dbg("Driver can't access device - SMBI bit is set.\n"); 79d44e7a9a1f1e56918f8e937dcf750626ac5ad9b4Matthew Vick return -E1000_ERR_NVM; 80d44e7a9a1f1e56918f8e937dcf750626ac5ad9b4Matthew Vick } 81d44e7a9a1f1e56918f8e937dcf750626ac5ad9b4Matthew Vick } 82d44e7a9a1f1e56918f8e937dcf750626ac5ad9b4Matthew Vick 837916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny /* Get the FW semaphore. */ 847916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny for (i = 0; i < timeout; i++) { 857916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny swsm = rd32(E1000_SWSM); 867916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny wr32(E1000_SWSM, swsm | E1000_SWSM_SWESMBI); 877916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny 887916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny /* Semaphore acquired if bit latched */ 897916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny if (rd32(E1000_SWSM) & E1000_SWSM_SWESMBI) 907916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny break; 917916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny 927916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny udelay(50); 937916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny } 947916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny 957916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny if (i == timeout) { 967916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny /* Release semaphores */ 977916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny igb_put_hw_semaphore(hw); 987916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny hw_dbg("Driver can't access the NVM\n"); 99d44e7a9a1f1e56918f8e937dcf750626ac5ad9b4Matthew Vick return -E1000_ERR_NVM; 1007916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny } 1017916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny 102d44e7a9a1f1e56918f8e937dcf750626ac5ad9b4Matthew Vick return E1000_SUCCESS; 1037916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny} 104f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny 105f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny/** 106f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * igb_acquire_nvm_i210 - Request for access to EEPROM 107f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * @hw: pointer to the HW structure 108f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * 109f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * Acquire the necessary semaphores for exclusive access to the EEPROM. 110f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * Set the EEPROM access request bit and wait for EEPROM access grant bit. 111f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * Return successful if access grant bit set, else clear the request for 112f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * EEPROM access and return -E1000_ERR_NVM (-1). 113f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny **/ 114f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wybornys32 igb_acquire_nvm_i210(struct e1000_hw *hw) 115f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny{ 116f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny return igb_acquire_swfw_sync_i210(hw, E1000_SWFW_EEP_SM); 117f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny} 118f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny 119f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny/** 120f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * igb_release_nvm_i210 - Release exclusive access to EEPROM 121f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * @hw: pointer to the HW structure 122f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * 123f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * Stop any current commands to the EEPROM and clear the EEPROM request bit, 124f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * then release the semaphores acquired. 125f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny **/ 126f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wybornyvoid igb_release_nvm_i210(struct e1000_hw *hw) 127f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny{ 128f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny igb_release_swfw_sync_i210(hw, E1000_SWFW_EEP_SM); 129f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny} 130f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny 131f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny/** 132f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * igb_acquire_swfw_sync_i210 - Acquire SW/FW semaphore 133f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * @hw: pointer to the HW structure 134f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * @mask: specifies which semaphore to acquire 135f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * 136f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * Acquire the SW/FW semaphore to access the PHY or NVM. The mask 137f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * will also specify which port we're acquiring the lock for. 138f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny **/ 139f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wybornys32 igb_acquire_swfw_sync_i210(struct e1000_hw *hw, u16 mask) 140f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny{ 141f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny u32 swfw_sync; 142f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny u32 swmask = mask; 143f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny u32 fwmask = mask << 16; 144f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny s32 ret_val = E1000_SUCCESS; 145f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny s32 i = 0, timeout = 200; /* FIXME: find real value to use here */ 146f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny 147f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny while (i < timeout) { 148f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny if (igb_get_hw_semaphore_i210(hw)) { 149f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny ret_val = -E1000_ERR_SWFW_SYNC; 150f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny goto out; 151f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny } 152f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny 153f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny swfw_sync = rd32(E1000_SW_FW_SYNC); 154d44e7a9a1f1e56918f8e937dcf750626ac5ad9b4Matthew Vick if (!(swfw_sync & (fwmask | swmask))) 155f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny break; 156f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny 157b980ac18c95f3251038da7a3826370aff05a7434Jeff Kirsher /* Firmware currently using resource (fwmask) */ 158d44e7a9a1f1e56918f8e937dcf750626ac5ad9b4Matthew Vick igb_put_hw_semaphore(hw); 159f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny mdelay(5); 160f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny i++; 161f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny } 162f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny 163f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny if (i == timeout) { 164f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny hw_dbg("Driver can't access resource, SW_FW_SYNC timeout.\n"); 165f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny ret_val = -E1000_ERR_SWFW_SYNC; 166f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny goto out; 167f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny } 168f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny 169f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny swfw_sync |= swmask; 170f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny wr32(E1000_SW_FW_SYNC, swfw_sync); 171f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny 172d44e7a9a1f1e56918f8e937dcf750626ac5ad9b4Matthew Vick igb_put_hw_semaphore(hw); 173f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wybornyout: 174f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny return ret_val; 175f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny} 176f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny 177f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny/** 178f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * igb_release_swfw_sync_i210 - Release SW/FW semaphore 179f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * @hw: pointer to the HW structure 180f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * @mask: specifies which semaphore to acquire 181f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * 182f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * Release the SW/FW semaphore used to access the PHY or NVM. The mask 183f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * will also specify which port we're releasing the lock for. 184f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny **/ 185f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wybornyvoid igb_release_swfw_sync_i210(struct e1000_hw *hw, u16 mask) 186f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny{ 187f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny u32 swfw_sync; 188f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny 189f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny while (igb_get_hw_semaphore_i210(hw) != E1000_SUCCESS) 190f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny ; /* Empty */ 191f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny 192f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny swfw_sync = rd32(E1000_SW_FW_SYNC); 193f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny swfw_sync &= ~mask; 194f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny wr32(E1000_SW_FW_SYNC, swfw_sync); 195f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny 196d44e7a9a1f1e56918f8e937dcf750626ac5ad9b4Matthew Vick igb_put_hw_semaphore(hw); 197f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny} 198f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny 199f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny/** 200f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * igb_read_nvm_srrd_i210 - Reads Shadow Ram using EERD register 201f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * @hw: pointer to the HW structure 202f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * @offset: offset of word in the Shadow Ram to read 203f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * @words: number of words to read 204f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * @data: word read from the Shadow Ram 205f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * 206f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * Reads a 16 bit word from the Shadow Ram using the EERD register. 207f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * Uses necessary synchronization semaphores. 208f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny **/ 209f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wybornys32 igb_read_nvm_srrd_i210(struct e1000_hw *hw, u16 offset, u16 words, 210f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny u16 *data) 211f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny{ 212f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny s32 status = E1000_SUCCESS; 213f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny u16 i, count; 214f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny 215f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny /* We cannot hold synchronization semaphores for too long, 216f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * because of forceful takeover procedure. However it is more efficient 217b980ac18c95f3251038da7a3826370aff05a7434Jeff Kirsher * to read in bursts than synchronizing access for each word. 218b980ac18c95f3251038da7a3826370aff05a7434Jeff Kirsher */ 219f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny for (i = 0; i < words; i += E1000_EERD_EEWR_MAX_COUNT) { 220f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny count = (words - i) / E1000_EERD_EEWR_MAX_COUNT > 0 ? 221f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny E1000_EERD_EEWR_MAX_COUNT : (words - i); 222f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny if (hw->nvm.ops.acquire(hw) == E1000_SUCCESS) { 223f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny status = igb_read_nvm_eerd(hw, offset, count, 224f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny data + i); 225f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny hw->nvm.ops.release(hw); 226f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny } else { 227f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny status = E1000_ERR_SWFW_SYNC; 228f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny } 229f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny 230f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny if (status != E1000_SUCCESS) 231f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny break; 232f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny } 233f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny 234f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny return status; 235f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny} 236f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny 237f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny/** 238f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * igb_write_nvm_srwr - Write to Shadow Ram using EEWR 239f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * @hw: pointer to the HW structure 240f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * @offset: offset within the Shadow Ram to be written to 241f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * @words: number of words to write 242f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * @data: 16 bit word(s) to be written to the Shadow Ram 243f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * 244f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * Writes data to Shadow Ram at offset using EEWR register. 245f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * 246f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * If igb_update_nvm_checksum is not called after this function , the 247f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * Shadow Ram will most likely contain an invalid checksum. 248f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny **/ 249f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wybornystatic s32 igb_write_nvm_srwr(struct e1000_hw *hw, u16 offset, u16 words, 250f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny u16 *data) 251f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny{ 252f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny struct e1000_nvm_info *nvm = &hw->nvm; 253f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny u32 i, k, eewr = 0; 254f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny u32 attempts = 100000; 255f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny s32 ret_val = E1000_SUCCESS; 256f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny 257b980ac18c95f3251038da7a3826370aff05a7434Jeff Kirsher /* A check for invalid values: offset too large, too many words, 258f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * too many words for the offset, and not enough words. 259f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny */ 260f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) || 261f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny (words == 0)) { 262f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny hw_dbg("nvm parameter(s) out of bounds\n"); 263f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny ret_val = -E1000_ERR_NVM; 264f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny goto out; 265f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny } 266f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny 267f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny for (i = 0; i < words; i++) { 268f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny eewr = ((offset+i) << E1000_NVM_RW_ADDR_SHIFT) | 269f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny (data[i] << E1000_NVM_RW_REG_DATA) | 270f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny E1000_NVM_RW_REG_START; 271f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny 272f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny wr32(E1000_SRWR, eewr); 273f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny 274f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny for (k = 0; k < attempts; k++) { 275f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny if (E1000_NVM_RW_REG_DONE & 276f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny rd32(E1000_SRWR)) { 277f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny ret_val = E1000_SUCCESS; 278f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny break; 279f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny } 280f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny udelay(5); 281f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny } 282f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny 283f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny if (ret_val != E1000_SUCCESS) { 284f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny hw_dbg("Shadow RAM write EEWR timed out\n"); 285f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny break; 286f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny } 287f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny } 288f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny 289f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wybornyout: 290f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny return ret_val; 291f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny} 292f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny 293f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny/** 2947916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny * igb_write_nvm_srwr_i210 - Write to Shadow RAM using EEWR 2957916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny * @hw: pointer to the HW structure 2967916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny * @offset: offset within the Shadow RAM to be written to 2977916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny * @words: number of words to write 2987916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny * @data: 16 bit word(s) to be written to the Shadow RAM 2997916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny * 3007916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny * Writes data to Shadow RAM at offset using EEWR register. 3017916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny * 3027916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny * If e1000_update_nvm_checksum is not called after this function , the 3037916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny * data will not be committed to FLASH and also Shadow RAM will most likely 3047916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny * contain an invalid checksum. 3057916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny * 3067916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny * If error code is returned, data and Shadow RAM may be inconsistent - buffer 3077916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny * partially written. 308b980ac18c95f3251038da7a3826370aff05a7434Jeff Kirsher **/ 3097916a53d203f12461095886cf72d58e9281240d9Carolyn Wybornys32 igb_write_nvm_srwr_i210(struct e1000_hw *hw, u16 offset, u16 words, 3107916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny u16 *data) 3117916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny{ 3127916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny s32 status = E1000_SUCCESS; 3137916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny u16 i, count; 3147916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny 3157916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny /* We cannot hold synchronization semaphores for too long, 3167916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny * because of forceful takeover procedure. However it is more efficient 3177916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny * to write in bursts than synchronizing access for each word. 3187916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny */ 3197916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny for (i = 0; i < words; i += E1000_EERD_EEWR_MAX_COUNT) { 3207916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny count = (words - i) / E1000_EERD_EEWR_MAX_COUNT > 0 ? 3217916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny E1000_EERD_EEWR_MAX_COUNT : (words - i); 3227916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny if (hw->nvm.ops.acquire(hw) == E1000_SUCCESS) { 3237916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny status = igb_write_nvm_srwr(hw, offset, count, 3247916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny data + i); 3257916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny hw->nvm.ops.release(hw); 3267916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny } else { 3277916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny status = E1000_ERR_SWFW_SYNC; 3287916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny } 3297916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny 3307916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny if (status != E1000_SUCCESS) 3317916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny break; 3327916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny } 3337916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny 3347916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny return status; 3357916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny} 3367916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny 3377916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny/** 338ef3a009297c50876980f21060aee61e8b516a990Carolyn Wyborny * igb_read_invm_word_i210 - Reads OTP 339ef3a009297c50876980f21060aee61e8b516a990Carolyn Wyborny * @hw: pointer to the HW structure 340ef3a009297c50876980f21060aee61e8b516a990Carolyn Wyborny * @address: the word address (aka eeprom offset) to read 341ef3a009297c50876980f21060aee61e8b516a990Carolyn Wyborny * @data: pointer to the data read 342ef3a009297c50876980f21060aee61e8b516a990Carolyn Wyborny * 343ef3a009297c50876980f21060aee61e8b516a990Carolyn Wyborny * Reads 16-bit words from the OTP. Return error when the word is not 344ef3a009297c50876980f21060aee61e8b516a990Carolyn Wyborny * stored in OTP. 345ef3a009297c50876980f21060aee61e8b516a990Carolyn Wyborny **/ 346ef3a009297c50876980f21060aee61e8b516a990Carolyn Wybornystatic s32 igb_read_invm_word_i210(struct e1000_hw *hw, u8 address, u16 *data) 347ef3a009297c50876980f21060aee61e8b516a990Carolyn Wyborny{ 348ef3a009297c50876980f21060aee61e8b516a990Carolyn Wyborny s32 status = -E1000_ERR_INVM_VALUE_NOT_FOUND; 349ef3a009297c50876980f21060aee61e8b516a990Carolyn Wyborny u32 invm_dword; 350ef3a009297c50876980f21060aee61e8b516a990Carolyn Wyborny u16 i; 351ef3a009297c50876980f21060aee61e8b516a990Carolyn Wyborny u8 record_type, word_address; 352ef3a009297c50876980f21060aee61e8b516a990Carolyn Wyborny 353ef3a009297c50876980f21060aee61e8b516a990Carolyn Wyborny for (i = 0; i < E1000_INVM_SIZE; i++) { 354ef3a009297c50876980f21060aee61e8b516a990Carolyn Wyborny invm_dword = rd32(E1000_INVM_DATA_REG(i)); 355ef3a009297c50876980f21060aee61e8b516a990Carolyn Wyborny /* Get record type */ 356ef3a009297c50876980f21060aee61e8b516a990Carolyn Wyborny record_type = INVM_DWORD_TO_RECORD_TYPE(invm_dword); 357ef3a009297c50876980f21060aee61e8b516a990Carolyn Wyborny if (record_type == E1000_INVM_UNINITIALIZED_STRUCTURE) 358ef3a009297c50876980f21060aee61e8b516a990Carolyn Wyborny break; 359ef3a009297c50876980f21060aee61e8b516a990Carolyn Wyborny if (record_type == E1000_INVM_CSR_AUTOLOAD_STRUCTURE) 360ef3a009297c50876980f21060aee61e8b516a990Carolyn Wyborny i += E1000_INVM_CSR_AUTOLOAD_DATA_SIZE_IN_DWORDS; 361ef3a009297c50876980f21060aee61e8b516a990Carolyn Wyborny if (record_type == E1000_INVM_RSA_KEY_SHA256_STRUCTURE) 362ef3a009297c50876980f21060aee61e8b516a990Carolyn Wyborny i += E1000_INVM_RSA_KEY_SHA256_DATA_SIZE_IN_DWORDS; 363ef3a009297c50876980f21060aee61e8b516a990Carolyn Wyborny if (record_type == E1000_INVM_WORD_AUTOLOAD_STRUCTURE) { 364ef3a009297c50876980f21060aee61e8b516a990Carolyn Wyborny word_address = INVM_DWORD_TO_WORD_ADDRESS(invm_dword); 365ef3a009297c50876980f21060aee61e8b516a990Carolyn Wyborny if (word_address == address) { 366ef3a009297c50876980f21060aee61e8b516a990Carolyn Wyborny *data = INVM_DWORD_TO_WORD_DATA(invm_dword); 367ef3a009297c50876980f21060aee61e8b516a990Carolyn Wyborny hw_dbg("Read INVM Word 0x%02x = %x", 368ef3a009297c50876980f21060aee61e8b516a990Carolyn Wyborny address, *data); 369ef3a009297c50876980f21060aee61e8b516a990Carolyn Wyborny status = E1000_SUCCESS; 370ef3a009297c50876980f21060aee61e8b516a990Carolyn Wyborny break; 371ef3a009297c50876980f21060aee61e8b516a990Carolyn Wyborny } 372ef3a009297c50876980f21060aee61e8b516a990Carolyn Wyborny } 373ef3a009297c50876980f21060aee61e8b516a990Carolyn Wyborny } 374ef3a009297c50876980f21060aee61e8b516a990Carolyn Wyborny if (status != E1000_SUCCESS) 375ef3a009297c50876980f21060aee61e8b516a990Carolyn Wyborny hw_dbg("Requested word 0x%02x not found in OTP\n", address); 376ef3a009297c50876980f21060aee61e8b516a990Carolyn Wyborny return status; 377ef3a009297c50876980f21060aee61e8b516a990Carolyn Wyborny} 378ef3a009297c50876980f21060aee61e8b516a990Carolyn Wyborny 379ef3a009297c50876980f21060aee61e8b516a990Carolyn Wyborny/** 380ef3a009297c50876980f21060aee61e8b516a990Carolyn Wyborny * igb_read_invm_i210 - Read invm wrapper function for I210/I211 381f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * @hw: pointer to the HW structure 3825c17a203721d72c36798e5d7fa564e1adf8beb65Akeem G. Abodunrin * @words: number of words to read 383f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * @data: pointer to the data read 384f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * 385f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * Wrapper function to return data formerly found in the NVM. 386f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny **/ 387ef3a009297c50876980f21060aee61e8b516a990Carolyn Wybornystatic s32 igb_read_invm_i210(struct e1000_hw *hw, u16 offset, 388ef3a009297c50876980f21060aee61e8b516a990Carolyn Wyborny u16 words __always_unused, u16 *data) 389f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny{ 390f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny s32 ret_val = E1000_SUCCESS; 391f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny 392f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny /* Only the MAC addr is required to be present in the iNVM */ 393f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny switch (offset) { 394f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny case NVM_MAC_ADDR: 395ef3a009297c50876980f21060aee61e8b516a990Carolyn Wyborny ret_val = igb_read_invm_word_i210(hw, (u8)offset, &data[0]); 396ef3a009297c50876980f21060aee61e8b516a990Carolyn Wyborny ret_val |= igb_read_invm_word_i210(hw, (u8)offset+1, 397ef3a009297c50876980f21060aee61e8b516a990Carolyn Wyborny &data[1]); 398ef3a009297c50876980f21060aee61e8b516a990Carolyn Wyborny ret_val |= igb_read_invm_word_i210(hw, (u8)offset+2, 399ef3a009297c50876980f21060aee61e8b516a990Carolyn Wyborny &data[2]); 400f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny if (ret_val != E1000_SUCCESS) 401f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny hw_dbg("MAC Addr not found in iNVM\n"); 402f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny break; 403f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny case NVM_INIT_CTRL_2: 404ef3a009297c50876980f21060aee61e8b516a990Carolyn Wyborny ret_val = igb_read_invm_word_i210(hw, (u8)offset, data); 4051720ee3e4054eff175743820ceba16ecfe97943aCarolyn Wyborny if (ret_val != E1000_SUCCESS) { 4061720ee3e4054eff175743820ceba16ecfe97943aCarolyn Wyborny *data = NVM_INIT_CTRL_2_DEFAULT_I211; 4071720ee3e4054eff175743820ceba16ecfe97943aCarolyn Wyborny ret_val = E1000_SUCCESS; 4081720ee3e4054eff175743820ceba16ecfe97943aCarolyn Wyborny } 4091720ee3e4054eff175743820ceba16ecfe97943aCarolyn Wyborny break; 410f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny case NVM_INIT_CTRL_4: 411ef3a009297c50876980f21060aee61e8b516a990Carolyn Wyborny ret_val = igb_read_invm_word_i210(hw, (u8)offset, data); 4121720ee3e4054eff175743820ceba16ecfe97943aCarolyn Wyborny if (ret_val != E1000_SUCCESS) { 4131720ee3e4054eff175743820ceba16ecfe97943aCarolyn Wyborny *data = NVM_INIT_CTRL_4_DEFAULT_I211; 4141720ee3e4054eff175743820ceba16ecfe97943aCarolyn Wyborny ret_val = E1000_SUCCESS; 4151720ee3e4054eff175743820ceba16ecfe97943aCarolyn Wyborny } 4161720ee3e4054eff175743820ceba16ecfe97943aCarolyn Wyborny break; 417f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny case NVM_LED_1_CFG: 418ef3a009297c50876980f21060aee61e8b516a990Carolyn Wyborny ret_val = igb_read_invm_word_i210(hw, (u8)offset, data); 4191720ee3e4054eff175743820ceba16ecfe97943aCarolyn Wyborny if (ret_val != E1000_SUCCESS) { 4201720ee3e4054eff175743820ceba16ecfe97943aCarolyn Wyborny *data = NVM_LED_1_CFG_DEFAULT_I211; 4211720ee3e4054eff175743820ceba16ecfe97943aCarolyn Wyborny ret_val = E1000_SUCCESS; 4221720ee3e4054eff175743820ceba16ecfe97943aCarolyn Wyborny } 4231720ee3e4054eff175743820ceba16ecfe97943aCarolyn Wyborny break; 424f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny case NVM_LED_0_2_CFG: 425ef3a009297c50876980f21060aee61e8b516a990Carolyn Wyborny ret_val = igb_read_invm_word_i210(hw, (u8)offset, data); 4261720ee3e4054eff175743820ceba16ecfe97943aCarolyn Wyborny if (ret_val != E1000_SUCCESS) { 4271720ee3e4054eff175743820ceba16ecfe97943aCarolyn Wyborny *data = NVM_LED_0_2_CFG_DEFAULT_I211; 4281720ee3e4054eff175743820ceba16ecfe97943aCarolyn Wyborny ret_val = E1000_SUCCESS; 4291720ee3e4054eff175743820ceba16ecfe97943aCarolyn Wyborny } 430f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny break; 4311720ee3e4054eff175743820ceba16ecfe97943aCarolyn Wyborny case NVM_ID_LED_SETTINGS: 432ef3a009297c50876980f21060aee61e8b516a990Carolyn Wyborny ret_val = igb_read_invm_word_i210(hw, (u8)offset, data); 4331720ee3e4054eff175743820ceba16ecfe97943aCarolyn Wyborny if (ret_val != E1000_SUCCESS) { 4341720ee3e4054eff175743820ceba16ecfe97943aCarolyn Wyborny *data = ID_LED_RESERVED_FFFF; 4351720ee3e4054eff175743820ceba16ecfe97943aCarolyn Wyborny ret_val = E1000_SUCCESS; 4361720ee3e4054eff175743820ceba16ecfe97943aCarolyn Wyborny } 437f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny case NVM_SUB_DEV_ID: 438f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny *data = hw->subsystem_device_id; 439f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny break; 440f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny case NVM_SUB_VEN_ID: 441f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny *data = hw->subsystem_vendor_id; 442f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny break; 443f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny case NVM_DEV_ID: 444f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny *data = hw->device_id; 445f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny break; 446f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny case NVM_VEN_ID: 447f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny *data = hw->vendor_id; 448f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny break; 449f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny default: 450f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny hw_dbg("NVM word 0x%02x is not mapped.\n", offset); 451f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny *data = NVM_RESERVED_WORD; 452f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny break; 453f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny } 454f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny return ret_val; 455f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny} 456f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny 457f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny/** 45809e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny * igb_read_invm_version - Reads iNVM version and image type 45909e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny * @hw: pointer to the HW structure 46009e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny * @invm_ver: version structure for the version read 46109e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny * 46209e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny * Reads iNVM version and image type. 46309e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny **/ 46409e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wybornys32 igb_read_invm_version(struct e1000_hw *hw, 46509e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny struct e1000_fw_version *invm_ver) { 46609e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny u32 *record = NULL; 46709e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny u32 *next_record = NULL; 46809e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny u32 i = 0; 46909e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny u32 invm_dword = 0; 47009e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny u32 invm_blocks = E1000_INVM_SIZE - (E1000_INVM_ULT_BYTES_SIZE / 47109e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny E1000_INVM_RECORD_SIZE_IN_BYTES); 47209e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny u32 buffer[E1000_INVM_SIZE]; 47309e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny s32 status = -E1000_ERR_INVM_VALUE_NOT_FOUND; 47409e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny u16 version = 0; 47509e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny 47609e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny /* Read iNVM memory */ 47709e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny for (i = 0; i < E1000_INVM_SIZE; i++) { 47809e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny invm_dword = rd32(E1000_INVM_DATA_REG(i)); 47909e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny buffer[i] = invm_dword; 48009e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny } 48109e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny 48209e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny /* Read version number */ 48309e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny for (i = 1; i < invm_blocks; i++) { 48409e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny record = &buffer[invm_blocks - i]; 48509e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny next_record = &buffer[invm_blocks - i + 1]; 48609e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny 48709e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny /* Check if we have first version location used */ 48809e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny if ((i == 1) && ((*record & E1000_INVM_VER_FIELD_ONE) == 0)) { 48909e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny version = 0; 49009e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny status = E1000_SUCCESS; 49109e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny break; 49209e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny } 49309e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny /* Check if we have second version location used */ 49409e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny else if ((i == 1) && 49509e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny ((*record & E1000_INVM_VER_FIELD_TWO) == 0)) { 49609e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny version = (*record & E1000_INVM_VER_FIELD_ONE) >> 3; 49709e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny status = E1000_SUCCESS; 49809e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny break; 49909e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny } 50009e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny /* Check if we have odd version location 50109e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny * used and it is the last one used 50209e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny */ 50309e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny else if ((((*record & E1000_INVM_VER_FIELD_ONE) == 0) && 50409e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny ((*record & 0x3) == 0)) || (((*record & 0x3) != 0) && 50509e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny (i != 1))) { 50609e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny version = (*next_record & E1000_INVM_VER_FIELD_TWO) 50709e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny >> 13; 50809e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny status = E1000_SUCCESS; 50909e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny break; 51009e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny } 51109e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny /* Check if we have even version location 51209e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny * used and it is the last one used 51309e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny */ 51409e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny else if (((*record & E1000_INVM_VER_FIELD_TWO) == 0) && 51509e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny ((*record & 0x3) == 0)) { 51609e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny version = (*record & E1000_INVM_VER_FIELD_ONE) >> 3; 51709e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny status = E1000_SUCCESS; 51809e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny break; 51909e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny } 52009e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny } 52109e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny 52209e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny if (status == E1000_SUCCESS) { 52309e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny invm_ver->invm_major = (version & E1000_INVM_MAJOR_MASK) 52409e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny >> E1000_INVM_MAJOR_SHIFT; 52509e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny invm_ver->invm_minor = version & E1000_INVM_MINOR_MASK; 52609e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny } 52709e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny /* Read Image Type */ 52809e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny for (i = 1; i < invm_blocks; i++) { 52909e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny record = &buffer[invm_blocks - i]; 53009e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny next_record = &buffer[invm_blocks - i + 1]; 53109e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny 53209e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny /* Check if we have image type in first location used */ 53309e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny if ((i == 1) && ((*record & E1000_INVM_IMGTYPE_FIELD) == 0)) { 53409e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny invm_ver->invm_img_type = 0; 53509e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny status = E1000_SUCCESS; 53609e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny break; 53709e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny } 53809e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny /* Check if we have image type in first location used */ 53909e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny else if ((((*record & 0x3) == 0) && 54009e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny ((*record & E1000_INVM_IMGTYPE_FIELD) == 0)) || 54109e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny ((((*record & 0x3) != 0) && (i != 1)))) { 54209e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny invm_ver->invm_img_type = 54309e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny (*next_record & E1000_INVM_IMGTYPE_FIELD) >> 23; 54409e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny status = E1000_SUCCESS; 54509e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny break; 54609e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny } 54709e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny } 54809e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny return status; 54909e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny} 55009e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny 55109e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny/** 552f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * igb_validate_nvm_checksum_i210 - Validate EEPROM checksum 553f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * @hw: pointer to the HW structure 554f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * 555f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * Calculates the EEPROM checksum by reading/adding each word of the EEPROM 556f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * and then verifies that the sum of the EEPROM is equal to 0xBABA. 557f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny **/ 558f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wybornys32 igb_validate_nvm_checksum_i210(struct e1000_hw *hw) 559f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny{ 560f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny s32 status = E1000_SUCCESS; 561f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny s32 (*read_op_ptr)(struct e1000_hw *, u16, u16, u16 *); 562f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny 563f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny if (hw->nvm.ops.acquire(hw) == E1000_SUCCESS) { 564f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny 565b980ac18c95f3251038da7a3826370aff05a7434Jeff Kirsher /* Replace the read function with semaphore grabbing with 566f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * the one that skips this for a while. 567f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * We have semaphore taken already here. 568f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny */ 569f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny read_op_ptr = hw->nvm.ops.read; 570f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny hw->nvm.ops.read = igb_read_nvm_eerd; 571f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny 572f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny status = igb_validate_nvm_checksum(hw); 573f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny 574f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny /* Revert original read operation. */ 575f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny hw->nvm.ops.read = read_op_ptr; 576f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny 577f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny hw->nvm.ops.release(hw); 578f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny } else { 579f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny status = E1000_ERR_SWFW_SYNC; 580f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny } 581f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny 582f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny return status; 583f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny} 584f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny 585f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny/** 586f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * igb_update_nvm_checksum_i210 - Update EEPROM checksum 587f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * @hw: pointer to the HW structure 588f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * 589f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * Updates the EEPROM checksum by reading/adding each word of the EEPROM 590f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * up to the checksum. Then calculates the EEPROM checksum and writes the 591f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * value to the EEPROM. Next commit EEPROM data onto the Flash. 592f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny **/ 593f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wybornys32 igb_update_nvm_checksum_i210(struct e1000_hw *hw) 594f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny{ 595f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny s32 ret_val = E1000_SUCCESS; 596f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny u16 checksum = 0; 597f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny u16 i, nvm_data; 598f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny 599b980ac18c95f3251038da7a3826370aff05a7434Jeff Kirsher /* Read the first word from the EEPROM. If this times out or fails, do 600f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * not continue or we could be in for a very long wait while every 601f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * EEPROM read fails 602f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny */ 603f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny ret_val = igb_read_nvm_eerd(hw, 0, 1, &nvm_data); 604f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny if (ret_val != E1000_SUCCESS) { 605f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny hw_dbg("EEPROM read failed\n"); 606f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny goto out; 607f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny } 608f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny 609f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny if (hw->nvm.ops.acquire(hw) == E1000_SUCCESS) { 610b980ac18c95f3251038da7a3826370aff05a7434Jeff Kirsher /* Do not use hw->nvm.ops.write, hw->nvm.ops.read 611f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * because we do not want to take the synchronization 612f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * semaphores twice here. 613f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny */ 614f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny 615f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny for (i = 0; i < NVM_CHECKSUM_REG; i++) { 616f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny ret_val = igb_read_nvm_eerd(hw, i, 1, &nvm_data); 617f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny if (ret_val) { 618f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny hw->nvm.ops.release(hw); 619f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny hw_dbg("NVM Read Error while updating checksum.\n"); 620f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny goto out; 621f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny } 622f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny checksum += nvm_data; 623f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny } 624f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny checksum = (u16) NVM_SUM - checksum; 625f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny ret_val = igb_write_nvm_srwr(hw, NVM_CHECKSUM_REG, 1, 626f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny &checksum); 627f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny if (ret_val != E1000_SUCCESS) { 628f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny hw->nvm.ops.release(hw); 629f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny hw_dbg("NVM Write Error while updating checksum.\n"); 630f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny goto out; 631f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny } 632f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny 633f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny hw->nvm.ops.release(hw); 634f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny 635f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny ret_val = igb_update_flash_i210(hw); 636f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny } else { 637f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny ret_val = -E1000_ERR_SWFW_SYNC; 638f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny } 639f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wybornyout: 640f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny return ret_val; 641f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny} 642f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny 643f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny/** 6447916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny * igb_pool_flash_update_done_i210 - Pool FLUDONE status. 6457916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny * @hw: pointer to the HW structure 6467916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny * 647b980ac18c95f3251038da7a3826370aff05a7434Jeff Kirsher **/ 6487916a53d203f12461095886cf72d58e9281240d9Carolyn Wybornystatic s32 igb_pool_flash_update_done_i210(struct e1000_hw *hw) 6497916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny{ 6507916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny s32 ret_val = -E1000_ERR_NVM; 6517916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny u32 i, reg; 6527916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny 6537916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny for (i = 0; i < E1000_FLUDONE_ATTEMPTS; i++) { 6547916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny reg = rd32(E1000_EECD); 6557916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny if (reg & E1000_EECD_FLUDONE_I210) { 6567916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny ret_val = E1000_SUCCESS; 6577916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny break; 6587916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny } 6597916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny udelay(5); 6607916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny } 6617916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny 6627916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny return ret_val; 6637916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny} 6647916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny 6657916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny/** 6665a823d8cdd0e16081bc09a03fa253b9750c4b034Carolyn Wyborny * igb_get_flash_presence_i210 - Check if flash device is detected. 6675a823d8cdd0e16081bc09a03fa253b9750c4b034Carolyn Wyborny * @hw: pointer to the HW structure 6685a823d8cdd0e16081bc09a03fa253b9750c4b034Carolyn Wyborny * 6695a823d8cdd0e16081bc09a03fa253b9750c4b034Carolyn Wyborny **/ 6705a823d8cdd0e16081bc09a03fa253b9750c4b034Carolyn Wybornybool igb_get_flash_presence_i210(struct e1000_hw *hw) 6715a823d8cdd0e16081bc09a03fa253b9750c4b034Carolyn Wyborny{ 6725a823d8cdd0e16081bc09a03fa253b9750c4b034Carolyn Wyborny u32 eec = 0; 6735a823d8cdd0e16081bc09a03fa253b9750c4b034Carolyn Wyborny bool ret_val = false; 6745a823d8cdd0e16081bc09a03fa253b9750c4b034Carolyn Wyborny 6755a823d8cdd0e16081bc09a03fa253b9750c4b034Carolyn Wyborny eec = rd32(E1000_EECD); 6765a823d8cdd0e16081bc09a03fa253b9750c4b034Carolyn Wyborny if (eec & E1000_EECD_FLASH_DETECTED_I210) 6775a823d8cdd0e16081bc09a03fa253b9750c4b034Carolyn Wyborny ret_val = true; 6785a823d8cdd0e16081bc09a03fa253b9750c4b034Carolyn Wyborny 6795a823d8cdd0e16081bc09a03fa253b9750c4b034Carolyn Wyborny return ret_val; 6805a823d8cdd0e16081bc09a03fa253b9750c4b034Carolyn Wyborny} 6815a823d8cdd0e16081bc09a03fa253b9750c4b034Carolyn Wyborny 6825a823d8cdd0e16081bc09a03fa253b9750c4b034Carolyn Wyborny/** 683f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * igb_update_flash_i210 - Commit EEPROM to the flash 684f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * @hw: pointer to the HW structure 685f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * 686f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny **/ 687f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wybornys32 igb_update_flash_i210(struct e1000_hw *hw) 688f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny{ 689f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny s32 ret_val = E1000_SUCCESS; 690f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny u32 flup; 691f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny 692f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny ret_val = igb_pool_flash_update_done_i210(hw); 693f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny if (ret_val == -E1000_ERR_NVM) { 694f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny hw_dbg("Flash update time out\n"); 695f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny goto out; 696f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny } 697f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny 698f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny flup = rd32(E1000_EECD) | E1000_EECD_FLUPD_I210; 699f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny wr32(E1000_EECD, flup); 700f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny 701f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny ret_val = igb_pool_flash_update_done_i210(hw); 702f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny if (ret_val == E1000_SUCCESS) 703f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny hw_dbg("Flash update complete\n"); 704f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny else 705f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny hw_dbg("Flash update time out\n"); 706f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny 707f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wybornyout: 708f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny return ret_val; 709f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny} 710f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny 711f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny/** 712f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * igb_valid_led_default_i210 - Verify a valid default LED config 713f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * @hw: pointer to the HW structure 714f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * @data: pointer to the NVM (EEPROM) 715f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * 716f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * Read the EEPROM for the current default LED configuration. If the 717f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * LED configuration is not valid, set to a valid LED configuration. 718f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny **/ 719f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wybornys32 igb_valid_led_default_i210(struct e1000_hw *hw, u16 *data) 720f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny{ 721f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny s32 ret_val; 722f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny 723f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny ret_val = hw->nvm.ops.read(hw, NVM_ID_LED_SETTINGS, 1, data); 724f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny if (ret_val) { 725f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny hw_dbg("NVM Read Error\n"); 726f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny goto out; 727f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny } 728f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny 729f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny if (*data == ID_LED_RESERVED_0000 || *data == ID_LED_RESERVED_FFFF) { 730f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny switch (hw->phy.media_type) { 731f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny case e1000_media_type_internal_serdes: 732f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny *data = ID_LED_DEFAULT_I210_SERDES; 733f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny break; 734f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny case e1000_media_type_copper: 735f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny default: 736f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny *data = ID_LED_DEFAULT_I210; 737f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny break; 738f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny } 739f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny } 740f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wybornyout: 741f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny return ret_val; 742f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny} 74387371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vick 74487371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vick/** 74587371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vick * __igb_access_xmdio_reg - Read/write XMDIO register 74687371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vick * @hw: pointer to the HW structure 74787371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vick * @address: XMDIO address to program 74887371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vick * @dev_addr: device address to program 74987371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vick * @data: pointer to value to read/write from/to the XMDIO address 75087371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vick * @read: boolean flag to indicate read or write 75187371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vick **/ 75287371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vickstatic s32 __igb_access_xmdio_reg(struct e1000_hw *hw, u16 address, 75387371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vick u8 dev_addr, u16 *data, bool read) 75487371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vick{ 75587371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vick s32 ret_val = E1000_SUCCESS; 75687371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vick 75787371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vick ret_val = hw->phy.ops.write_reg(hw, E1000_MMDAC, dev_addr); 75887371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vick if (ret_val) 75987371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vick return ret_val; 76087371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vick 76187371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vick ret_val = hw->phy.ops.write_reg(hw, E1000_MMDAAD, address); 76287371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vick if (ret_val) 76387371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vick return ret_val; 76487371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vick 76587371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vick ret_val = hw->phy.ops.write_reg(hw, E1000_MMDAC, E1000_MMDAC_FUNC_DATA | 76687371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vick dev_addr); 76787371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vick if (ret_val) 76887371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vick return ret_val; 76987371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vick 77087371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vick if (read) 77187371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vick ret_val = hw->phy.ops.read_reg(hw, E1000_MMDAAD, data); 77287371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vick else 77387371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vick ret_val = hw->phy.ops.write_reg(hw, E1000_MMDAAD, *data); 77487371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vick if (ret_val) 77587371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vick return ret_val; 77687371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vick 77787371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vick /* Recalibrate the device back to 0 */ 77887371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vick ret_val = hw->phy.ops.write_reg(hw, E1000_MMDAC, 0); 77987371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vick if (ret_val) 78087371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vick return ret_val; 78187371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vick 78287371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vick return ret_val; 78387371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vick} 78487371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vick 78587371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vick/** 78687371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vick * igb_read_xmdio_reg - Read XMDIO register 78787371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vick * @hw: pointer to the HW structure 78887371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vick * @addr: XMDIO address to program 78987371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vick * @dev_addr: device address to program 79087371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vick * @data: value to be read from the EMI address 79187371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vick **/ 79287371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vicks32 igb_read_xmdio_reg(struct e1000_hw *hw, u16 addr, u8 dev_addr, u16 *data) 79387371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vick{ 79487371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vick return __igb_access_xmdio_reg(hw, addr, dev_addr, data, true); 79587371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vick} 79687371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vick 79787371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vick/** 79887371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vick * igb_write_xmdio_reg - Write XMDIO register 79987371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vick * @hw: pointer to the HW structure 80087371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vick * @addr: XMDIO address to program 80187371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vick * @dev_addr: device address to program 80287371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vick * @data: value to be written to the XMDIO address 80387371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vick **/ 80487371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vicks32 igb_write_xmdio_reg(struct e1000_hw *hw, u16 addr, u8 dev_addr, u16 data) 80587371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vick{ 80687371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vick return __igb_access_xmdio_reg(hw, addr, dev_addr, &data, false); 80787371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vick} 8085a823d8cdd0e16081bc09a03fa253b9750c4b034Carolyn Wyborny 8095a823d8cdd0e16081bc09a03fa253b9750c4b034Carolyn Wyborny/** 8105a823d8cdd0e16081bc09a03fa253b9750c4b034Carolyn Wyborny * igb_init_nvm_params_i210 - Init NVM func ptrs. 8115a823d8cdd0e16081bc09a03fa253b9750c4b034Carolyn Wyborny * @hw: pointer to the HW structure 8125a823d8cdd0e16081bc09a03fa253b9750c4b034Carolyn Wyborny **/ 8135a823d8cdd0e16081bc09a03fa253b9750c4b034Carolyn Wybornys32 igb_init_nvm_params_i210(struct e1000_hw *hw) 8145a823d8cdd0e16081bc09a03fa253b9750c4b034Carolyn Wyborny{ 8155a823d8cdd0e16081bc09a03fa253b9750c4b034Carolyn Wyborny s32 ret_val = 0; 8165a823d8cdd0e16081bc09a03fa253b9750c4b034Carolyn Wyborny struct e1000_nvm_info *nvm = &hw->nvm; 8175a823d8cdd0e16081bc09a03fa253b9750c4b034Carolyn Wyborny 8185a823d8cdd0e16081bc09a03fa253b9750c4b034Carolyn Wyborny nvm->ops.acquire = igb_acquire_nvm_i210; 8195a823d8cdd0e16081bc09a03fa253b9750c4b034Carolyn Wyborny nvm->ops.release = igb_release_nvm_i210; 8205a823d8cdd0e16081bc09a03fa253b9750c4b034Carolyn Wyborny nvm->ops.valid_led_default = igb_valid_led_default_i210; 8215a823d8cdd0e16081bc09a03fa253b9750c4b034Carolyn Wyborny 8225a823d8cdd0e16081bc09a03fa253b9750c4b034Carolyn Wyborny /* NVM Function Pointers */ 8235a823d8cdd0e16081bc09a03fa253b9750c4b034Carolyn Wyborny if (igb_get_flash_presence_i210(hw)) { 8245a823d8cdd0e16081bc09a03fa253b9750c4b034Carolyn Wyborny hw->nvm.type = e1000_nvm_flash_hw; 8255a823d8cdd0e16081bc09a03fa253b9750c4b034Carolyn Wyborny nvm->ops.read = igb_read_nvm_srrd_i210; 8265a823d8cdd0e16081bc09a03fa253b9750c4b034Carolyn Wyborny nvm->ops.write = igb_write_nvm_srwr_i210; 8275a823d8cdd0e16081bc09a03fa253b9750c4b034Carolyn Wyborny nvm->ops.validate = igb_validate_nvm_checksum_i210; 8285a823d8cdd0e16081bc09a03fa253b9750c4b034Carolyn Wyborny nvm->ops.update = igb_update_nvm_checksum_i210; 8295a823d8cdd0e16081bc09a03fa253b9750c4b034Carolyn Wyborny } else { 8305a823d8cdd0e16081bc09a03fa253b9750c4b034Carolyn Wyborny hw->nvm.type = e1000_nvm_invm; 831ef3a009297c50876980f21060aee61e8b516a990Carolyn Wyborny nvm->ops.read = igb_read_invm_i210; 8325a823d8cdd0e16081bc09a03fa253b9750c4b034Carolyn Wyborny nvm->ops.write = NULL; 8335a823d8cdd0e16081bc09a03fa253b9750c4b034Carolyn Wyborny nvm->ops.validate = NULL; 8345a823d8cdd0e16081bc09a03fa253b9750c4b034Carolyn Wyborny nvm->ops.update = NULL; 8355a823d8cdd0e16081bc09a03fa253b9750c4b034Carolyn Wyborny } 8365a823d8cdd0e16081bc09a03fa253b9750c4b034Carolyn Wyborny return ret_val; 8375a823d8cdd0e16081bc09a03fa253b9750c4b034Carolyn Wyborny} 838