156a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg/******************************************************************************* 256a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg * 356a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg * Intel Ethernet Controller XL710 Family Linux Driver 4dc641b7319f19a17639ed7d36aaddbf090206644Greg Rose * Copyright(c) 2013 - 2014 Intel Corporation. 556a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg * 656a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg * This program is free software; you can redistribute it and/or modify it 756a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg * under the terms and conditions of the GNU General Public License, 856a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg * version 2, as published by the Free Software Foundation. 956a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg * 1056a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg * This program is distributed in the hope it will be useful, but WITHOUT 1156a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1256a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 1356a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg * more details. 1456a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg * 15dc641b7319f19a17639ed7d36aaddbf090206644Greg Rose * You should have received a copy of the GNU General Public License along 16dc641b7319f19a17639ed7d36aaddbf090206644Greg Rose * with this program. If not, see <http://www.gnu.org/licenses/>. 1756a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg * 1856a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg * The full GNU General Public License is included in this distribution in 1956a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg * the file called "COPYING". 2056a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg * 2156a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg * Contact Information: 2256a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg * e1000-devel Mailing List <e1000-devel@lists.sourceforge.net> 2356a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 2456a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg * 2556a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg ******************************************************************************/ 2656a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg 2756a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg#include "i40e_prototype.h" 2856a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg 2956a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg/** 303e26186d4c2f856cf60b9c22863ab0080afbdc66Shannon Nelson * i40e_init_nvm_ops - Initialize NVM function pointers 313e26186d4c2f856cf60b9c22863ab0080afbdc66Shannon Nelson * @hw: pointer to the HW structure 3256a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg * 333e26186d4c2f856cf60b9c22863ab0080afbdc66Shannon Nelson * Setup the function pointers and the NVM info structure. Should be called 343e26186d4c2f856cf60b9c22863ab0080afbdc66Shannon Nelson * once per NVM initialization, e.g. inside the i40e_init_shared_code(). 353e26186d4c2f856cf60b9c22863ab0080afbdc66Shannon Nelson * Please notice that the NVM term is used here (& in all methods covered 363e26186d4c2f856cf60b9c22863ab0080afbdc66Shannon Nelson * in this file) as an equivalent of the FLASH part mapped into the SR. 373e26186d4c2f856cf60b9c22863ab0080afbdc66Shannon Nelson * We are accessing FLASH always thru the Shadow RAM. 3856a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg **/ 3956a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburgi40e_status i40e_init_nvm(struct i40e_hw *hw) 4056a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg{ 4156a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg struct i40e_nvm_info *nvm = &hw->nvm; 4256a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg i40e_status ret_code = 0; 4356a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg u32 fla, gens; 4456a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg u8 sr_size; 4556a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg 4656a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg /* The SR size is stored regardless of the nvm programming mode 4756a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg * as the blank mode may be used in the factory line. 4856a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg */ 4956a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg gens = rd32(hw, I40E_GLNVM_GENS); 5056a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg sr_size = ((gens & I40E_GLNVM_GENS_SR_SIZE_MASK) >> 5156a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg I40E_GLNVM_GENS_SR_SIZE_SHIFT); 523e26186d4c2f856cf60b9c22863ab0080afbdc66Shannon Nelson /* Switching to words (sr_size contains power of 2KB) */ 5356a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg nvm->sr_size = (1 << sr_size) * I40E_SR_WORDS_IN_1KB; 5456a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg 553e26186d4c2f856cf60b9c22863ab0080afbdc66Shannon Nelson /* Check if we are in the normal or blank NVM programming mode */ 5656a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg fla = rd32(hw, I40E_GLNVM_FLA); 573e26186d4c2f856cf60b9c22863ab0080afbdc66Shannon Nelson if (fla & I40E_GLNVM_FLA_LOCKED_MASK) { /* Normal programming mode */ 583e26186d4c2f856cf60b9c22863ab0080afbdc66Shannon Nelson /* Max NVM timeout */ 5956a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg nvm->timeout = I40E_MAX_NVM_TIMEOUT; 6056a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg nvm->blank_nvm_mode = false; 613e26186d4c2f856cf60b9c22863ab0080afbdc66Shannon Nelson } else { /* Blank programming mode */ 6256a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg nvm->blank_nvm_mode = true; 6356a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg ret_code = I40E_ERR_NVM_BLANK_MODE; 6456a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg hw_dbg(hw, "NVM init error: unsupported blank mode.\n"); 6556a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg } 6656a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg 6756a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg return ret_code; 6856a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg} 6956a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg 7056a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg/** 713e26186d4c2f856cf60b9c22863ab0080afbdc66Shannon Nelson * i40e_acquire_nvm - Generic request for acquiring the NVM ownership 723e26186d4c2f856cf60b9c22863ab0080afbdc66Shannon Nelson * @hw: pointer to the HW structure 733e26186d4c2f856cf60b9c22863ab0080afbdc66Shannon Nelson * @access: NVM access type (read or write) 7456a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg * 753e26186d4c2f856cf60b9c22863ab0080afbdc66Shannon Nelson * This function will request NVM ownership for reading 763e26186d4c2f856cf60b9c22863ab0080afbdc66Shannon Nelson * via the proper Admin Command. 7756a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg **/ 7856a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburgi40e_status i40e_acquire_nvm(struct i40e_hw *hw, 7956a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg enum i40e_aq_resource_access_type access) 8056a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg{ 8156a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg i40e_status ret_code = 0; 8256a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg u64 gtime, timeout; 8356a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg u64 time = 0; 8456a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg 8556a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg if (hw->nvm.blank_nvm_mode) 8656a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg goto i40e_i40e_acquire_nvm_exit; 8756a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg 8856a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg ret_code = i40e_aq_request_resource(hw, I40E_NVM_RESOURCE_ID, access, 8956a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg 0, &time, NULL); 903e26186d4c2f856cf60b9c22863ab0080afbdc66Shannon Nelson /* Reading the Global Device Timer */ 9156a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg gtime = rd32(hw, I40E_GLVFGEN_TIMER); 9256a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg 933e26186d4c2f856cf60b9c22863ab0080afbdc66Shannon Nelson /* Store the timeout */ 9456a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg hw->nvm.hw_semaphore_timeout = I40E_MS_TO_GTIME(time) + gtime; 9556a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg 9656a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg if (ret_code) { 973e26186d4c2f856cf60b9c22863ab0080afbdc66Shannon Nelson /* Set the polling timeout */ 9856a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg if (time > I40E_MAX_NVM_TIMEOUT) 9956a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg timeout = I40E_MS_TO_GTIME(I40E_MAX_NVM_TIMEOUT) 10056a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg + gtime; 10156a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg else 10256a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg timeout = hw->nvm.hw_semaphore_timeout; 1033e26186d4c2f856cf60b9c22863ab0080afbdc66Shannon Nelson /* Poll until the current NVM owner timeouts */ 10456a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg while (gtime < timeout) { 10556a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg usleep_range(10000, 20000); 10656a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg ret_code = i40e_aq_request_resource(hw, 10756a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg I40E_NVM_RESOURCE_ID, 10856a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg access, 0, &time, 10956a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg NULL); 11056a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg if (!ret_code) { 11156a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg hw->nvm.hw_semaphore_timeout = 11256a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg I40E_MS_TO_GTIME(time) + gtime; 11356a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg break; 11456a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg } 11556a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg gtime = rd32(hw, I40E_GLVFGEN_TIMER); 11656a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg } 11756a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg if (ret_code) { 11856a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg hw->nvm.hw_semaphore_timeout = 0; 11956a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg hw->nvm.hw_semaphore_wait = 12056a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg I40E_MS_TO_GTIME(time) + gtime; 12156a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg hw_dbg(hw, "NVM acquire timed out, wait %llu ms before trying again.\n", 12256a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg time); 12356a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg } 12456a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg } 12556a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg 12656a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburgi40e_i40e_acquire_nvm_exit: 12756a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg return ret_code; 12856a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg} 12956a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg 13056a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg/** 1313e26186d4c2f856cf60b9c22863ab0080afbdc66Shannon Nelson * i40e_release_nvm - Generic request for releasing the NVM ownership 1323e26186d4c2f856cf60b9c22863ab0080afbdc66Shannon Nelson * @hw: pointer to the HW structure 13356a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg * 1343e26186d4c2f856cf60b9c22863ab0080afbdc66Shannon Nelson * This function will release NVM resource via the proper Admin Command. 13556a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg **/ 13656a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburgvoid i40e_release_nvm(struct i40e_hw *hw) 13756a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg{ 13856a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg if (!hw->nvm.blank_nvm_mode) 13956a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg i40e_aq_release_resource(hw, I40E_NVM_RESOURCE_ID, 0, NULL); 14056a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg} 14156a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg 14256a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg/** 1433e26186d4c2f856cf60b9c22863ab0080afbdc66Shannon Nelson * i40e_poll_sr_srctl_done_bit - Polls the GLNVM_SRCTL done bit 1443e26186d4c2f856cf60b9c22863ab0080afbdc66Shannon Nelson * @hw: pointer to the HW structure 14556a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg * 1463e26186d4c2f856cf60b9c22863ab0080afbdc66Shannon Nelson * Polls the SRCTL Shadow RAM register done bit. 14756a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg **/ 14856a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburgstatic i40e_status i40e_poll_sr_srctl_done_bit(struct i40e_hw *hw) 14956a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg{ 15056a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg i40e_status ret_code = I40E_ERR_TIMEOUT; 15156a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg u32 srctl, wait_cnt; 15256a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg 1533e26186d4c2f856cf60b9c22863ab0080afbdc66Shannon Nelson /* Poll the I40E_GLNVM_SRCTL until the done bit is set */ 15456a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg for (wait_cnt = 0; wait_cnt < I40E_SRRD_SRCTL_ATTEMPTS; wait_cnt++) { 15556a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg srctl = rd32(hw, I40E_GLNVM_SRCTL); 15656a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg if (srctl & I40E_GLNVM_SRCTL_DONE_MASK) { 15756a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg ret_code = 0; 15856a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg break; 15956a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg } 16056a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg udelay(5); 16156a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg } 16256a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg if (ret_code == I40E_ERR_TIMEOUT) 163c5ffe7e1f745984b37b8ffe03b03f3d716a072f3Jakub Kicinski hw_dbg(hw, "Done bit in GLNVM_SRCTL not set\n"); 16456a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg return ret_code; 16556a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg} 16656a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg 16756a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg/** 1683e26186d4c2f856cf60b9c22863ab0080afbdc66Shannon Nelson * i40e_read_nvm_word - Reads Shadow RAM 1693e26186d4c2f856cf60b9c22863ab0080afbdc66Shannon Nelson * @hw: pointer to the HW structure 1703e26186d4c2f856cf60b9c22863ab0080afbdc66Shannon Nelson * @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF) 1713e26186d4c2f856cf60b9c22863ab0080afbdc66Shannon Nelson * @data: word read from the Shadow RAM 17256a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg * 1733e26186d4c2f856cf60b9c22863ab0080afbdc66Shannon Nelson * Reads one 16 bit word from the Shadow RAM using the GLNVM_SRCTL register. 17456a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg **/ 175a4bcfbb7067ab04ddd4f48b8ac4da10d62a8de9aShannon Nelsoni40e_status i40e_read_nvm_word(struct i40e_hw *hw, u16 offset, 176a4bcfbb7067ab04ddd4f48b8ac4da10d62a8de9aShannon Nelson u16 *data) 17756a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg{ 17856a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg i40e_status ret_code = I40E_ERR_TIMEOUT; 17956a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg u32 sr_reg; 18056a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg 18156a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg if (offset >= hw->nvm.sr_size) { 18256a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg hw_dbg(hw, "NVM read error: Offset beyond Shadow RAM limit.\n"); 18356a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg ret_code = I40E_ERR_PARAM; 18456a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg goto read_nvm_exit; 18556a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg } 18656a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg 1873e26186d4c2f856cf60b9c22863ab0080afbdc66Shannon Nelson /* Poll the done bit first */ 18856a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg ret_code = i40e_poll_sr_srctl_done_bit(hw); 18956a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg if (!ret_code) { 1903e26186d4c2f856cf60b9c22863ab0080afbdc66Shannon Nelson /* Write the address and start reading */ 19156a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg sr_reg = (u32)(offset << I40E_GLNVM_SRCTL_ADDR_SHIFT) | 19256a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg (1 << I40E_GLNVM_SRCTL_START_SHIFT); 19356a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg wr32(hw, I40E_GLNVM_SRCTL, sr_reg); 19456a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg 1953e26186d4c2f856cf60b9c22863ab0080afbdc66Shannon Nelson /* Poll I40E_GLNVM_SRCTL until the done bit is set */ 19656a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg ret_code = i40e_poll_sr_srctl_done_bit(hw); 19756a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg if (!ret_code) { 19856a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg sr_reg = rd32(hw, I40E_GLNVM_SRDATA); 19956a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg *data = (u16)((sr_reg & 20056a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg I40E_GLNVM_SRDATA_RDDATA_MASK) 20156a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg >> I40E_GLNVM_SRDATA_RDDATA_SHIFT); 20256a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg } 20356a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg } 20456a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg if (ret_code) 20556a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg hw_dbg(hw, "NVM read error: Couldn't access Shadow RAM address: 0x%x\n", 20656a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg offset); 20756a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg 20856a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburgread_nvm_exit: 20956a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg return ret_code; 21056a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg} 21156a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg 21256a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg/** 2133e26186d4c2f856cf60b9c22863ab0080afbdc66Shannon Nelson * i40e_read_nvm_buffer - Reads Shadow RAM buffer 2143e26186d4c2f856cf60b9c22863ab0080afbdc66Shannon Nelson * @hw: pointer to the HW structure 2153e26186d4c2f856cf60b9c22863ab0080afbdc66Shannon Nelson * @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF). 2163e26186d4c2f856cf60b9c22863ab0080afbdc66Shannon Nelson * @words: (in) number of words to read; (out) number of words actually read 2173e26186d4c2f856cf60b9c22863ab0080afbdc66Shannon Nelson * @data: words read from the Shadow RAM 21856a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg * 2193e26186d4c2f856cf60b9c22863ab0080afbdc66Shannon Nelson * Reads 16 bit words (data buffer) from the SR using the i40e_read_nvm_srrd() 2203e26186d4c2f856cf60b9c22863ab0080afbdc66Shannon Nelson * method. The buffer read is preceded by the NVM ownership take 2213e26186d4c2f856cf60b9c22863ab0080afbdc66Shannon Nelson * and followed by the release. 22256a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg **/ 22356a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburgi40e_status i40e_read_nvm_buffer(struct i40e_hw *hw, u16 offset, 22456a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg u16 *words, u16 *data) 22556a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg{ 22656a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg i40e_status ret_code = 0; 22756a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg u16 index, word; 22856a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg 2293e26186d4c2f856cf60b9c22863ab0080afbdc66Shannon Nelson /* Loop thru the selected region */ 230a4bcfbb7067ab04ddd4f48b8ac4da10d62a8de9aShannon Nelson for (word = 0; word < *words; word++) { 231a4bcfbb7067ab04ddd4f48b8ac4da10d62a8de9aShannon Nelson index = offset + word; 232a4bcfbb7067ab04ddd4f48b8ac4da10d62a8de9aShannon Nelson ret_code = i40e_read_nvm_word(hw, index, &data[word]); 233a4bcfbb7067ab04ddd4f48b8ac4da10d62a8de9aShannon Nelson if (ret_code) 234a4bcfbb7067ab04ddd4f48b8ac4da10d62a8de9aShannon Nelson break; 23556a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg } 23656a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg 2373e26186d4c2f856cf60b9c22863ab0080afbdc66Shannon Nelson /* Update the number of words read from the Shadow RAM */ 238a4bcfbb7067ab04ddd4f48b8ac4da10d62a8de9aShannon Nelson *words = word; 239a4bcfbb7067ab04ddd4f48b8ac4da10d62a8de9aShannon Nelson 24056a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg return ret_code; 24156a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg} 24256a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg 24356a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg/** 244cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson * i40e_write_nvm_aq - Writes Shadow RAM. 245cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson * @hw: pointer to the HW structure. 246cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson * @module_pointer: module pointer location in words from the NVM beginning 247cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson * @offset: offset in words from module start 248cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson * @words: number of words to write 249cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson * @data: buffer with words to write to the Shadow RAM 250cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson * @last_command: tells the AdminQ that this is the last command 251cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson * 252cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson * Writes a 16 bit words buffer to the Shadow RAM using the admin command. 253cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson **/ 254952d9639dba84e2a979cf4dd8edab3542b477ba3Wei Yongjunstatic i40e_status i40e_write_nvm_aq(struct i40e_hw *hw, u8 module_pointer, 255952d9639dba84e2a979cf4dd8edab3542b477ba3Wei Yongjun u32 offset, u16 words, void *data, 256952d9639dba84e2a979cf4dd8edab3542b477ba3Wei Yongjun bool last_command) 257cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson{ 258cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson i40e_status ret_code = I40E_ERR_NVM; 259cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson 260cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson /* Here we are checking the SR limit only for the flat memory model. 261cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson * We cannot do it for the module-based model, as we did not acquire 262cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson * the NVM resource yet (we cannot get the module pointer value). 263cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson * Firmware will check the module-based model. 264cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson */ 265cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson if ((offset + words) > hw->nvm.sr_size) 266cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson hw_dbg(hw, "NVM write error: offset beyond Shadow RAM limit.\n"); 267cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson else if (words > I40E_SR_SECTOR_SIZE_IN_WORDS) 268cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson /* We can write only up to 4KB (one sector), in one AQ write */ 269cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson hw_dbg(hw, "NVM write fail error: cannot write more than 4KB in a single write.\n"); 270cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson else if (((offset + (words - 1)) / I40E_SR_SECTOR_SIZE_IN_WORDS) 271cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson != (offset / I40E_SR_SECTOR_SIZE_IN_WORDS)) 272cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson /* A single write cannot spread over two sectors */ 273cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson hw_dbg(hw, "NVM write error: cannot spread over two sectors in a single write.\n"); 274cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson else 275cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson ret_code = i40e_aq_update_nvm(hw, module_pointer, 276cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson 2 * offset, /*bytes*/ 277cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson 2 * words, /*bytes*/ 278cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson data, last_command, NULL); 279cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson 280cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson return ret_code; 281cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson} 282cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson 283cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson/** 2843e26186d4c2f856cf60b9c22863ab0080afbdc66Shannon Nelson * i40e_calc_nvm_checksum - Calculates and returns the checksum 2853e26186d4c2f856cf60b9c22863ab0080afbdc66Shannon Nelson * @hw: pointer to hardware structure 2863e26186d4c2f856cf60b9c22863ab0080afbdc66Shannon Nelson * @checksum: pointer to the checksum 28756a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg * 2883e26186d4c2f856cf60b9c22863ab0080afbdc66Shannon Nelson * This function calculates SW Checksum that covers the whole 64kB shadow RAM 2893e26186d4c2f856cf60b9c22863ab0080afbdc66Shannon Nelson * except the VPD and PCIe ALT Auto-load modules. The structure and size of VPD 2903e26186d4c2f856cf60b9c22863ab0080afbdc66Shannon Nelson * is customer specific and unknown. Therefore, this function skips all maximum 2913e26186d4c2f856cf60b9c22863ab0080afbdc66Shannon Nelson * possible size of VPD (1kB). 29256a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg **/ 29356a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburgstatic i40e_status i40e_calc_nvm_checksum(struct i40e_hw *hw, 29456a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg u16 *checksum) 29556a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg{ 29656a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg i40e_status ret_code = 0; 29756a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg u16 pcie_alt_module = 0; 29856a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg u16 checksum_local = 0; 29956a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg u16 vpd_module = 0; 30056a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg u16 word = 0; 30156a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg u32 i = 0; 30256a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg 30356a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg /* read pointer to VPD area */ 304a4bcfbb7067ab04ddd4f48b8ac4da10d62a8de9aShannon Nelson ret_code = i40e_read_nvm_word(hw, I40E_SR_VPD_PTR, &vpd_module); 30556a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg if (ret_code) { 30656a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg ret_code = I40E_ERR_NVM_CHECKSUM; 30756a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg goto i40e_calc_nvm_checksum_exit; 30856a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg } 30956a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg 31056a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg /* read pointer to PCIe Alt Auto-load module */ 311a4bcfbb7067ab04ddd4f48b8ac4da10d62a8de9aShannon Nelson ret_code = i40e_read_nvm_word(hw, I40E_SR_PCIE_ALT_AUTO_LOAD_PTR, 31256a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg &pcie_alt_module); 31356a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg if (ret_code) { 31456a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg ret_code = I40E_ERR_NVM_CHECKSUM; 31556a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg goto i40e_calc_nvm_checksum_exit; 31656a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg } 31756a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg 31856a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg /* Calculate SW checksum that covers the whole 64kB shadow RAM 31956a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg * except the VPD and PCIe ALT Auto-load modules 32056a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg */ 32156a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg for (i = 0; i < hw->nvm.sr_size; i++) { 32256a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg /* Skip Checksum word */ 32356a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg if (i == I40E_SR_SW_CHECKSUM_WORD) 32456a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg i++; 32556a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg /* Skip VPD module (convert byte size to word count) */ 32656a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg if (i == (u32)vpd_module) { 32756a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg i += (I40E_SR_VPD_MODULE_MAX_SIZE / 2); 32856a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg if (i >= hw->nvm.sr_size) 32956a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg break; 33056a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg } 33156a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg /* Skip PCIe ALT module (convert byte size to word count) */ 33256a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg if (i == (u32)pcie_alt_module) { 33356a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg i += (I40E_SR_PCIE_ALT_MODULE_MAX_SIZE / 2); 33456a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg if (i >= hw->nvm.sr_size) 33556a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg break; 33656a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg } 33756a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg 338a4bcfbb7067ab04ddd4f48b8ac4da10d62a8de9aShannon Nelson ret_code = i40e_read_nvm_word(hw, (u16)i, &word); 33956a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg if (ret_code) { 34056a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg ret_code = I40E_ERR_NVM_CHECKSUM; 34156a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg goto i40e_calc_nvm_checksum_exit; 34256a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg } 34356a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg checksum_local += word; 34456a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg } 34556a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg 34656a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg *checksum = (u16)I40E_SR_SW_CHECKSUM_BASE - checksum_local; 34756a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg 34856a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburgi40e_calc_nvm_checksum_exit: 34956a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg return ret_code; 35056a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg} 35156a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg 35256a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg/** 353cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson * i40e_update_nvm_checksum - Updates the NVM checksum 354cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson * @hw: pointer to hardware structure 355cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson * 356cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson * NVM ownership must be acquired before calling this function and released 357cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson * on ARQ completion event reception by caller. 358cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson * This function will commit SR to NVM. 359cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson **/ 360cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelsoni40e_status i40e_update_nvm_checksum(struct i40e_hw *hw) 361cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson{ 362cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson i40e_status ret_code = 0; 363cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson u16 checksum; 364cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson 365cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson ret_code = i40e_calc_nvm_checksum(hw, &checksum); 366cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson if (!ret_code) 367cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson ret_code = i40e_write_nvm_aq(hw, 0x00, I40E_SR_SW_CHECKSUM_WORD, 368cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson 1, &checksum, true); 369cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson 370cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson return ret_code; 371cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson} 372cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson 373cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson/** 3743e26186d4c2f856cf60b9c22863ab0080afbdc66Shannon Nelson * i40e_validate_nvm_checksum - Validate EEPROM checksum 3753e26186d4c2f856cf60b9c22863ab0080afbdc66Shannon Nelson * @hw: pointer to hardware structure 3763e26186d4c2f856cf60b9c22863ab0080afbdc66Shannon Nelson * @checksum: calculated checksum 37756a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg * 3783e26186d4c2f856cf60b9c22863ab0080afbdc66Shannon Nelson * Performs checksum calculation and validates the NVM SW checksum. If the 3793e26186d4c2f856cf60b9c22863ab0080afbdc66Shannon Nelson * caller does not need checksum, the value can be NULL. 38056a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg **/ 38156a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburgi40e_status i40e_validate_nvm_checksum(struct i40e_hw *hw, 38256a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg u16 *checksum) 38356a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg{ 38456a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg i40e_status ret_code = 0; 38556a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg u16 checksum_sr = 0; 386e15c9fa03639fcd30d035ea829f11b222b95e7f3Jesse Brandeburg u16 checksum_local = 0; 38756a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg 38856a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg ret_code = i40e_calc_nvm_checksum(hw, &checksum_local); 38956a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg if (ret_code) 3907a208e83fcedc0b845facc17d05ead0b9b73a967Kamil Krawczyk goto i40e_validate_nvm_checksum_exit; 39156a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg 39256a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg /* Do not use i40e_read_nvm_word() because we do not want to take 39356a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg * the synchronization semaphores twice here. 39456a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg */ 395a4bcfbb7067ab04ddd4f48b8ac4da10d62a8de9aShannon Nelson i40e_read_nvm_word(hw, I40E_SR_SW_CHECKSUM_WORD, &checksum_sr); 39656a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg 39756a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg /* Verify read checksum from EEPROM is the same as 39856a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg * calculated checksum 39956a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg */ 40056a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg if (checksum_local != checksum_sr) 40156a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg ret_code = I40E_ERR_NVM_CHECKSUM; 40256a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg 40356a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg /* If the user cares, return the calculated checksum */ 40456a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg if (checksum) 40556a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg *checksum = checksum_local; 40656a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg 40756a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburgi40e_validate_nvm_checksum_exit: 40856a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg return ret_code; 40956a62fc8689509fb86bcb20768d575b81d9c311eJesse Brandeburg} 410cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson 411cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelsonstatic i40e_status i40e_nvmupd_state_init(struct i40e_hw *hw, 412cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson struct i40e_nvm_access *cmd, 413cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson u8 *bytes, int *errno); 414cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelsonstatic i40e_status i40e_nvmupd_state_reading(struct i40e_hw *hw, 415cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson struct i40e_nvm_access *cmd, 416cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson u8 *bytes, int *errno); 417cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelsonstatic i40e_status i40e_nvmupd_state_writing(struct i40e_hw *hw, 418cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson struct i40e_nvm_access *cmd, 419cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson u8 *bytes, int *errno); 420cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelsonstatic enum i40e_nvmupd_cmd i40e_nvmupd_validate_command(struct i40e_hw *hw, 421cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson struct i40e_nvm_access *cmd, 422cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson int *errno); 423cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelsonstatic i40e_status i40e_nvmupd_nvm_erase(struct i40e_hw *hw, 424cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson struct i40e_nvm_access *cmd, 425cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson int *errno); 426cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelsonstatic i40e_status i40e_nvmupd_nvm_write(struct i40e_hw *hw, 427cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson struct i40e_nvm_access *cmd, 428cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson u8 *bytes, int *errno); 429cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelsonstatic i40e_status i40e_nvmupd_nvm_read(struct i40e_hw *hw, 430cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson struct i40e_nvm_access *cmd, 431cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson u8 *bytes, int *errno); 432cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelsonstatic inline u8 i40e_nvmupd_get_module(u32 val) 433cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson{ 434cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson return (u8)(val & I40E_NVM_MOD_PNT_MASK); 435cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson} 436cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelsonstatic inline u8 i40e_nvmupd_get_transaction(u32 val) 437cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson{ 438cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson return (u8)((val & I40E_NVM_TRANS_MASK) >> I40E_NVM_TRANS_SHIFT); 439cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson} 440cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson 441cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson/** 442cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson * i40e_nvmupd_command - Process an NVM update command 443cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson * @hw: pointer to hardware structure 444cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson * @cmd: pointer to nvm update command 445cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson * @bytes: pointer to the data buffer 446cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson * @errno: pointer to return error code 447cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson * 448cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson * Dispatches command depending on what update state is current 449cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson **/ 450cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelsoni40e_status i40e_nvmupd_command(struct i40e_hw *hw, 451cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson struct i40e_nvm_access *cmd, 452cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson u8 *bytes, int *errno) 453cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson{ 454cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson i40e_status status; 455cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson 456cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson /* assume success */ 457cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson *errno = 0; 458cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson 459cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson switch (hw->nvmupd_state) { 460cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson case I40E_NVMUPD_STATE_INIT: 461cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson status = i40e_nvmupd_state_init(hw, cmd, bytes, errno); 462cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson break; 463cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson 464cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson case I40E_NVMUPD_STATE_READING: 465cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson status = i40e_nvmupd_state_reading(hw, cmd, bytes, errno); 466cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson break; 467cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson 468cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson case I40E_NVMUPD_STATE_WRITING: 469cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson status = i40e_nvmupd_state_writing(hw, cmd, bytes, errno); 470cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson break; 471cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson 472cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson default: 473cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson /* invalid state, should never happen */ 474cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson status = I40E_NOT_SUPPORTED; 475cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson *errno = -ESRCH; 476cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson break; 477cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson } 478cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson return status; 479cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson} 480cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson 481cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson/** 482cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson * i40e_nvmupd_state_init - Handle NVM update state Init 483cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson * @hw: pointer to hardware structure 484cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson * @cmd: pointer to nvm update command buffer 485cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson * @bytes: pointer to the data buffer 486cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson * @errno: pointer to return error code 487cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson * 488cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson * Process legitimate commands of the Init state and conditionally set next 489cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson * state. Reject all other commands. 490cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson **/ 491cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelsonstatic i40e_status i40e_nvmupd_state_init(struct i40e_hw *hw, 492cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson struct i40e_nvm_access *cmd, 493cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson u8 *bytes, int *errno) 494cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson{ 495cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson i40e_status status = 0; 496cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson enum i40e_nvmupd_cmd upd_cmd; 497cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson 498cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson upd_cmd = i40e_nvmupd_validate_command(hw, cmd, errno); 499cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson 500cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson switch (upd_cmd) { 501cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson case I40E_NVMUPD_READ_SA: 502cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson status = i40e_acquire_nvm(hw, I40E_RESOURCE_READ); 503cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson if (status) { 504cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson *errno = i40e_aq_rc_to_posix(hw->aq.asq_last_status); 505cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson } else { 506cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson status = i40e_nvmupd_nvm_read(hw, cmd, bytes, errno); 507cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson i40e_release_nvm(hw); 508cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson } 509cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson break; 510cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson 511cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson case I40E_NVMUPD_READ_SNT: 512cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson status = i40e_acquire_nvm(hw, I40E_RESOURCE_READ); 513cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson if (status) { 514cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson *errno = i40e_aq_rc_to_posix(hw->aq.asq_last_status); 515cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson } else { 516cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson status = i40e_nvmupd_nvm_read(hw, cmd, bytes, errno); 517cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson hw->nvmupd_state = I40E_NVMUPD_STATE_READING; 518cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson } 519cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson break; 520cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson 521cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson case I40E_NVMUPD_WRITE_ERA: 522cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson status = i40e_acquire_nvm(hw, I40E_RESOURCE_WRITE); 523cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson if (status) { 524cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson *errno = i40e_aq_rc_to_posix(hw->aq.asq_last_status); 525cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson } else { 526cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson status = i40e_nvmupd_nvm_erase(hw, cmd, errno); 527cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson if (status) 528cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson i40e_release_nvm(hw); 529cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson else 530cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson hw->aq.nvm_release_on_done = true; 531cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson } 532cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson break; 533cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson 534cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson case I40E_NVMUPD_WRITE_SA: 535cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson status = i40e_acquire_nvm(hw, I40E_RESOURCE_WRITE); 536cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson if (status) { 537cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson *errno = i40e_aq_rc_to_posix(hw->aq.asq_last_status); 538cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson } else { 539cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson status = i40e_nvmupd_nvm_write(hw, cmd, bytes, errno); 540cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson if (status) 541cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson i40e_release_nvm(hw); 542cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson else 543cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson hw->aq.nvm_release_on_done = true; 544cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson } 545cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson break; 546cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson 547cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson case I40E_NVMUPD_WRITE_SNT: 548cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson status = i40e_acquire_nvm(hw, I40E_RESOURCE_WRITE); 549cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson if (status) { 550cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson *errno = i40e_aq_rc_to_posix(hw->aq.asq_last_status); 551cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson } else { 552cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson status = i40e_nvmupd_nvm_write(hw, cmd, bytes, errno); 553cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson hw->nvmupd_state = I40E_NVMUPD_STATE_WRITING; 554cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson } 555cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson break; 556cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson 557cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson case I40E_NVMUPD_CSUM_SA: 558cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson status = i40e_acquire_nvm(hw, I40E_RESOURCE_WRITE); 559cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson if (status) { 560cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson *errno = i40e_aq_rc_to_posix(hw->aq.asq_last_status); 561cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson } else { 562cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson status = i40e_update_nvm_checksum(hw); 563cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson if (status) { 564cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson *errno = hw->aq.asq_last_status ? 565cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson i40e_aq_rc_to_posix(hw->aq.asq_last_status) : 566cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson -EIO; 567cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson i40e_release_nvm(hw); 568cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson } else { 569cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson hw->aq.nvm_release_on_done = true; 570cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson } 571cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson } 572cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson break; 573cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson 574cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson default: 575cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson status = I40E_ERR_NVM; 576cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson *errno = -ESRCH; 577cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson break; 578cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson } 579cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson return status; 580cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson} 581cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson 582cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson/** 583cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson * i40e_nvmupd_state_reading - Handle NVM update state Reading 584cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson * @hw: pointer to hardware structure 585cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson * @cmd: pointer to nvm update command buffer 586cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson * @bytes: pointer to the data buffer 587cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson * @errno: pointer to return error code 588cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson * 589cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson * NVM ownership is already held. Process legitimate commands and set any 590cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson * change in state; reject all other commands. 591cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson **/ 592cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelsonstatic i40e_status i40e_nvmupd_state_reading(struct i40e_hw *hw, 593cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson struct i40e_nvm_access *cmd, 594cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson u8 *bytes, int *errno) 595cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson{ 596cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson i40e_status status; 597cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson enum i40e_nvmupd_cmd upd_cmd; 598cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson 599cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson upd_cmd = i40e_nvmupd_validate_command(hw, cmd, errno); 600cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson 601cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson switch (upd_cmd) { 602cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson case I40E_NVMUPD_READ_SA: 603cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson case I40E_NVMUPD_READ_CON: 604cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson status = i40e_nvmupd_nvm_read(hw, cmd, bytes, errno); 605cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson break; 606cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson 607cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson case I40E_NVMUPD_READ_LCB: 608cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson status = i40e_nvmupd_nvm_read(hw, cmd, bytes, errno); 609cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson i40e_release_nvm(hw); 610cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson hw->nvmupd_state = I40E_NVMUPD_STATE_INIT; 611cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson break; 612cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson 613cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson default: 614cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson status = I40E_NOT_SUPPORTED; 615cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson *errno = -ESRCH; 616cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson break; 617cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson } 618cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson return status; 619cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson} 620cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson 621cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson/** 622cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson * i40e_nvmupd_state_writing - Handle NVM update state Writing 623cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson * @hw: pointer to hardware structure 624cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson * @cmd: pointer to nvm update command buffer 625cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson * @bytes: pointer to the data buffer 626cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson * @errno: pointer to return error code 627cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson * 628cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson * NVM ownership is already held. Process legitimate commands and set any 629cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson * change in state; reject all other commands 630cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson **/ 631cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelsonstatic i40e_status i40e_nvmupd_state_writing(struct i40e_hw *hw, 632cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson struct i40e_nvm_access *cmd, 633cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson u8 *bytes, int *errno) 634cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson{ 635cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson i40e_status status; 636cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson enum i40e_nvmupd_cmd upd_cmd; 637cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson 638cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson upd_cmd = i40e_nvmupd_validate_command(hw, cmd, errno); 639cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson 640cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson switch (upd_cmd) { 641cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson case I40E_NVMUPD_WRITE_CON: 642cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson status = i40e_nvmupd_nvm_write(hw, cmd, bytes, errno); 643cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson break; 644cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson 645cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson case I40E_NVMUPD_WRITE_LCB: 646cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson status = i40e_nvmupd_nvm_write(hw, cmd, bytes, errno); 647cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson if (!status) { 648cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson hw->aq.nvm_release_on_done = true; 649cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson hw->nvmupd_state = I40E_NVMUPD_STATE_INIT; 650cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson } 651cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson break; 652cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson 653cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson case I40E_NVMUPD_CSUM_CON: 654cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson status = i40e_update_nvm_checksum(hw); 655cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson if (status) 656cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson *errno = hw->aq.asq_last_status ? 657cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson i40e_aq_rc_to_posix(hw->aq.asq_last_status) : 658cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson -EIO; 659cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson break; 660cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson 661cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson case I40E_NVMUPD_CSUM_LCB: 662cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson status = i40e_update_nvm_checksum(hw); 663cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson if (status) { 664cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson *errno = hw->aq.asq_last_status ? 665cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson i40e_aq_rc_to_posix(hw->aq.asq_last_status) : 666cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson -EIO; 667cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson } else { 668cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson hw->aq.nvm_release_on_done = true; 669cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson hw->nvmupd_state = I40E_NVMUPD_STATE_INIT; 670cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson } 671cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson break; 672cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson 673cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson default: 674cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson status = I40E_NOT_SUPPORTED; 675cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson *errno = -ESRCH; 676cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson break; 677cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson } 678cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson return status; 679cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson} 680cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson 681cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson/** 682cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson * i40e_nvmupd_validate_command - Validate given command 683cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson * @hw: pointer to hardware structure 684cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson * @cmd: pointer to nvm update command buffer 685cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson * @errno: pointer to return error code 686cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson * 687cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson * Return one of the valid command types or I40E_NVMUPD_INVALID 688cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson **/ 689cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelsonstatic enum i40e_nvmupd_cmd i40e_nvmupd_validate_command(struct i40e_hw *hw, 690cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson struct i40e_nvm_access *cmd, 691cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson int *errno) 692cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson{ 693cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson enum i40e_nvmupd_cmd upd_cmd; 694cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson u8 transaction, module; 695cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson 696cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson /* anything that doesn't match a recognized case is an error */ 697cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson upd_cmd = I40E_NVMUPD_INVALID; 698cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson 699cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson transaction = i40e_nvmupd_get_transaction(cmd->config); 700cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson module = i40e_nvmupd_get_module(cmd->config); 701cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson 702cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson /* limits on data size */ 703cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson if ((cmd->data_size < 1) || 704cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson (cmd->data_size > I40E_NVMUPD_MAX_DATA)) { 705cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson hw_dbg(hw, "i40e_nvmupd_validate_command data_size %d\n", 706cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson cmd->data_size); 707cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson *errno = -EFAULT; 708cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson return I40E_NVMUPD_INVALID; 709cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson } 710cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson 711cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson switch (cmd->command) { 712cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson case I40E_NVM_READ: 713cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson switch (transaction) { 714cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson case I40E_NVM_CON: 715cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson upd_cmd = I40E_NVMUPD_READ_CON; 716cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson break; 717cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson case I40E_NVM_SNT: 718cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson upd_cmd = I40E_NVMUPD_READ_SNT; 719cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson break; 720cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson case I40E_NVM_LCB: 721cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson upd_cmd = I40E_NVMUPD_READ_LCB; 722cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson break; 723cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson case I40E_NVM_SA: 724cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson upd_cmd = I40E_NVMUPD_READ_SA; 725cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson break; 726cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson } 727cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson break; 728cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson 729cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson case I40E_NVM_WRITE: 730cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson switch (transaction) { 731cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson case I40E_NVM_CON: 732cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson upd_cmd = I40E_NVMUPD_WRITE_CON; 733cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson break; 734cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson case I40E_NVM_SNT: 735cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson upd_cmd = I40E_NVMUPD_WRITE_SNT; 736cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson break; 737cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson case I40E_NVM_LCB: 738cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson upd_cmd = I40E_NVMUPD_WRITE_LCB; 739cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson break; 740cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson case I40E_NVM_SA: 741cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson upd_cmd = I40E_NVMUPD_WRITE_SA; 742cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson break; 743cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson case I40E_NVM_ERA: 744cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson upd_cmd = I40E_NVMUPD_WRITE_ERA; 745cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson break; 746cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson case I40E_NVM_CSUM: 747cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson upd_cmd = I40E_NVMUPD_CSUM_CON; 748cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson break; 749cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson case (I40E_NVM_CSUM|I40E_NVM_SA): 750cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson upd_cmd = I40E_NVMUPD_CSUM_SA; 751cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson break; 752cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson case (I40E_NVM_CSUM|I40E_NVM_LCB): 753cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson upd_cmd = I40E_NVMUPD_CSUM_LCB; 754cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson break; 755cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson } 756cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson break; 757cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson } 758cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson 759cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson if (upd_cmd == I40E_NVMUPD_INVALID) { 760cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson *errno = -EFAULT; 761cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson hw_dbg(hw, 762cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson "i40e_nvmupd_validate_command returns %d errno: %d\n", 763cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson upd_cmd, *errno); 764cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson } 765cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson return upd_cmd; 766cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson} 767cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson 768cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson/** 769cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson * i40e_nvmupd_nvm_read - Read NVM 770cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson * @hw: pointer to hardware structure 771cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson * @cmd: pointer to nvm update command buffer 772cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson * @bytes: pointer to the data buffer 773cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson * @errno: pointer to return error code 774cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson * 775cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson * cmd structure contains identifiers and data buffer 776cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson **/ 777cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelsonstatic i40e_status i40e_nvmupd_nvm_read(struct i40e_hw *hw, 778cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson struct i40e_nvm_access *cmd, 779cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson u8 *bytes, int *errno) 780cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson{ 781cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson i40e_status status; 782cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson u8 module, transaction; 783cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson bool last; 784cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson 785cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson transaction = i40e_nvmupd_get_transaction(cmd->config); 786cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson module = i40e_nvmupd_get_module(cmd->config); 787cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson last = (transaction == I40E_NVM_LCB) || (transaction == I40E_NVM_SA); 788cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson hw_dbg(hw, "i40e_nvmupd_nvm_read mod 0x%x off 0x%x len 0x%x\n", 789cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson module, cmd->offset, cmd->data_size); 790cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson 791cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson status = i40e_aq_read_nvm(hw, module, cmd->offset, (u16)cmd->data_size, 792cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson bytes, last, NULL); 793cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson hw_dbg(hw, "i40e_nvmupd_nvm_read status %d\n", status); 794cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson if (status) 795cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson *errno = i40e_aq_rc_to_posix(hw->aq.asq_last_status); 796cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson 797cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson return status; 798cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson} 799cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson 800cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson/** 801cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson * i40e_nvmupd_nvm_erase - Erase an NVM module 802cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson * @hw: pointer to hardware structure 803cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson * @cmd: pointer to nvm update command buffer 804cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson * @errno: pointer to return error code 805cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson * 806cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson * module, offset, data_size and data are in cmd structure 807cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson **/ 808cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelsonstatic i40e_status i40e_nvmupd_nvm_erase(struct i40e_hw *hw, 809cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson struct i40e_nvm_access *cmd, 810cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson int *errno) 811cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson{ 812cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson i40e_status status = 0; 813cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson u8 module, transaction; 814cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson bool last; 815cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson 816cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson transaction = i40e_nvmupd_get_transaction(cmd->config); 817cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson module = i40e_nvmupd_get_module(cmd->config); 818cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson last = (transaction & I40E_NVM_LCB); 819cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson hw_dbg(hw, "i40e_nvmupd_nvm_erase mod 0x%x off 0x%x len 0x%x\n", 820cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson module, cmd->offset, cmd->data_size); 821cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson status = i40e_aq_erase_nvm(hw, module, cmd->offset, (u16)cmd->data_size, 822cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson last, NULL); 823cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson hw_dbg(hw, "i40e_nvmupd_nvm_erase status %d\n", status); 824cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson if (status) 825cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson *errno = i40e_aq_rc_to_posix(hw->aq.asq_last_status); 826cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson 827cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson return status; 828cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson} 829cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson 830cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson/** 831cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson * i40e_nvmupd_nvm_write - Write NVM 832cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson * @hw: pointer to hardware structure 833cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson * @cmd: pointer to nvm update command buffer 834cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson * @bytes: pointer to the data buffer 835cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson * @errno: pointer to return error code 836cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson * 837cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson * module, offset, data_size and data are in cmd structure 838cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson **/ 839cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelsonstatic i40e_status i40e_nvmupd_nvm_write(struct i40e_hw *hw, 840cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson struct i40e_nvm_access *cmd, 841cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson u8 *bytes, int *errno) 842cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson{ 843cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson i40e_status status = 0; 844cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson u8 module, transaction; 845cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson bool last; 846cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson 847cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson transaction = i40e_nvmupd_get_transaction(cmd->config); 848cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson module = i40e_nvmupd_get_module(cmd->config); 849cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson last = (transaction & I40E_NVM_LCB); 850cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson hw_dbg(hw, "i40e_nvmupd_nvm_write mod 0x%x off 0x%x len 0x%x\n", 851cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson module, cmd->offset, cmd->data_size); 852cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson status = i40e_aq_update_nvm(hw, module, cmd->offset, 853cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson (u16)cmd->data_size, bytes, last, NULL); 854cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson hw_dbg(hw, "i40e_nvmupd_nvm_write status %d\n", status); 855cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson if (status) 856cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson *errno = i40e_aq_rc_to_posix(hw->aq.asq_last_status); 857cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson 858cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson return status; 859cd552cb49e9ad5fd8748fb6b38a8bd38e9e4d86cShannon Nelson} 860