i40e: Add AQ commands for NVM Update for X722
X722 does NVM update via the adminq queue, so we need to add support for that. Signed-off-by: Shannon Nelson <shannon.nelson@intel.com> Signed-off-by: Catherine Sullivan <catherine.sullivan@intel.com> Tested-by: Jim Young <james.m.young@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
This commit is contained in:
parent
52eb95ef32
commit
7073f46e44
@ -211,6 +211,74 @@ read_nvm_exit:
|
|||||||
return ret_code;
|
return ret_code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* i40e_read_nvm_aq - Read Shadow RAM.
|
||||||
|
* @hw: pointer to the HW structure.
|
||||||
|
* @module_pointer: module pointer location in words from the NVM beginning
|
||||||
|
* @offset: offset in words from module start
|
||||||
|
* @words: number of words to write
|
||||||
|
* @data: buffer with words to write to the Shadow RAM
|
||||||
|
* @last_command: tells the AdminQ that this is the last command
|
||||||
|
*
|
||||||
|
* Writes a 16 bit words buffer to the Shadow RAM using the admin command.
|
||||||
|
**/
|
||||||
|
static i40e_status i40e_read_nvm_aq(struct i40e_hw *hw, u8 module_pointer,
|
||||||
|
u32 offset, u16 words, void *data,
|
||||||
|
bool last_command)
|
||||||
|
{
|
||||||
|
i40e_status ret_code = I40E_ERR_NVM;
|
||||||
|
struct i40e_asq_cmd_details cmd_details;
|
||||||
|
|
||||||
|
memset(&cmd_details, 0, sizeof(cmd_details));
|
||||||
|
|
||||||
|
/* Here we are checking the SR limit only for the flat memory model.
|
||||||
|
* We cannot do it for the module-based model, as we did not acquire
|
||||||
|
* the NVM resource yet (we cannot get the module pointer value).
|
||||||
|
* Firmware will check the module-based model.
|
||||||
|
*/
|
||||||
|
if ((offset + words) > hw->nvm.sr_size)
|
||||||
|
i40e_debug(hw, I40E_DEBUG_NVM,
|
||||||
|
"NVM write error: offset %d beyond Shadow RAM limit %d\n",
|
||||||
|
(offset + words), hw->nvm.sr_size);
|
||||||
|
else if (words > I40E_SR_SECTOR_SIZE_IN_WORDS)
|
||||||
|
/* We can write only up to 4KB (one sector), in one AQ write */
|
||||||
|
i40e_debug(hw, I40E_DEBUG_NVM,
|
||||||
|
"NVM write fail error: tried to write %d words, limit is %d.\n",
|
||||||
|
words, I40E_SR_SECTOR_SIZE_IN_WORDS);
|
||||||
|
else if (((offset + (words - 1)) / I40E_SR_SECTOR_SIZE_IN_WORDS)
|
||||||
|
!= (offset / I40E_SR_SECTOR_SIZE_IN_WORDS))
|
||||||
|
/* A single write cannot spread over two sectors */
|
||||||
|
i40e_debug(hw, I40E_DEBUG_NVM,
|
||||||
|
"NVM write error: cannot spread over two sectors in a single write offset=%d words=%d\n",
|
||||||
|
offset, words);
|
||||||
|
else
|
||||||
|
ret_code = i40e_aq_read_nvm(hw, module_pointer,
|
||||||
|
2 * offset, /*bytes*/
|
||||||
|
2 * words, /*bytes*/
|
||||||
|
data, last_command, &cmd_details);
|
||||||
|
|
||||||
|
return ret_code;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* i40e_read_nvm_word_aq - Reads Shadow RAM via AQ
|
||||||
|
* @hw: pointer to the HW structure
|
||||||
|
* @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF)
|
||||||
|
* @data: word read from the Shadow RAM
|
||||||
|
*
|
||||||
|
* Reads one 16 bit word from the Shadow RAM using the GLNVM_SRCTL register.
|
||||||
|
**/
|
||||||
|
static i40e_status i40e_read_nvm_word_aq(struct i40e_hw *hw, u16 offset,
|
||||||
|
u16 *data)
|
||||||
|
{
|
||||||
|
i40e_status ret_code = I40E_ERR_TIMEOUT;
|
||||||
|
|
||||||
|
ret_code = i40e_read_nvm_aq(hw, 0x0, offset, 1, data, true);
|
||||||
|
*data = le16_to_cpu(*(__le16 *)data);
|
||||||
|
|
||||||
|
return ret_code;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* i40e_read_nvm_word - Reads Shadow RAM
|
* i40e_read_nvm_word - Reads Shadow RAM
|
||||||
* @hw: pointer to the HW structure
|
* @hw: pointer to the HW structure
|
||||||
@ -222,6 +290,8 @@ read_nvm_exit:
|
|||||||
i40e_status i40e_read_nvm_word(struct i40e_hw *hw, u16 offset,
|
i40e_status i40e_read_nvm_word(struct i40e_hw *hw, u16 offset,
|
||||||
u16 *data)
|
u16 *data)
|
||||||
{
|
{
|
||||||
|
if (hw->mac.type == I40E_MAC_X722)
|
||||||
|
return i40e_read_nvm_word_aq(hw, offset, data);
|
||||||
return i40e_read_nvm_word_srctl(hw, offset, data);
|
return i40e_read_nvm_word_srctl(hw, offset, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -256,6 +326,63 @@ static i40e_status i40e_read_nvm_buffer_srctl(struct i40e_hw *hw, u16 offset,
|
|||||||
return ret_code;
|
return ret_code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* i40e_read_nvm_buffer_aq - Reads Shadow RAM buffer via AQ
|
||||||
|
* @hw: pointer to the HW structure
|
||||||
|
* @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF).
|
||||||
|
* @words: (in) number of words to read; (out) number of words actually read
|
||||||
|
* @data: words read from the Shadow RAM
|
||||||
|
*
|
||||||
|
* Reads 16 bit words (data buffer) from the SR using the i40e_read_nvm_aq()
|
||||||
|
* method. The buffer read is preceded by the NVM ownership take
|
||||||
|
* and followed by the release.
|
||||||
|
**/
|
||||||
|
static i40e_status i40e_read_nvm_buffer_aq(struct i40e_hw *hw, u16 offset,
|
||||||
|
u16 *words, u16 *data)
|
||||||
|
{
|
||||||
|
i40e_status ret_code;
|
||||||
|
u16 read_size = *words;
|
||||||
|
bool last_cmd = false;
|
||||||
|
u16 words_read = 0;
|
||||||
|
u16 i = 0;
|
||||||
|
|
||||||
|
do {
|
||||||
|
/* Calculate number of bytes we should read in this step.
|
||||||
|
* FVL AQ do not allow to read more than one page at a time or
|
||||||
|
* to cross page boundaries.
|
||||||
|
*/
|
||||||
|
if (offset % I40E_SR_SECTOR_SIZE_IN_WORDS)
|
||||||
|
read_size = min(*words,
|
||||||
|
(u16)(I40E_SR_SECTOR_SIZE_IN_WORDS -
|
||||||
|
(offset % I40E_SR_SECTOR_SIZE_IN_WORDS)));
|
||||||
|
else
|
||||||
|
read_size = min((*words - words_read),
|
||||||
|
I40E_SR_SECTOR_SIZE_IN_WORDS);
|
||||||
|
|
||||||
|
/* Check if this is last command, if so set proper flag */
|
||||||
|
if ((words_read + read_size) >= *words)
|
||||||
|
last_cmd = true;
|
||||||
|
|
||||||
|
ret_code = i40e_read_nvm_aq(hw, 0x0, offset, read_size,
|
||||||
|
data + words_read, last_cmd);
|
||||||
|
if (ret_code)
|
||||||
|
goto read_nvm_buffer_aq_exit;
|
||||||
|
|
||||||
|
/* Increment counter for words already read and move offset to
|
||||||
|
* new read location
|
||||||
|
*/
|
||||||
|
words_read += read_size;
|
||||||
|
offset += read_size;
|
||||||
|
} while (words_read < *words);
|
||||||
|
|
||||||
|
for (i = 0; i < *words; i++)
|
||||||
|
data[i] = le16_to_cpu(((__le16 *)data)[i]);
|
||||||
|
|
||||||
|
read_nvm_buffer_aq_exit:
|
||||||
|
*words = words_read;
|
||||||
|
return ret_code;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* i40e_read_nvm_buffer - Reads Shadow RAM buffer
|
* i40e_read_nvm_buffer - Reads Shadow RAM buffer
|
||||||
* @hw: pointer to the HW structure
|
* @hw: pointer to the HW structure
|
||||||
@ -270,6 +397,8 @@ static i40e_status i40e_read_nvm_buffer_srctl(struct i40e_hw *hw, u16 offset,
|
|||||||
i40e_status i40e_read_nvm_buffer(struct i40e_hw *hw, u16 offset,
|
i40e_status i40e_read_nvm_buffer(struct i40e_hw *hw, u16 offset,
|
||||||
u16 *words, u16 *data)
|
u16 *words, u16 *data)
|
||||||
{
|
{
|
||||||
|
if (hw->mac.type == I40E_MAC_X722)
|
||||||
|
return i40e_read_nvm_buffer_aq(hw, offset, words, data);
|
||||||
return i40e_read_nvm_buffer_srctl(hw, offset, words, data);
|
return i40e_read_nvm_buffer_srctl(hw, offset, words, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user