e1000_i210.c revision 7916a53d203f12461095886cf72d58e9281240d9
1f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny/******************************************************************************* 2f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny 3f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny Intel(R) Gigabit Ethernet Linux driver 4f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny Copyright(c) 2007-2012 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 ret_val = E1000_SUCCESS; 487916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny s32 timeout = hw->nvm.word_size + 1; 497916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny s32 i = 0; 507916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny 517916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny /* Get the FW semaphore. */ 527916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny for (i = 0; i < timeout; i++) { 537916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny swsm = rd32(E1000_SWSM); 547916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny wr32(E1000_SWSM, swsm | E1000_SWSM_SWESMBI); 557916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny 567916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny /* Semaphore acquired if bit latched */ 577916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny if (rd32(E1000_SWSM) & E1000_SWSM_SWESMBI) 587916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny break; 597916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny 607916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny udelay(50); 617916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny } 627916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny 637916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny if (i == timeout) { 647916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny /* Release semaphores */ 657916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny igb_put_hw_semaphore(hw); 667916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny hw_dbg("Driver can't access the NVM\n"); 677916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny ret_val = -E1000_ERR_NVM; 687916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny goto out; 697916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny } 707916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny 717916a53d203f12461095886cf72d58e9281240d9Carolyn Wybornyout: 727916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny return ret_val; 737916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny} 74f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny 75f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny/** 76f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * igb_acquire_nvm_i210 - Request for access to EEPROM 77f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * @hw: pointer to the HW structure 78f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * 79f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * Acquire the necessary semaphores for exclusive access to the EEPROM. 80f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * Set the EEPROM access request bit and wait for EEPROM access grant bit. 81f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * Return successful if access grant bit set, else clear the request for 82f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * EEPROM access and return -E1000_ERR_NVM (-1). 83f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny **/ 84f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wybornys32 igb_acquire_nvm_i210(struct e1000_hw *hw) 85f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny{ 86f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny return igb_acquire_swfw_sync_i210(hw, E1000_SWFW_EEP_SM); 87f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny} 88f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny 89f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny/** 90f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * igb_release_nvm_i210 - Release exclusive access to EEPROM 91f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * @hw: pointer to the HW structure 92f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * 93f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * Stop any current commands to the EEPROM and clear the EEPROM request bit, 94f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * then release the semaphores acquired. 95f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny **/ 96f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wybornyvoid igb_release_nvm_i210(struct e1000_hw *hw) 97f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny{ 98f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny igb_release_swfw_sync_i210(hw, E1000_SWFW_EEP_SM); 99f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny} 100f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny 101f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny/** 1027916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny * igb_put_hw_semaphore_i210 - Release hardware semaphore 1037916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny * @hw: pointer to the HW structure 1047916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny * 1057916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny * Release hardware semaphore used to access the PHY or NVM 1067916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny */ 1077916a53d203f12461095886cf72d58e9281240d9Carolyn Wybornystatic void igb_put_hw_semaphore_i210(struct e1000_hw *hw) 1087916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny{ 1097916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny u32 swsm; 1107916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny 1117916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny swsm = rd32(E1000_SWSM); 1127916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny 1137916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny swsm &= ~E1000_SWSM_SWESMBI; 1147916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny 1157916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny wr32(E1000_SWSM, swsm); 1167916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny} 1177916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny 1187916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny/** 119f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * igb_acquire_swfw_sync_i210 - Acquire SW/FW semaphore 120f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * @hw: pointer to the HW structure 121f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * @mask: specifies which semaphore to acquire 122f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * 123f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * Acquire the SW/FW semaphore to access the PHY or NVM. The mask 124f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * will also specify which port we're acquiring the lock for. 125f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny **/ 126f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wybornys32 igb_acquire_swfw_sync_i210(struct e1000_hw *hw, u16 mask) 127f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny{ 128f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny u32 swfw_sync; 129f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny u32 swmask = mask; 130f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny u32 fwmask = mask << 16; 131f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny s32 ret_val = E1000_SUCCESS; 132f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny s32 i = 0, timeout = 200; /* FIXME: find real value to use here */ 133f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny 134f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny while (i < timeout) { 135f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny if (igb_get_hw_semaphore_i210(hw)) { 136f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny ret_val = -E1000_ERR_SWFW_SYNC; 137f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny goto out; 138f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny } 139f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny 140f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny swfw_sync = rd32(E1000_SW_FW_SYNC); 141f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny if (!(swfw_sync & fwmask)) 142f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny break; 143f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny 144f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny /* 145f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * Firmware currently using resource (fwmask) 146f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny */ 147f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny igb_put_hw_semaphore_i210(hw); 148f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny mdelay(5); 149f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny i++; 150f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny } 151f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny 152f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny if (i == timeout) { 153f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny hw_dbg("Driver can't access resource, SW_FW_SYNC timeout.\n"); 154f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny ret_val = -E1000_ERR_SWFW_SYNC; 155f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny goto out; 156f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny } 157f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny 158f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny swfw_sync |= swmask; 159f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny wr32(E1000_SW_FW_SYNC, swfw_sync); 160f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny 161f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny igb_put_hw_semaphore_i210(hw); 162f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wybornyout: 163f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny return ret_val; 164f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny} 165f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny 166f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny/** 167f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * igb_release_swfw_sync_i210 - Release SW/FW semaphore 168f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * @hw: pointer to the HW structure 169f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * @mask: specifies which semaphore to acquire 170f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * 171f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * Release the SW/FW semaphore used to access the PHY or NVM. The mask 172f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * will also specify which port we're releasing the lock for. 173f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny **/ 174f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wybornyvoid igb_release_swfw_sync_i210(struct e1000_hw *hw, u16 mask) 175f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny{ 176f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny u32 swfw_sync; 177f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny 178f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny while (igb_get_hw_semaphore_i210(hw) != E1000_SUCCESS) 179f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny ; /* Empty */ 180f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny 181f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny swfw_sync = rd32(E1000_SW_FW_SYNC); 182f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny swfw_sync &= ~mask; 183f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny wr32(E1000_SW_FW_SYNC, swfw_sync); 184f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny 185f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny igb_put_hw_semaphore_i210(hw); 186f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny} 187f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny 188f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny/** 189f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * igb_read_nvm_srrd_i210 - Reads Shadow Ram using EERD register 190f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * @hw: pointer to the HW structure 191f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * @offset: offset of word in the Shadow Ram to read 192f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * @words: number of words to read 193f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * @data: word read from the Shadow Ram 194f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * 195f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * Reads a 16 bit word from the Shadow Ram using the EERD register. 196f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * Uses necessary synchronization semaphores. 197f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny **/ 198f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wybornys32 igb_read_nvm_srrd_i210(struct e1000_hw *hw, u16 offset, u16 words, 199f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny u16 *data) 200f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny{ 201f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny s32 status = E1000_SUCCESS; 202f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny u16 i, count; 203f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny 204f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny /* We cannot hold synchronization semaphores for too long, 205f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * because of forceful takeover procedure. However it is more efficient 206f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * to read in bursts than synchronizing access for each word. */ 207f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny for (i = 0; i < words; i += E1000_EERD_EEWR_MAX_COUNT) { 208f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny count = (words - i) / E1000_EERD_EEWR_MAX_COUNT > 0 ? 209f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny E1000_EERD_EEWR_MAX_COUNT : (words - i); 210f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny if (hw->nvm.ops.acquire(hw) == E1000_SUCCESS) { 211f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny status = igb_read_nvm_eerd(hw, offset, count, 212f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny data + i); 213f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny hw->nvm.ops.release(hw); 214f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny } else { 215f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny status = E1000_ERR_SWFW_SYNC; 216f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny } 217f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny 218f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny if (status != E1000_SUCCESS) 219f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny break; 220f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny } 221f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny 222f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny return status; 223f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny} 224f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny 225f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny/** 226f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * igb_write_nvm_srwr - Write to Shadow Ram using EEWR 227f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * @hw: pointer to the HW structure 228f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * @offset: offset within the Shadow Ram to be written to 229f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * @words: number of words to write 230f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * @data: 16 bit word(s) to be written to the Shadow Ram 231f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * 232f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * Writes data to Shadow Ram at offset using EEWR register. 233f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * 234f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * If igb_update_nvm_checksum is not called after this function , the 235f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * Shadow Ram will most likely contain an invalid checksum. 236f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny **/ 237f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wybornystatic s32 igb_write_nvm_srwr(struct e1000_hw *hw, u16 offset, u16 words, 238f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny u16 *data) 239f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny{ 240f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny struct e1000_nvm_info *nvm = &hw->nvm; 241f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny u32 i, k, eewr = 0; 242f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny u32 attempts = 100000; 243f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny s32 ret_val = E1000_SUCCESS; 244f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny 245f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny /* 246f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * A check for invalid values: offset too large, too many words, 247f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * too many words for the offset, and not enough words. 248f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny */ 249f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) || 250f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny (words == 0)) { 251f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny hw_dbg("nvm parameter(s) out of bounds\n"); 252f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny ret_val = -E1000_ERR_NVM; 253f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny goto out; 254f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny } 255f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny 256f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny for (i = 0; i < words; i++) { 257f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny eewr = ((offset+i) << E1000_NVM_RW_ADDR_SHIFT) | 258f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny (data[i] << E1000_NVM_RW_REG_DATA) | 259f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny E1000_NVM_RW_REG_START; 260f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny 261f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny wr32(E1000_SRWR, eewr); 262f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny 263f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny for (k = 0; k < attempts; k++) { 264f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny if (E1000_NVM_RW_REG_DONE & 265f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny rd32(E1000_SRWR)) { 266f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny ret_val = E1000_SUCCESS; 267f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny break; 268f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny } 269f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny udelay(5); 270f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny } 271f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny 272f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny if (ret_val != E1000_SUCCESS) { 273f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny hw_dbg("Shadow RAM write EEWR timed out\n"); 274f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny break; 275f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny } 276f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny } 277f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny 278f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wybornyout: 279f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny return ret_val; 280f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny} 281f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny 282f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny/** 2837916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny * igb_write_nvm_srwr_i210 - Write to Shadow RAM using EEWR 2847916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny * @hw: pointer to the HW structure 2857916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny * @offset: offset within the Shadow RAM to be written to 2867916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny * @words: number of words to write 2877916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny * @data: 16 bit word(s) to be written to the Shadow RAM 2887916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny * 2897916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny * Writes data to Shadow RAM at offset using EEWR register. 2907916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny * 2917916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny * If e1000_update_nvm_checksum is not called after this function , the 2927916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny * data will not be committed to FLASH and also Shadow RAM will most likely 2937916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny * contain an invalid checksum. 2947916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny * 2957916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny * If error code is returned, data and Shadow RAM may be inconsistent - buffer 2967916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny * partially written. 2977916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny */ 2987916a53d203f12461095886cf72d58e9281240d9Carolyn Wybornys32 igb_write_nvm_srwr_i210(struct e1000_hw *hw, u16 offset, u16 words, 2997916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny u16 *data) 3007916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny{ 3017916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny s32 status = E1000_SUCCESS; 3027916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny u16 i, count; 3037916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny 3047916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny /* We cannot hold synchronization semaphores for too long, 3057916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny * because of forceful takeover procedure. However it is more efficient 3067916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny * to write in bursts than synchronizing access for each word. 3077916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny */ 3087916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny for (i = 0; i < words; i += E1000_EERD_EEWR_MAX_COUNT) { 3097916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny count = (words - i) / E1000_EERD_EEWR_MAX_COUNT > 0 ? 3107916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny E1000_EERD_EEWR_MAX_COUNT : (words - i); 3117916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny if (hw->nvm.ops.acquire(hw) == E1000_SUCCESS) { 3127916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny status = igb_write_nvm_srwr(hw, offset, count, 3137916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny data + i); 3147916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny hw->nvm.ops.release(hw); 3157916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny } else { 3167916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny status = E1000_ERR_SWFW_SYNC; 3177916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny } 3187916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny 3197916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny if (status != E1000_SUCCESS) 3207916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny break; 3217916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny } 3227916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny 3237916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny return status; 3247916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny} 3257916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny 3267916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny/** 327f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * igb_read_nvm_i211 - Read NVM wrapper function for I211 328f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * @hw: pointer to the HW structure 329f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * @address: the word address (aka eeprom offset) to read 330f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * @data: pointer to the data read 331f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * 332f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * Wrapper function to return data formerly found in the NVM. 333f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny **/ 334f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wybornys32 igb_read_nvm_i211(struct e1000_hw *hw, u16 offset, u16 words, 335f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny u16 *data) 336f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny{ 337f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny s32 ret_val = E1000_SUCCESS; 338f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny 339f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny /* Only the MAC addr is required to be present in the iNVM */ 340f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny switch (offset) { 341f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny case NVM_MAC_ADDR: 342f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny ret_val = igb_read_invm_i211(hw, offset, &data[0]); 343f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny ret_val |= igb_read_invm_i211(hw, offset+1, &data[1]); 344f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny ret_val |= igb_read_invm_i211(hw, offset+2, &data[2]); 345f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny if (ret_val != E1000_SUCCESS) 346f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny hw_dbg("MAC Addr not found in iNVM\n"); 347f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny break; 348f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny case NVM_INIT_CTRL_2: 3491720ee3e4054eff175743820ceba16ecfe97943aCarolyn Wyborny ret_val = igb_read_invm_i211(hw, (u8)offset, data); 3501720ee3e4054eff175743820ceba16ecfe97943aCarolyn Wyborny if (ret_val != E1000_SUCCESS) { 3511720ee3e4054eff175743820ceba16ecfe97943aCarolyn Wyborny *data = NVM_INIT_CTRL_2_DEFAULT_I211; 3521720ee3e4054eff175743820ceba16ecfe97943aCarolyn Wyborny ret_val = E1000_SUCCESS; 3531720ee3e4054eff175743820ceba16ecfe97943aCarolyn Wyborny } 3541720ee3e4054eff175743820ceba16ecfe97943aCarolyn Wyborny break; 355f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny case NVM_INIT_CTRL_4: 3561720ee3e4054eff175743820ceba16ecfe97943aCarolyn Wyborny ret_val = igb_read_invm_i211(hw, (u8)offset, data); 3571720ee3e4054eff175743820ceba16ecfe97943aCarolyn Wyborny if (ret_val != E1000_SUCCESS) { 3581720ee3e4054eff175743820ceba16ecfe97943aCarolyn Wyborny *data = NVM_INIT_CTRL_4_DEFAULT_I211; 3591720ee3e4054eff175743820ceba16ecfe97943aCarolyn Wyborny ret_val = E1000_SUCCESS; 3601720ee3e4054eff175743820ceba16ecfe97943aCarolyn Wyborny } 3611720ee3e4054eff175743820ceba16ecfe97943aCarolyn Wyborny break; 362f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny case NVM_LED_1_CFG: 3631720ee3e4054eff175743820ceba16ecfe97943aCarolyn Wyborny ret_val = igb_read_invm_i211(hw, (u8)offset, data); 3641720ee3e4054eff175743820ceba16ecfe97943aCarolyn Wyborny if (ret_val != E1000_SUCCESS) { 3651720ee3e4054eff175743820ceba16ecfe97943aCarolyn Wyborny *data = NVM_LED_1_CFG_DEFAULT_I211; 3661720ee3e4054eff175743820ceba16ecfe97943aCarolyn Wyborny ret_val = E1000_SUCCESS; 3671720ee3e4054eff175743820ceba16ecfe97943aCarolyn Wyborny } 3681720ee3e4054eff175743820ceba16ecfe97943aCarolyn Wyborny break; 369f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny case NVM_LED_0_2_CFG: 370f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny igb_read_invm_i211(hw, offset, data); 3711720ee3e4054eff175743820ceba16ecfe97943aCarolyn Wyborny if (ret_val != E1000_SUCCESS) { 3721720ee3e4054eff175743820ceba16ecfe97943aCarolyn Wyborny *data = NVM_LED_0_2_CFG_DEFAULT_I211; 3731720ee3e4054eff175743820ceba16ecfe97943aCarolyn Wyborny ret_val = E1000_SUCCESS; 3741720ee3e4054eff175743820ceba16ecfe97943aCarolyn Wyborny } 375f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny break; 3761720ee3e4054eff175743820ceba16ecfe97943aCarolyn Wyborny case NVM_ID_LED_SETTINGS: 3771720ee3e4054eff175743820ceba16ecfe97943aCarolyn Wyborny ret_val = igb_read_invm_i211(hw, (u8)offset, data); 3781720ee3e4054eff175743820ceba16ecfe97943aCarolyn Wyborny if (ret_val != E1000_SUCCESS) { 3791720ee3e4054eff175743820ceba16ecfe97943aCarolyn Wyborny *data = ID_LED_RESERVED_FFFF; 3801720ee3e4054eff175743820ceba16ecfe97943aCarolyn Wyborny ret_val = E1000_SUCCESS; 3811720ee3e4054eff175743820ceba16ecfe97943aCarolyn Wyborny } 382f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny case NVM_SUB_DEV_ID: 383f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny *data = hw->subsystem_device_id; 384f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny break; 385f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny case NVM_SUB_VEN_ID: 386f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny *data = hw->subsystem_vendor_id; 387f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny break; 388f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny case NVM_DEV_ID: 389f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny *data = hw->device_id; 390f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny break; 391f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny case NVM_VEN_ID: 392f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny *data = hw->vendor_id; 393f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny break; 394f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny default: 395f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny hw_dbg("NVM word 0x%02x is not mapped.\n", offset); 396f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny *data = NVM_RESERVED_WORD; 397f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny break; 398f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny } 399f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny return ret_val; 400f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny} 401f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny 402f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny/** 403f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * igb_read_invm_i211 - Reads OTP 404f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * @hw: pointer to the HW structure 405f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * @address: the word address (aka eeprom offset) to read 406f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * @data: pointer to the data read 407f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * 408f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * Reads 16-bit words from the OTP. Return error when the word is not 409f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * stored in OTP. 410f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny **/ 411f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wybornys32 igb_read_invm_i211(struct e1000_hw *hw, u16 address, u16 *data) 412f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny{ 413f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny s32 status = -E1000_ERR_INVM_VALUE_NOT_FOUND; 414f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny u32 invm_dword; 415f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny u16 i; 416f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny u8 record_type, word_address; 417f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny 418f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny for (i = 0; i < E1000_INVM_SIZE; i++) { 419f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny invm_dword = rd32(E1000_INVM_DATA_REG(i)); 420f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny /* Get record type */ 421f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny record_type = INVM_DWORD_TO_RECORD_TYPE(invm_dword); 422f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny if (record_type == E1000_INVM_UNINITIALIZED_STRUCTURE) 423f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny break; 424f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny if (record_type == E1000_INVM_CSR_AUTOLOAD_STRUCTURE) 425f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny i += E1000_INVM_CSR_AUTOLOAD_DATA_SIZE_IN_DWORDS; 426f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny if (record_type == E1000_INVM_RSA_KEY_SHA256_STRUCTURE) 427f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny i += E1000_INVM_RSA_KEY_SHA256_DATA_SIZE_IN_DWORDS; 428f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny if (record_type == E1000_INVM_WORD_AUTOLOAD_STRUCTURE) { 429f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny word_address = INVM_DWORD_TO_WORD_ADDRESS(invm_dword); 430f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny if (word_address == (u8)address) { 431f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny *data = INVM_DWORD_TO_WORD_DATA(invm_dword); 432f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny hw_dbg("Read INVM Word 0x%02x = %x", 433f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny address, *data); 434f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny status = E1000_SUCCESS; 435f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny break; 436f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny } 437f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny } 438f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny } 439f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny if (status != E1000_SUCCESS) 440f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny hw_dbg("Requested word 0x%02x not found in OTP\n", address); 441f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny return status; 442f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny} 443f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny 444f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny/** 44509e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny * igb_read_invm_version - Reads iNVM version and image type 44609e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny * @hw: pointer to the HW structure 44709e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny * @invm_ver: version structure for the version read 44809e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny * 44909e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny * Reads iNVM version and image type. 45009e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny **/ 45109e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wybornys32 igb_read_invm_version(struct e1000_hw *hw, 45209e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny struct e1000_fw_version *invm_ver) { 45309e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny u32 *record = NULL; 45409e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny u32 *next_record = NULL; 45509e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny u32 i = 0; 45609e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny u32 invm_dword = 0; 45709e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny u32 invm_blocks = E1000_INVM_SIZE - (E1000_INVM_ULT_BYTES_SIZE / 45809e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny E1000_INVM_RECORD_SIZE_IN_BYTES); 45909e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny u32 buffer[E1000_INVM_SIZE]; 46009e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny s32 status = -E1000_ERR_INVM_VALUE_NOT_FOUND; 46109e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny u16 version = 0; 46209e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny 46309e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny /* Read iNVM memory */ 46409e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny for (i = 0; i < E1000_INVM_SIZE; i++) { 46509e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny invm_dword = rd32(E1000_INVM_DATA_REG(i)); 46609e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny buffer[i] = invm_dword; 46709e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny } 46809e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny 46909e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny /* Read version number */ 47009e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny for (i = 1; i < invm_blocks; i++) { 47109e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny record = &buffer[invm_blocks - i]; 47209e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny next_record = &buffer[invm_blocks - i + 1]; 47309e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny 47409e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny /* Check if we have first version location used */ 47509e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny if ((i == 1) && ((*record & E1000_INVM_VER_FIELD_ONE) == 0)) { 47609e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny version = 0; 47709e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny status = E1000_SUCCESS; 47809e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny break; 47909e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny } 48009e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny /* Check if we have second version location used */ 48109e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny else if ((i == 1) && 48209e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny ((*record & E1000_INVM_VER_FIELD_TWO) == 0)) { 48309e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny version = (*record & E1000_INVM_VER_FIELD_ONE) >> 3; 48409e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny status = E1000_SUCCESS; 48509e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny break; 48609e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny } 48709e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny /* Check if we have odd version location 48809e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny * used and it is the last one used 48909e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny */ 49009e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny else if ((((*record & E1000_INVM_VER_FIELD_ONE) == 0) && 49109e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny ((*record & 0x3) == 0)) || (((*record & 0x3) != 0) && 49209e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny (i != 1))) { 49309e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny version = (*next_record & E1000_INVM_VER_FIELD_TWO) 49409e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny >> 13; 49509e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny status = E1000_SUCCESS; 49609e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny break; 49709e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny } 49809e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny /* Check if we have even version location 49909e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny * used and it is the last one used 50009e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny */ 50109e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny else if (((*record & E1000_INVM_VER_FIELD_TWO) == 0) && 50209e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny ((*record & 0x3) == 0)) { 50309e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny version = (*record & E1000_INVM_VER_FIELD_ONE) >> 3; 50409e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny status = E1000_SUCCESS; 50509e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny break; 50609e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny } 50709e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny } 50809e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny 50909e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny if (status == E1000_SUCCESS) { 51009e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny invm_ver->invm_major = (version & E1000_INVM_MAJOR_MASK) 51109e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny >> E1000_INVM_MAJOR_SHIFT; 51209e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny invm_ver->invm_minor = version & E1000_INVM_MINOR_MASK; 51309e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny } 51409e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny /* Read Image Type */ 51509e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny for (i = 1; i < invm_blocks; i++) { 51609e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny record = &buffer[invm_blocks - i]; 51709e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny next_record = &buffer[invm_blocks - i + 1]; 51809e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny 51909e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny /* Check if we have image type in first location used */ 52009e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny if ((i == 1) && ((*record & E1000_INVM_IMGTYPE_FIELD) == 0)) { 52109e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny invm_ver->invm_img_type = 0; 52209e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny status = E1000_SUCCESS; 52309e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny break; 52409e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny } 52509e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny /* Check if we have image type in first location used */ 52609e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny else if ((((*record & 0x3) == 0) && 52709e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny ((*record & E1000_INVM_IMGTYPE_FIELD) == 0)) || 52809e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny ((((*record & 0x3) != 0) && (i != 1)))) { 52909e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny invm_ver->invm_img_type = 53009e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny (*next_record & E1000_INVM_IMGTYPE_FIELD) >> 23; 53109e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny status = E1000_SUCCESS; 53209e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny break; 53309e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny } 53409e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny } 53509e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny return status; 53609e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny} 53709e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny 53809e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny/** 539f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * igb_validate_nvm_checksum_i210 - Validate EEPROM checksum 540f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * @hw: pointer to the HW structure 541f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * 542f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * Calculates the EEPROM checksum by reading/adding each word of the EEPROM 543f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * and then verifies that the sum of the EEPROM is equal to 0xBABA. 544f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny **/ 545f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wybornys32 igb_validate_nvm_checksum_i210(struct e1000_hw *hw) 546f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny{ 547f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny s32 status = E1000_SUCCESS; 548f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny s32 (*read_op_ptr)(struct e1000_hw *, u16, u16, u16 *); 549f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny 550f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny if (hw->nvm.ops.acquire(hw) == E1000_SUCCESS) { 551f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny 552f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny /* 553f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * Replace the read function with semaphore grabbing with 554f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * the one that skips this for a while. 555f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * We have semaphore taken already here. 556f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny */ 557f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny read_op_ptr = hw->nvm.ops.read; 558f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny hw->nvm.ops.read = igb_read_nvm_eerd; 559f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny 560f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny status = igb_validate_nvm_checksum(hw); 561f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny 562f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny /* Revert original read operation. */ 563f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny hw->nvm.ops.read = read_op_ptr; 564f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny 565f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny hw->nvm.ops.release(hw); 566f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny } else { 567f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny status = E1000_ERR_SWFW_SYNC; 568f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny } 569f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny 570f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny return status; 571f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny} 572f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny 573f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny 574f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny/** 575f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * igb_update_nvm_checksum_i210 - Update EEPROM checksum 576f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * @hw: pointer to the HW structure 577f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * 578f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * Updates the EEPROM checksum by reading/adding each word of the EEPROM 579f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * up to the checksum. Then calculates the EEPROM checksum and writes the 580f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * value to the EEPROM. Next commit EEPROM data onto the Flash. 581f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny **/ 582f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wybornys32 igb_update_nvm_checksum_i210(struct e1000_hw *hw) 583f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny{ 584f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny s32 ret_val = E1000_SUCCESS; 585f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny u16 checksum = 0; 586f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny u16 i, nvm_data; 587f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny 588f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny /* 589f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * Read the first word from the EEPROM. If this times out or fails, do 590f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * not continue or we could be in for a very long wait while every 591f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * EEPROM read fails 592f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny */ 593f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny ret_val = igb_read_nvm_eerd(hw, 0, 1, &nvm_data); 594f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny if (ret_val != E1000_SUCCESS) { 595f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny hw_dbg("EEPROM read failed\n"); 596f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny goto out; 597f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny } 598f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny 599f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny if (hw->nvm.ops.acquire(hw) == E1000_SUCCESS) { 600f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny /* 601f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * Do not use hw->nvm.ops.write, hw->nvm.ops.read 602f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * because we do not want to take the synchronization 603f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * semaphores twice here. 604f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny */ 605f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny 606f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny for (i = 0; i < NVM_CHECKSUM_REG; i++) { 607f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny ret_val = igb_read_nvm_eerd(hw, i, 1, &nvm_data); 608f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny if (ret_val) { 609f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny hw->nvm.ops.release(hw); 610f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny hw_dbg("NVM Read Error while updating checksum.\n"); 611f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny goto out; 612f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny } 613f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny checksum += nvm_data; 614f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny } 615f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny checksum = (u16) NVM_SUM - checksum; 616f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny ret_val = igb_write_nvm_srwr(hw, NVM_CHECKSUM_REG, 1, 617f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny &checksum); 618f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny if (ret_val != E1000_SUCCESS) { 619f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny hw->nvm.ops.release(hw); 620f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny hw_dbg("NVM Write Error while updating checksum.\n"); 621f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny goto out; 622f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny } 623f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny 624f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny hw->nvm.ops.release(hw); 625f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny 626f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny ret_val = igb_update_flash_i210(hw); 627f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny } else { 628f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny ret_val = -E1000_ERR_SWFW_SYNC; 629f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny } 630f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wybornyout: 631f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny return ret_val; 632f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny} 633f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny 634f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny/** 6357916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny * igb_pool_flash_update_done_i210 - Pool FLUDONE status. 6367916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny * @hw: pointer to the HW structure 6377916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny * 6387916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny */ 6397916a53d203f12461095886cf72d58e9281240d9Carolyn Wybornystatic s32 igb_pool_flash_update_done_i210(struct e1000_hw *hw) 6407916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny{ 6417916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny s32 ret_val = -E1000_ERR_NVM; 6427916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny u32 i, reg; 6437916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny 6447916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny for (i = 0; i < E1000_FLUDONE_ATTEMPTS; i++) { 6457916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny reg = rd32(E1000_EECD); 6467916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny if (reg & E1000_EECD_FLUDONE_I210) { 6477916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny ret_val = E1000_SUCCESS; 6487916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny break; 6497916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny } 6507916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny udelay(5); 6517916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny } 6527916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny 6537916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny return ret_val; 6547916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny} 6557916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny 6567916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny/** 657f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * igb_update_flash_i210 - Commit EEPROM to the flash 658f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * @hw: pointer to the HW structure 659f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * 660f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny **/ 661f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wybornys32 igb_update_flash_i210(struct e1000_hw *hw) 662f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny{ 663f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny s32 ret_val = E1000_SUCCESS; 664f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny u32 flup; 665f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny 666f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny ret_val = igb_pool_flash_update_done_i210(hw); 667f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny if (ret_val == -E1000_ERR_NVM) { 668f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny hw_dbg("Flash update time out\n"); 669f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny goto out; 670f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny } 671f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny 672f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny flup = rd32(E1000_EECD) | E1000_EECD_FLUPD_I210; 673f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny wr32(E1000_EECD, flup); 674f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny 675f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny ret_val = igb_pool_flash_update_done_i210(hw); 676f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny if (ret_val == E1000_SUCCESS) 677f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny hw_dbg("Flash update complete\n"); 678f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny else 679f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny hw_dbg("Flash update time out\n"); 680f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny 681f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wybornyout: 682f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny return ret_val; 683f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny} 684f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny 685f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny/** 686f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * igb_valid_led_default_i210 - Verify a valid default LED config 687f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * @hw: pointer to the HW structure 688f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * @data: pointer to the NVM (EEPROM) 689f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * 690f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * Read the EEPROM for the current default LED configuration. If the 691f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * LED configuration is not valid, set to a valid LED configuration. 692f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny **/ 693f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wybornys32 igb_valid_led_default_i210(struct e1000_hw *hw, u16 *data) 694f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny{ 695f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny s32 ret_val; 696f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny 697f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny ret_val = hw->nvm.ops.read(hw, NVM_ID_LED_SETTINGS, 1, data); 698f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny if (ret_val) { 699f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny hw_dbg("NVM Read Error\n"); 700f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny goto out; 701f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny } 702f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny 703f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny if (*data == ID_LED_RESERVED_0000 || *data == ID_LED_RESERVED_FFFF) { 704f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny switch (hw->phy.media_type) { 705f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny case e1000_media_type_internal_serdes: 706f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny *data = ID_LED_DEFAULT_I210_SERDES; 707f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny break; 708f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny case e1000_media_type_copper: 709f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny default: 710f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny *data = ID_LED_DEFAULT_I210; 711f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny break; 712f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny } 713f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny } 714f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wybornyout: 715f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny return ret_val; 716f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny} 717