9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi/******************************************************************************
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi Copyright (c) 2013-2015, Intel Corporation
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi All rights reserved.
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi Redistribution and use in source and binary forms, with or without
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi modification, are permitted provided that the following conditions are met:
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi 1. Redistributions of source code must retain the above copyright notice,
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi this list of conditions and the following disclaimer.
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi 2. Redistributions in binary form must reproduce the above copyright
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi notice, this list of conditions and the following disclaimer in the
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi documentation and/or other materials provided with the distribution.
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi 3. Neither the name of the Intel Corporation nor the names of its
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi contributors may be used to endorse or promote products derived from
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi this software without specific prior written permission.
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi POSSIBILITY OF SUCH DAMAGE.
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi******************************************************************************/
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi/*$FreeBSD: head/sys/dev/ixl/i40e_nvm.c 284049 2015-06-05 22:52:42Z jfv $*/
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi#include "i40e_prototype.h"
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchienum i40e_status_code i40e_read_nvm_word_srctl(struct i40e_hw *hw, u16 offset,
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi u16 *data);
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchienum i40e_status_code i40e_read_nvm_word_aq(struct i40e_hw *hw, u16 offset,
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi u16 *data);
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchienum i40e_status_code i40e_read_nvm_buffer_srctl(struct i40e_hw *hw, u16 offset,
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi u16 *words, u16 *data);
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchienum i40e_status_code i40e_read_nvm_buffer_aq(struct i40e_hw *hw, u16 offset,
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi u16 *words, u16 *data);
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchienum i40e_status_code i40e_read_nvm_aq(struct i40e_hw *hw, u8 module_pointer,
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi u32 offset, u16 words, void *data,
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi bool last_command);
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi/**
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * i40e_init_nvm_ops - Initialize NVM function pointers
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * @hw: pointer to the HW structure
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi *
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * Setup the function pointers and the NVM info structure. Should be called
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * once per NVM initialization, e.g. inside the i40e_init_shared_code().
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * Please notice that the NVM term is used here (& in all methods covered
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * in this file) as an equivalent of the FLASH part mapped into the SR.
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * We are accessing FLASH always thru the Shadow RAM.
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi **/
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchienum i40e_status_code i40e_init_nvm(struct i40e_hw *hw)
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi{
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi struct i40e_nvm_info *nvm = &hw->nvm;
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi enum i40e_status_code ret_code = I40E_SUCCESS;
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi u32 fla, gens;
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi u8 sr_size;
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi DEBUGFUNC("i40e_init_nvm");
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi /* The SR size is stored regardless of the nvm programming mode
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * as the blank mode may be used in the factory line.
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi */
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi gens = rd32(hw, I40E_GLNVM_GENS);
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi sr_size = ((gens & I40E_GLNVM_GENS_SR_SIZE_MASK) >>
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi I40E_GLNVM_GENS_SR_SIZE_SHIFT);
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi /* Switching to words (sr_size contains power of 2KB) */
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi nvm->sr_size = BIT(sr_size) * I40E_SR_WORDS_IN_1KB;
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi /* Check if we are in the normal or blank NVM programming mode */
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi fla = rd32(hw, I40E_GLNVM_FLA);
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi if (fla & I40E_GLNVM_FLA_LOCKED_MASK) { /* Normal programming mode */
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi /* Max NVM timeout */
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi nvm->timeout = I40E_MAX_NVM_TIMEOUT;
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi nvm->blank_nvm_mode = FALSE;
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi } else { /* Blank programming mode */
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi nvm->blank_nvm_mode = TRUE;
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi ret_code = I40E_ERR_NVM_BLANK_MODE;
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi i40e_debug(hw, I40E_DEBUG_NVM, "NVM init error: unsupported blank mode.\n");
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi }
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi return ret_code;
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi}
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi/**
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * i40e_acquire_nvm - Generic request for acquiring the NVM ownership
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * @hw: pointer to the HW structure
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * @access: NVM access type (read or write)
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi *
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * This function will request NVM ownership for reading
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * via the proper Admin Command.
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi **/
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchienum i40e_status_code i40e_acquire_nvm(struct i40e_hw *hw,
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi enum i40e_aq_resource_access_type access)
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi{
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi enum i40e_status_code ret_code = I40E_SUCCESS;
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi u64 gtime, timeout;
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi u64 time_left = 0;
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi DEBUGFUNC("i40e_acquire_nvm");
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi if (hw->nvm.blank_nvm_mode)
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi goto i40e_i40e_acquire_nvm_exit;
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi ret_code = i40e_aq_request_resource(hw, I40E_NVM_RESOURCE_ID, access,
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi 0, &time_left, NULL);
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi /* Reading the Global Device Timer */
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi gtime = rd32(hw, I40E_GLVFGEN_TIMER);
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi /* Store the timeout */
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi hw->nvm.hw_semaphore_timeout = I40E_MS_TO_GTIME(time_left) + gtime;
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi if (ret_code)
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi i40e_debug(hw, I40E_DEBUG_NVM,
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi "NVM acquire type %d failed time_left=%llu ret=%d aq_err=%d\n",
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi access, time_left, ret_code, hw->aq.asq_last_status);
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi if (ret_code && time_left) {
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi /* Poll until the current NVM owner timeouts */
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi timeout = I40E_MS_TO_GTIME(I40E_MAX_NVM_TIMEOUT) + gtime;
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi while ((gtime < timeout) && time_left) {
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi i40e_msec_delay(10);
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi gtime = rd32(hw, I40E_GLVFGEN_TIMER);
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi ret_code = i40e_aq_request_resource(hw,
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi I40E_NVM_RESOURCE_ID,
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi access, 0, &time_left,
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi NULL);
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi if (ret_code == I40E_SUCCESS) {
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi hw->nvm.hw_semaphore_timeout =
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi I40E_MS_TO_GTIME(time_left) + gtime;
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi break;
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi }
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi }
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi if (ret_code != I40E_SUCCESS) {
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi hw->nvm.hw_semaphore_timeout = 0;
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi i40e_debug(hw, I40E_DEBUG_NVM,
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi "NVM acquire timed out, wait %llu ms before trying again. status=%d aq_err=%d\n",
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi time_left, ret_code, hw->aq.asq_last_status);
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi }
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi }
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchii40e_i40e_acquire_nvm_exit:
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi return ret_code;
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi}
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi/**
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * i40e_release_nvm - Generic request for releasing the NVM ownership
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * @hw: pointer to the HW structure
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi *
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * This function will release NVM resource via the proper Admin Command.
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi **/
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchivoid i40e_release_nvm(struct i40e_hw *hw)
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi{
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi enum i40e_status_code ret_code = I40E_SUCCESS;
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi u32 total_delay = 0;
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi DEBUGFUNC("i40e_release_nvm");
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi if (hw->nvm.blank_nvm_mode)
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi return;
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi ret_code = i40e_aq_release_resource(hw, I40E_NVM_RESOURCE_ID, 0, NULL);
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi /* there are some rare cases when trying to release the resource
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * results in an admin Q timeout, so handle them correctly
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi */
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi while ((ret_code == I40E_ERR_ADMIN_QUEUE_TIMEOUT) &&
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi (total_delay < hw->aq.asq_cmd_timeout)) {
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi i40e_msec_delay(1);
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi ret_code = i40e_aq_release_resource(hw,
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi I40E_NVM_RESOURCE_ID, 0, NULL);
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi total_delay++;
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi }
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi}
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi/**
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * i40e_poll_sr_srctl_done_bit - Polls the GLNVM_SRCTL done bit
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * @hw: pointer to the HW structure
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi *
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * Polls the SRCTL Shadow RAM register done bit.
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi **/
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchistatic enum i40e_status_code i40e_poll_sr_srctl_done_bit(struct i40e_hw *hw)
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi{
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi enum i40e_status_code ret_code = I40E_ERR_TIMEOUT;
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi u32 srctl, wait_cnt;
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi DEBUGFUNC("i40e_poll_sr_srctl_done_bit");
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi /* Poll the I40E_GLNVM_SRCTL until the done bit is set */
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi for (wait_cnt = 0; wait_cnt < I40E_SRRD_SRCTL_ATTEMPTS; wait_cnt++) {
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi srctl = rd32(hw, I40E_GLNVM_SRCTL);
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi if (srctl & I40E_GLNVM_SRCTL_DONE_MASK) {
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi ret_code = I40E_SUCCESS;
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi break;
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi }
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi i40e_usec_delay(5);
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi }
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi if (ret_code == I40E_ERR_TIMEOUT)
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi i40e_debug(hw, I40E_DEBUG_NVM, "Done bit in GLNVM_SRCTL not set");
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi return ret_code;
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi}
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi/**
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * i40e_read_nvm_word - Reads Shadow RAM
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * @hw: pointer to the HW structure
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF)
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * @data: word read from the Shadow RAM
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi *
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * Reads one 16 bit word from the Shadow RAM using the GLNVM_SRCTL register.
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi **/
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchienum i40e_status_code i40e_read_nvm_word(struct i40e_hw *hw, u16 offset,
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi u16 *data)
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi{
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi#ifdef X722_SUPPORT
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi if (hw->mac.type == I40E_MAC_X722)
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi return i40e_read_nvm_word_aq(hw, offset, data);
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi#endif
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi return i40e_read_nvm_word_srctl(hw, offset, data);
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi}
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi/**
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * i40e_read_nvm_word_srctl - Reads Shadow RAM via SRCTL register
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * @hw: pointer to the HW structure
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF)
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * @data: word read from the Shadow RAM
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi *
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * Reads one 16 bit word from the Shadow RAM using the GLNVM_SRCTL register.
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi **/
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchienum i40e_status_code i40e_read_nvm_word_srctl(struct i40e_hw *hw, u16 offset,
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi u16 *data)
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi{
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi enum i40e_status_code ret_code = I40E_ERR_TIMEOUT;
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi u32 sr_reg;
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi DEBUGFUNC("i40e_read_nvm_word_srctl");
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi if (offset >= hw->nvm.sr_size) {
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi i40e_debug(hw, I40E_DEBUG_NVM,
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi "NVM read error: Offset %d beyond Shadow RAM limit %d\n",
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi offset, hw->nvm.sr_size);
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi ret_code = I40E_ERR_PARAM;
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi goto read_nvm_exit;
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi }
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi /* Poll the done bit first */
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi ret_code = i40e_poll_sr_srctl_done_bit(hw);
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi if (ret_code == I40E_SUCCESS) {
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi /* Write the address and start reading */
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi sr_reg = ((u32)offset << I40E_GLNVM_SRCTL_ADDR_SHIFT) |
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi BIT(I40E_GLNVM_SRCTL_START_SHIFT);
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi wr32(hw, I40E_GLNVM_SRCTL, sr_reg);
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi /* Poll I40E_GLNVM_SRCTL until the done bit is set */
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi ret_code = i40e_poll_sr_srctl_done_bit(hw);
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi if (ret_code == I40E_SUCCESS) {
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi sr_reg = rd32(hw, I40E_GLNVM_SRDATA);
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi *data = (u16)((sr_reg &
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi I40E_GLNVM_SRDATA_RDDATA_MASK)
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi >> I40E_GLNVM_SRDATA_RDDATA_SHIFT);
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi }
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi }
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi if (ret_code != I40E_SUCCESS)
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi i40e_debug(hw, I40E_DEBUG_NVM,
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi "NVM read error: Couldn't access Shadow RAM address: 0x%x\n",
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi offset);
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchiread_nvm_exit:
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi return ret_code;
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi}
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi/**
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * i40e_read_nvm_word_aq - Reads Shadow RAM via AQ
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * @hw: pointer to the HW structure
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF)
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * @data: word read from the Shadow RAM
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi *
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * Reads one 16 bit word from the Shadow RAM using the GLNVM_SRCTL register.
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi **/
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchienum i40e_status_code i40e_read_nvm_word_aq(struct i40e_hw *hw, u16 offset,
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi u16 *data)
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi{
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi enum i40e_status_code ret_code = I40E_ERR_TIMEOUT;
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi DEBUGFUNC("i40e_read_nvm_word_aq");
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi ret_code = i40e_read_nvm_aq(hw, 0x0, offset, 1, data, TRUE);
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi *data = LE16_TO_CPU(*(__le16 *)data);
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi return ret_code;
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi}
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi/**
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * i40e_read_nvm_buffer - Reads Shadow RAM buffer
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * @hw: pointer to the HW structure
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF).
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * @words: (in) number of words to read; (out) number of words actually read
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * @data: words read from the Shadow RAM
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi *
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * Reads 16 bit words (data buffer) from the SR using the i40e_read_nvm_srrd()
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * method. The buffer read is preceded by the NVM ownership take
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * and followed by the release.
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi **/
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchienum i40e_status_code i40e_read_nvm_buffer(struct i40e_hw *hw, u16 offset,
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi u16 *words, u16 *data)
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi{
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi#ifdef X722_SUPPORT
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi if (hw->mac.type == I40E_MAC_X722)
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi return i40e_read_nvm_buffer_aq(hw, offset, words, data);
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi#endif
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi return i40e_read_nvm_buffer_srctl(hw, offset, words, data);
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi}
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi/**
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * i40e_read_nvm_buffer_srctl - Reads Shadow RAM buffer via SRCTL register
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * @hw: pointer to the HW structure
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF).
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * @words: (in) number of words to read; (out) number of words actually read
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * @data: words read from the Shadow RAM
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi *
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * Reads 16 bit words (data buffer) from the SR using the i40e_read_nvm_srrd()
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * method. The buffer read is preceded by the NVM ownership take
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * and followed by the release.
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi **/
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchienum i40e_status_code i40e_read_nvm_buffer_srctl(struct i40e_hw *hw, u16 offset,
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi u16 *words, u16 *data)
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi{
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi enum i40e_status_code ret_code = I40E_SUCCESS;
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi u16 index, word;
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi DEBUGFUNC("i40e_read_nvm_buffer_srctl");
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi /* Loop thru the selected region */
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi for (word = 0; word < *words; word++) {
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi index = offset + word;
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi ret_code = i40e_read_nvm_word_srctl(hw, index, &data[word]);
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi if (ret_code != I40E_SUCCESS)
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi break;
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi }
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi /* Update the number of words read from the Shadow RAM */
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi *words = word;
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi return ret_code;
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi}
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi/**
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * i40e_read_nvm_buffer_aq - Reads Shadow RAM buffer via AQ
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * @hw: pointer to the HW structure
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF).
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * @words: (in) number of words to read; (out) number of words actually read
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * @data: words read from the Shadow RAM
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi *
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * Reads 16 bit words (data buffer) from the SR using the i40e_read_nvm_aq()
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * method. The buffer read is preceded by the NVM ownership take
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * and followed by the release.
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi **/
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchienum i40e_status_code i40e_read_nvm_buffer_aq(struct i40e_hw *hw, u16 offset,
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi u16 *words, u16 *data)
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi{
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi enum i40e_status_code ret_code;
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi u16 read_size = *words;
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi bool last_cmd = FALSE;
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi u16 words_read = 0;
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi u16 i = 0;
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi DEBUGFUNC("i40e_read_nvm_buffer_aq");
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi do {
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi /* Calculate number of bytes we should read in this step.
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * FVL AQ do not allow to read more than one page at a time or
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * to cross page boundaries.
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi */
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi if (offset % I40E_SR_SECTOR_SIZE_IN_WORDS)
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi read_size = min(*words,
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi (u16)(I40E_SR_SECTOR_SIZE_IN_WORDS -
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi (offset % I40E_SR_SECTOR_SIZE_IN_WORDS)));
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi else
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi read_size = min((*words - words_read),
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi I40E_SR_SECTOR_SIZE_IN_WORDS);
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi /* Check if this is last command, if so set proper flag */
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi if ((words_read + read_size) >= *words)
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi last_cmd = TRUE;
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi ret_code = i40e_read_nvm_aq(hw, 0x0, offset, read_size,
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi data + words_read, last_cmd);
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi if (ret_code != I40E_SUCCESS)
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi goto read_nvm_buffer_aq_exit;
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi /* Increment counter for words already read and move offset to
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * new read location
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi */
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi words_read += read_size;
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi offset += read_size;
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi } while (words_read < *words);
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi for (i = 0; i < *words; i++)
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi data[i] = LE16_TO_CPU(((__le16 *)data)[i]);
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchiread_nvm_buffer_aq_exit:
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi *words = words_read;
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi return ret_code;
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi}
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi/**
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * i40e_read_nvm_aq - Read Shadow RAM.
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * @hw: pointer to the HW structure.
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * @module_pointer: module pointer location in words from the NVM beginning
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * @offset: offset in words from module start
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * @words: number of words to write
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * @data: buffer with words to write to the Shadow RAM
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * @last_command: tells the AdminQ that this is the last command
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi *
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * Writes a 16 bit words buffer to the Shadow RAM using the admin command.
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi **/
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchienum i40e_status_code i40e_read_nvm_aq(struct i40e_hw *hw, u8 module_pointer,
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi u32 offset, u16 words, void *data,
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi bool last_command)
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi{
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi enum i40e_status_code ret_code = I40E_ERR_NVM;
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi struct i40e_asq_cmd_details cmd_details;
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi DEBUGFUNC("i40e_read_nvm_aq");
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi memset(&cmd_details, 0, sizeof(cmd_details));
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi cmd_details.wb_desc = &hw->nvm_wb_desc;
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi /* Here we are checking the SR limit only for the flat memory model.
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * We cannot do it for the module-based model, as we did not acquire
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * the NVM resource yet (we cannot get the module pointer value).
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * Firmware will check the module-based model.
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi */
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi if ((offset + words) > hw->nvm.sr_size)
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi i40e_debug(hw, I40E_DEBUG_NVM,
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi "NVM write error: offset %d beyond Shadow RAM limit %d\n",
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi (offset + words), hw->nvm.sr_size);
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi else if (words > I40E_SR_SECTOR_SIZE_IN_WORDS)
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi /* We can write only up to 4KB (one sector), in one AQ write */
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi i40e_debug(hw, I40E_DEBUG_NVM,
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi "NVM write fail error: tried to write %d words, limit is %d.\n",
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi words, I40E_SR_SECTOR_SIZE_IN_WORDS);
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi else if (((offset + (words - 1)) / I40E_SR_SECTOR_SIZE_IN_WORDS)
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi != (offset / I40E_SR_SECTOR_SIZE_IN_WORDS))
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi /* A single write cannot spread over two sectors */
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi i40e_debug(hw, I40E_DEBUG_NVM,
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi "NVM write error: cannot spread over two sectors in a single write offset=%d words=%d\n",
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi offset, words);
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi else
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi ret_code = i40e_aq_read_nvm(hw, module_pointer,
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi 2 * offset, /*bytes*/
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi 2 * words, /*bytes*/
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi data, last_command, &cmd_details);
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi return ret_code;
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi}
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi/**
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * i40e_write_nvm_aq - Writes Shadow RAM.
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * @hw: pointer to the HW structure.
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * @module_pointer: module pointer location in words from the NVM beginning
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * @offset: offset in words from module start
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * @words: number of words to write
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * @data: buffer with words to write to the Shadow RAM
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * @last_command: tells the AdminQ that this is the last command
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi *
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * Writes a 16 bit words buffer to the Shadow RAM using the admin command.
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi **/
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchienum i40e_status_code i40e_write_nvm_aq(struct i40e_hw *hw, u8 module_pointer,
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi u32 offset, u16 words, void *data,
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi bool last_command)
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi{
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi enum i40e_status_code ret_code = I40E_ERR_NVM;
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi struct i40e_asq_cmd_details cmd_details;
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi DEBUGFUNC("i40e_write_nvm_aq");
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi memset(&cmd_details, 0, sizeof(cmd_details));
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi cmd_details.wb_desc = &hw->nvm_wb_desc;
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi /* Here we are checking the SR limit only for the flat memory model.
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * We cannot do it for the module-based model, as we did not acquire
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * the NVM resource yet (we cannot get the module pointer value).
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * Firmware will check the module-based model.
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi */
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi if ((offset + words) > hw->nvm.sr_size)
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi DEBUGOUT("NVM write error: offset beyond Shadow RAM limit.\n");
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi else if (words > I40E_SR_SECTOR_SIZE_IN_WORDS)
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi /* We can write only up to 4KB (one sector), in one AQ write */
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi DEBUGOUT("NVM write fail error: cannot write more than 4KB in a single write.\n");
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi else if (((offset + (words - 1)) / I40E_SR_SECTOR_SIZE_IN_WORDS)
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi != (offset / I40E_SR_SECTOR_SIZE_IN_WORDS))
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi /* A single write cannot spread over two sectors */
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi DEBUGOUT("NVM write error: cannot spread over two sectors in a single write.\n");
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi else
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi ret_code = i40e_aq_update_nvm(hw, module_pointer,
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi 2 * offset, /*bytes*/
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi 2 * words, /*bytes*/
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi data, last_command, &cmd_details);
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi return ret_code;
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi}
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi/**
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * i40e_write_nvm_word - Writes Shadow RAM word
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * @hw: pointer to the HW structure
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * @offset: offset of the Shadow RAM word to write
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * @data: word to write to the Shadow RAM
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi *
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * Writes a 16 bit word to the SR using the i40e_write_nvm_aq() method.
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * NVM ownership have to be acquired and released (on ARQ completion event
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * reception) by caller. To commit SR to NVM update checksum function
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * should be called.
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi **/
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchienum i40e_status_code i40e_write_nvm_word(struct i40e_hw *hw, u32 offset,
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi void *data)
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi{
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi DEBUGFUNC("i40e_write_nvm_word");
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi *((__le16 *)data) = CPU_TO_LE16(*((u16 *)data));
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi /* Value 0x00 below means that we treat SR as a flat mem */
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi return i40e_write_nvm_aq(hw, 0x00, offset, 1, data, FALSE);
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi}
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi/**
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * i40e_write_nvm_buffer - Writes Shadow RAM buffer
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * @hw: pointer to the HW structure
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * @module_pointer: module pointer location in words from the NVM beginning
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * @offset: offset of the Shadow RAM buffer to write
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * @words: number of words to write
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * @data: words to write to the Shadow RAM
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi *
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * Writes a 16 bit words buffer to the Shadow RAM using the admin command.
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * NVM ownership must be acquired before calling this function and released
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * on ARQ completion event reception by caller. To commit SR to NVM update
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * checksum function should be called.
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi **/
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchienum i40e_status_code i40e_write_nvm_buffer(struct i40e_hw *hw,
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi u8 module_pointer, u32 offset,
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi u16 words, void *data)
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi{
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi __le16 *le_word_ptr = (__le16 *)data;
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi u16 *word_ptr = (u16 *)data;
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi u32 i = 0;
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi DEBUGFUNC("i40e_write_nvm_buffer");
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi for (i = 0; i < words; i++)
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi le_word_ptr[i] = CPU_TO_LE16(word_ptr[i]);
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi /* Here we will only write one buffer as the size of the modules
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * mirrored in the Shadow RAM is always less than 4K.
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi */
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi return i40e_write_nvm_aq(hw, module_pointer, offset, words,
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi data, FALSE);
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi}
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi/**
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * i40e_calc_nvm_checksum - Calculates and returns the checksum
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * @hw: pointer to hardware structure
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * @checksum: pointer to the checksum
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi *
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * This function calculates SW Checksum that covers the whole 64kB shadow RAM
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * except the VPD and PCIe ALT Auto-load modules. The structure and size of VPD
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * is customer specific and unknown. Therefore, this function skips all maximum
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * possible size of VPD (1kB).
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi **/
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchienum i40e_status_code i40e_calc_nvm_checksum(struct i40e_hw *hw, u16 *checksum)
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi{
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi enum i40e_status_code ret_code = I40E_SUCCESS;
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi struct i40e_virt_mem vmem;
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi u16 pcie_alt_module = 0;
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi u16 checksum_local = 0;
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi u16 vpd_module = 0;
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi u16 *data;
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi u16 i = 0;
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi DEBUGFUNC("i40e_calc_nvm_checksum");
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi ret_code = i40e_allocate_virt_mem(hw, &vmem,
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi I40E_SR_SECTOR_SIZE_IN_WORDS * sizeof(u16));
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi if (ret_code)
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi goto i40e_calc_nvm_checksum_exit;
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi data = (u16 *)vmem.va;
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi /* read pointer to VPD area */
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi ret_code = i40e_read_nvm_word(hw, I40E_SR_VPD_PTR, &vpd_module);
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi if (ret_code != I40E_SUCCESS) {
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi ret_code = I40E_ERR_NVM_CHECKSUM;
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi goto i40e_calc_nvm_checksum_exit;
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi }
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi /* read pointer to PCIe Alt Auto-load module */
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi ret_code = i40e_read_nvm_word(hw, I40E_SR_PCIE_ALT_AUTO_LOAD_PTR,
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi &pcie_alt_module);
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi if (ret_code != I40E_SUCCESS) {
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi ret_code = I40E_ERR_NVM_CHECKSUM;
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi goto i40e_calc_nvm_checksum_exit;
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi }
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi /* Calculate SW checksum that covers the whole 64kB shadow RAM
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * except the VPD and PCIe ALT Auto-load modules
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi */
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi for (i = 0; i < hw->nvm.sr_size; i++) {
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi /* Read SR page */
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi if ((i % I40E_SR_SECTOR_SIZE_IN_WORDS) == 0) {
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi u16 words = I40E_SR_SECTOR_SIZE_IN_WORDS;
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi ret_code = i40e_read_nvm_buffer(hw, i, &words, data);
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi if (ret_code != I40E_SUCCESS) {
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi ret_code = I40E_ERR_NVM_CHECKSUM;
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi goto i40e_calc_nvm_checksum_exit;
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi }
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi }
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi /* Skip Checksum word */
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi if (i == I40E_SR_SW_CHECKSUM_WORD)
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi continue;
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi /* Skip VPD module (convert byte size to word count) */
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi if ((i >= (u32)vpd_module) &&
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi (i < ((u32)vpd_module +
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi (I40E_SR_VPD_MODULE_MAX_SIZE / 2)))) {
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi continue;
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi }
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi /* Skip PCIe ALT module (convert byte size to word count) */
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi if ((i >= (u32)pcie_alt_module) &&
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi (i < ((u32)pcie_alt_module +
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi (I40E_SR_PCIE_ALT_MODULE_MAX_SIZE / 2)))) {
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi continue;
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi }
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi checksum_local += data[i % I40E_SR_SECTOR_SIZE_IN_WORDS];
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi }
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi *checksum = (u16)I40E_SR_SW_CHECKSUM_BASE - checksum_local;
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchii40e_calc_nvm_checksum_exit:
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi i40e_free_virt_mem(hw, &vmem);
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi return ret_code;
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi}
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi/**
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * i40e_update_nvm_checksum - Updates the NVM checksum
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * @hw: pointer to hardware structure
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi *
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * NVM ownership must be acquired before calling this function and released
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * on ARQ completion event reception by caller.
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * This function will commit SR to NVM.
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi **/
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchienum i40e_status_code i40e_update_nvm_checksum(struct i40e_hw *hw)
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi{
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi enum i40e_status_code ret_code = I40E_SUCCESS;
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi u16 checksum;
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi __le16 le_sum;
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi DEBUGFUNC("i40e_update_nvm_checksum");
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi ret_code = i40e_calc_nvm_checksum(hw, &checksum);
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi le_sum = CPU_TO_LE16(checksum);
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi if (ret_code == I40E_SUCCESS)
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi ret_code = i40e_write_nvm_aq(hw, 0x00, I40E_SR_SW_CHECKSUM_WORD,
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi 1, &le_sum, TRUE);
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi return ret_code;
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi}
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi/**
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * i40e_validate_nvm_checksum - Validate EEPROM checksum
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * @hw: pointer to hardware structure
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * @checksum: calculated checksum
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi *
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * Performs checksum calculation and validates the NVM SW checksum. If the
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * caller does not need checksum, the value can be NULL.
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi **/
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchienum i40e_status_code i40e_validate_nvm_checksum(struct i40e_hw *hw,
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi u16 *checksum)
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi{
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi enum i40e_status_code ret_code = I40E_SUCCESS;
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi u16 checksum_sr = 0;
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi u16 checksum_local = 0;
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi DEBUGFUNC("i40e_validate_nvm_checksum");
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi ret_code = i40e_calc_nvm_checksum(hw, &checksum_local);
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi if (ret_code != I40E_SUCCESS)
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi goto i40e_validate_nvm_checksum_exit;
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi /* Do not use i40e_read_nvm_word() because we do not want to take
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * the synchronization semaphores twice here.
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi */
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi i40e_read_nvm_word(hw, I40E_SR_SW_CHECKSUM_WORD, &checksum_sr);
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi /* Verify read checksum from EEPROM is the same as
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * calculated checksum
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi */
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi if (checksum_local != checksum_sr)
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi ret_code = I40E_ERR_NVM_CHECKSUM;
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi /* If the user cares, return the calculated checksum */
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi if (checksum)
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi *checksum = checksum_local;
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchii40e_validate_nvm_checksum_exit:
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi return ret_code;
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi}