aboutsummaryrefslogtreecommitdiff
path: root/sys/dev/ice/ice_nvm.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/ice/ice_nvm.c')
-rw-r--r--sys/dev/ice/ice_nvm.c398
1 files changed, 233 insertions, 165 deletions
diff --git a/sys/dev/ice/ice_nvm.c b/sys/dev/ice/ice_nvm.c
index 5234cb265f9b..ff30adfe8fa7 100644
--- a/sys/dev/ice/ice_nvm.c
+++ b/sys/dev/ice/ice_nvm.c
@@ -46,7 +46,7 @@
*
* Read the NVM using the admin queue commands (0x0701)
*/
-enum ice_status
+int
ice_aq_read_nvm(struct ice_hw *hw, u16 module_typeid, u32 offset, u16 length,
void *data, bool last_command, bool read_shadow_ram,
struct ice_sq_cd *cd)
@@ -92,14 +92,14 @@ ice_aq_read_nvm(struct ice_hw *hw, u16 module_typeid, u32 offset, u16 length,
* Returns a status code on failure. Note that the data pointer may be
* partially updated if some reads succeed before a failure.
*/
-enum ice_status
+int
ice_read_flat_nvm(struct ice_hw *hw, u32 offset, u32 *length, u8 *data,
bool read_shadow_ram)
{
- enum ice_status status;
u32 inlen = *length;
u32 bytes_read = 0;
bool last_cmd;
+ int status;
ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__);
@@ -157,7 +157,7 @@ ice_read_flat_nvm(struct ice_hw *hw, u32 offset, u32 *length, u8 *data,
*
* Update the NVM using the admin queue commands (0x0703)
*/
-enum ice_status
+int
ice_aq_update_nvm(struct ice_hw *hw, u16 module_typeid, u32 offset,
u16 length, void *data, bool last_command, u8 command_flags,
struct ice_sq_cd *cd)
@@ -198,12 +198,11 @@ ice_aq_update_nvm(struct ice_hw *hw, u16 module_typeid, u32 offset,
*
* Erase the NVM sector using the admin queue commands (0x0702)
*/
-enum ice_status
-ice_aq_erase_nvm(struct ice_hw *hw, u16 module_typeid, struct ice_sq_cd *cd)
+int ice_aq_erase_nvm(struct ice_hw *hw, u16 module_typeid, struct ice_sq_cd *cd)
{
struct ice_aq_desc desc;
struct ice_aqc_nvm *cmd;
- enum ice_status status;
+ int status;
__le16 len;
ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__);
@@ -240,13 +239,13 @@ ice_aq_erase_nvm(struct ice_hw *hw, u16 module_typeid, struct ice_sq_cd *cd)
*
* Reads single or multiple feature/field ID and data (0x0704)
*/
-enum ice_status
+int
ice_aq_read_nvm_cfg(struct ice_hw *hw, u8 cmd_flags, u16 field_id, void *data,
u16 buf_size, u16 *elem_count, struct ice_sq_cd *cd)
{
struct ice_aqc_nvm_cfg *cmd;
struct ice_aq_desc desc;
- enum ice_status status;
+ int status;
ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__);
@@ -275,7 +274,7 @@ ice_aq_read_nvm_cfg(struct ice_hw *hw, u8 cmd_flags, u16 field_id, void *data,
*
* Writes single or multiple feature/field ID and data (0x0705)
*/
-enum ice_status
+int
ice_aq_write_nvm_cfg(struct ice_hw *hw, u8 cmd_flags, void *data, u16 buf_size,
u16 elem_count, struct ice_sq_cd *cd)
{
@@ -301,7 +300,7 @@ ice_aq_write_nvm_cfg(struct ice_hw *hw, u8 cmd_flags, void *data, u16 buf_size,
* @offset: offset in words from module start
* @words: number of words to access
*/
-static enum ice_status
+static int
ice_check_sr_access_params(struct ice_hw *hw, u32 offset, u16 words)
{
if ((offset + words) > hw->flash.sr_words) {
@@ -323,7 +322,7 @@ ice_check_sr_access_params(struct ice_hw *hw, u32 offset, u16 words)
return ICE_ERR_PARAM;
}
- return ICE_SUCCESS;
+ return 0;
}
/**
@@ -334,11 +333,11 @@ ice_check_sr_access_params(struct ice_hw *hw, u32 offset, u16 words)
*
* Reads one 16 bit word from the Shadow RAM using ice_read_flat_nvm.
*/
-enum ice_status ice_read_sr_word_aq(struct ice_hw *hw, u16 offset, u16 *data)
+int ice_read_sr_word_aq(struct ice_hw *hw, u16 offset, u16 *data)
{
u32 bytes = sizeof(u16);
- enum ice_status status;
__le16 data_local;
+ int status;
ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__);
@@ -352,7 +351,7 @@ enum ice_status ice_read_sr_word_aq(struct ice_hw *hw, u16 offset, u16 *data)
return status;
*data = LE16_TO_CPU(data_local);
- return ICE_SUCCESS;
+ return 0;
}
/**
@@ -365,11 +364,11 @@ enum ice_status ice_read_sr_word_aq(struct ice_hw *hw, u16 offset, u16 *data)
*
* Writes a 16 bit words buffer to the Shadow RAM using the admin command.
*/
-static enum ice_status
+static int
ice_write_sr_aq(struct ice_hw *hw, u32 offset, u16 words, __le16 *data,
bool last_command)
{
- enum ice_status status;
+ int status;
ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__);
@@ -391,11 +390,11 @@ ice_write_sr_aq(struct ice_hw *hw, u32 offset, u16 words, __le16 *data,
* Reads 16 bit words (data buf) from the Shadow RAM. Ownership of the NVM is
* taken before reading the buffer and later released.
*/
-static enum ice_status
+static int
ice_read_sr_buf_aq(struct ice_hw *hw, u16 offset, u16 *words, u16 *data)
{
u32 bytes = *words * 2, i;
- enum ice_status status;
+ int status;
ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__);
@@ -421,12 +420,11 @@ ice_read_sr_buf_aq(struct ice_hw *hw, u16 offset, u16 *words, u16 *data)
*
* This function will request NVM ownership.
*/
-enum ice_status
-ice_acquire_nvm(struct ice_hw *hw, enum ice_aq_res_access_type access)
+int ice_acquire_nvm(struct ice_hw *hw, enum ice_aq_res_access_type access)
{
ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__);
if (hw->flash.blank_nvm_mode)
- return ICE_SUCCESS;
+ return 0;
return ice_acquire_res(hw, ICE_NVM_RES_ID, access, ICE_NVM_TIMEOUT);
}
@@ -532,11 +530,11 @@ static u32 ice_get_flash_bank_offset(struct ice_hw *hw, enum ice_bank_select ban
* hw->flash.banks data being setup by ice_determine_active_flash_banks()
* during initialization.
*/
-static enum ice_status
+static int
ice_read_flash_module(struct ice_hw *hw, enum ice_bank_select bank, u16 module,
u32 offset, u8 *data, u32 length)
{
- enum ice_status status;
+ int status;
u32 start;
ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__);
@@ -569,11 +567,11 @@ ice_read_flash_module(struct ice_hw *hw, enum ice_bank_select bank, u16 module,
* Read the specified word from the active NVM module. This includes the CSS
* header at the start of the NVM module.
*/
-static enum ice_status
+static int
ice_read_nvm_module(struct ice_hw *hw, enum ice_bank_select bank, u32 offset, u16 *data)
{
- enum ice_status status;
__le16 data_local;
+ int status;
status = ice_read_flash_module(hw, bank, ICE_SR_1ST_NVM_BANK_PTR, offset * sizeof(u16),
(_FORCE_ u8 *)&data_local, sizeof(u16));
@@ -592,13 +590,13 @@ ice_read_nvm_module(struct ice_hw *hw, enum ice_bank_select bank, u32 offset, u1
* Read the CSS header length from the NVM CSS header and add the Authentication
* header size, and then convert to words.
*/
-static enum ice_status
+static int
ice_get_nvm_css_hdr_len(struct ice_hw *hw, enum ice_bank_select bank,
u32 *hdr_len)
{
u16 hdr_len_l, hdr_len_h;
- enum ice_status status;
u32 hdr_len_dword;
+ int status;
status = ice_read_nvm_module(hw, bank, ICE_NVM_CSS_HDR_LEN_L,
&hdr_len_l);
@@ -616,7 +614,7 @@ ice_get_nvm_css_hdr_len(struct ice_hw *hw, enum ice_bank_select bank,
hdr_len_dword = hdr_len_h << 16 | hdr_len_l;
*hdr_len = (hdr_len_dword * 2) + ICE_NVM_AUTH_HEADER_LEN;
- return ICE_SUCCESS;
+ return 0;
}
/**
@@ -629,11 +627,11 @@ ice_get_nvm_css_hdr_len(struct ice_hw *hw, enum ice_bank_select bank,
* Read the specified word from the copy of the Shadow RAM found in the
* specified NVM module.
*/
-static enum ice_status
+static int
ice_read_nvm_sr_copy(struct ice_hw *hw, enum ice_bank_select bank, u32 offset, u16 *data)
{
- enum ice_status status;
u32 hdr_len;
+ int status;
status = ice_get_nvm_css_hdr_len(hw, bank, &hdr_len);
if (status)
@@ -655,11 +653,11 @@ ice_read_nvm_sr_copy(struct ice_hw *hw, enum ice_bank_select bank, u32 offset, u
* Note that unlike the NVM module, the CSS data is stored at the end of the
* module instead of at the beginning.
*/
-static enum ice_status
+static int
ice_read_orom_module(struct ice_hw *hw, enum ice_bank_select bank, u32 offset, u16 *data)
{
- enum ice_status status;
__le16 data_local;
+ int status;
status = ice_read_flash_module(hw, bank, ICE_SR_1ST_OROM_BANK_PTR, offset * sizeof(u16),
(_FORCE_ u8 *)&data_local, sizeof(u16));
@@ -678,11 +676,11 @@ ice_read_orom_module(struct ice_hw *hw, enum ice_bank_select bank, u32 offset, u
*
* Read a word from the specified netlist bank.
*/
-static enum ice_status
+static int
ice_read_netlist_module(struct ice_hw *hw, enum ice_bank_select bank, u32 offset, u16 *data)
{
- enum ice_status status;
__le16 data_local;
+ int status;
status = ice_read_flash_module(hw, bank, ICE_SR_NETLIST_BANK_PTR, offset * sizeof(u16),
(_FORCE_ u8 *)&data_local, sizeof(u16));
@@ -700,9 +698,9 @@ ice_read_netlist_module(struct ice_hw *hw, enum ice_bank_select bank, u32 offset
*
* Reads one 16 bit word from the Shadow RAM using the ice_read_sr_word_aq.
*/
-enum ice_status ice_read_sr_word(struct ice_hw *hw, u16 offset, u16 *data)
+int ice_read_sr_word(struct ice_hw *hw, u16 offset, u16 *data)
{
- enum ice_status status;
+ int status;
status = ice_acquire_nvm(hw, ICE_RES_READ);
if (!status) {
@@ -713,6 +711,8 @@ enum ice_status ice_read_sr_word(struct ice_hw *hw, u16 offset, u16 *data)
return status;
}
+#define check_add_overflow __builtin_add_overflow
+
/**
* ice_get_pfa_module_tlv - Reads sub module TLV from NVM PFA
* @hw: pointer to hardware structure
@@ -724,56 +724,71 @@ enum ice_status ice_read_sr_word(struct ice_hw *hw, u16 offset, u16 *data)
* Area (PFA) and returns the TLV pointer and length. The caller can
* use these to read the variable length TLV value.
*/
-enum ice_status
+int
ice_get_pfa_module_tlv(struct ice_hw *hw, u16 *module_tlv, u16 *module_tlv_len,
u16 module_type)
{
- enum ice_status status;
- u16 pfa_len, pfa_ptr;
- u16 next_tlv;
+ u16 pfa_len, pfa_ptr, next_tlv, max_tlv;
+ int status;
status = ice_read_sr_word(hw, ICE_SR_PFA_PTR, &pfa_ptr);
- if (status != ICE_SUCCESS) {
+ if (status) {
ice_debug(hw, ICE_DBG_INIT, "Preserved Field Array pointer.\n");
return status;
}
status = ice_read_sr_word(hw, pfa_ptr, &pfa_len);
- if (status != ICE_SUCCESS) {
+ if (status) {
ice_debug(hw, ICE_DBG_INIT, "Failed to read PFA length.\n");
return status;
}
- /* Starting with first TLV after PFA length, iterate through the list
+
+ if (check_add_overflow(pfa_ptr, (u16)(pfa_len - 1), &max_tlv)) {
+ ice_debug(hw, ICE_DBG_INIT, "PFA starts at offset %u. PFA length of %u caused 16-bit arithmetic overflow.\n",
+ pfa_ptr, pfa_len);
+ return ICE_ERR_INVAL_SIZE;
+ }
+
+ /* The Preserved Fields Area contains a sequence of TLVs which define
+ * its contents. The PFA length includes all of the TLVs, plus its
+ * initial length word itself, *and* one final word at the end of all
+ * of the TLVs.
+ *
+ * Starting with first TLV after PFA length, iterate through the list
* of TLVs to find the requested one.
*/
next_tlv = pfa_ptr + 1;
- while (next_tlv < pfa_ptr + pfa_len) {
+ while (next_tlv < max_tlv) {
u16 tlv_sub_module_type;
u16 tlv_len;
/* Read TLV type */
- status = ice_read_sr_word(hw, next_tlv, &tlv_sub_module_type);
- if (status != ICE_SUCCESS) {
+ status = ice_read_sr_word(hw, (u16)next_tlv,
+ &tlv_sub_module_type);
+ if (status) {
ice_debug(hw, ICE_DBG_INIT, "Failed to read TLV type.\n");
break;
}
/* Read TLV length */
- status = ice_read_sr_word(hw, next_tlv + 1, &tlv_len);
- if (status != ICE_SUCCESS) {
+ status = ice_read_sr_word(hw, (u16)(next_tlv + 1), &tlv_len);
+ if (status) {
ice_debug(hw, ICE_DBG_INIT, "Failed to read TLV length.\n");
break;
}
if (tlv_sub_module_type == module_type) {
if (tlv_len) {
- *module_tlv = next_tlv;
+ *module_tlv = (u16)next_tlv;
*module_tlv_len = tlv_len;
- return ICE_SUCCESS;
+ return 0;
}
return ICE_ERR_INVAL_SIZE;
}
- /* Check next TLV, i.e. current TLV pointer + length + 2 words
- * (for current TLV's type and length)
- */
- next_tlv = next_tlv + tlv_len + 2;
+
+ if (check_add_overflow(next_tlv, (u16)2, &next_tlv) ||
+ check_add_overflow(next_tlv, tlv_len, &next_tlv)) {
+ ice_debug(hw, ICE_DBG_INIT, "TLV of type %u and length 0x%04x caused 16-bit arithmetic overflow. The PFA starts at 0x%04x and has length of 0x%04x\n",
+ tlv_sub_module_type, tlv_len, pfa_ptr, pfa_len);
+ return ICE_ERR_INVAL_SIZE;
+ }
}
/* Module does not exist */
return ICE_ERR_DOES_NOT_EXIST;
@@ -787,24 +802,23 @@ ice_get_pfa_module_tlv(struct ice_hw *hw, u16 *module_tlv, u16 *module_tlv_len,
*
* Reads the part number string from the NVM.
*/
-enum ice_status
-ice_read_pba_string(struct ice_hw *hw, u8 *pba_num, u32 pba_num_size)
+int ice_read_pba_string(struct ice_hw *hw, u8 *pba_num, u32 pba_num_size)
{
u16 pba_tlv, pba_tlv_len;
- enum ice_status status;
u16 pba_word, pba_size;
+ int status;
u16 i;
status = ice_get_pfa_module_tlv(hw, &pba_tlv, &pba_tlv_len,
ICE_SR_PBA_BLOCK_PTR);
- if (status != ICE_SUCCESS) {
+ if (status) {
ice_debug(hw, ICE_DBG_INIT, "Failed to read PBA Block TLV.\n");
return status;
}
/* pba_size is the next word */
status = ice_read_sr_word(hw, (pba_tlv + 2), &pba_size);
- if (status != ICE_SUCCESS) {
+ if (status) {
ice_debug(hw, ICE_DBG_INIT, "Failed to read PBA Section size.\n");
return status;
}
@@ -825,7 +839,7 @@ ice_read_pba_string(struct ice_hw *hw, u8 *pba_num, u32 pba_num_size)
for (i = 0; i < pba_size; i++) {
status = ice_read_sr_word(hw, (pba_tlv + 2 + 1) + i, &pba_word);
- if (status != ICE_SUCCESS) {
+ if (status) {
ice_debug(hw, ICE_DBG_INIT, "Failed to read PBA Block word %d.\n", i);
return status;
}
@@ -847,10 +861,10 @@ ice_read_pba_string(struct ice_hw *hw, u8 *pba_num, u32 pba_num_size)
* Read the security revision out of the CSS header of the active NVM module
* bank.
*/
-static enum ice_status ice_get_nvm_srev(struct ice_hw *hw, enum ice_bank_select bank, u32 *srev)
+static int ice_get_nvm_srev(struct ice_hw *hw, enum ice_bank_select bank, u32 *srev)
{
- enum ice_status status;
u16 srev_l, srev_h;
+ int status;
status = ice_read_nvm_module(hw, bank, ICE_NVM_CSS_SREV_L, &srev_l);
if (status)
@@ -862,7 +876,7 @@ static enum ice_status ice_get_nvm_srev(struct ice_hw *hw, enum ice_bank_select
*srev = srev_h << 16 | srev_l;
- return ICE_SUCCESS;
+ return 0;
}
/**
@@ -874,11 +888,11 @@ static enum ice_status ice_get_nvm_srev(struct ice_hw *hw, enum ice_bank_select
* Read the NVM EETRACK ID and map version of the main NVM image bank, filling
* in the NVM info structure.
*/
-static enum ice_status
+static int
ice_get_nvm_ver_info(struct ice_hw *hw, enum ice_bank_select bank, struct ice_nvm_info *nvm)
{
u16 eetrack_lo, eetrack_hi, ver;
- enum ice_status status;
+ int status;
status = ice_read_nvm_sr_copy(hw, bank, ICE_SR_NVM_DEV_STARTER_VER, &ver);
if (status) {
@@ -906,7 +920,7 @@ ice_get_nvm_ver_info(struct ice_hw *hw, enum ice_bank_select bank, struct ice_nv
if (status)
ice_debug(hw, ICE_DBG_NVM, "Failed to read NVM security revision.\n");
- return ICE_SUCCESS;
+ return 0;
}
/**
@@ -918,7 +932,7 @@ ice_get_nvm_ver_info(struct ice_hw *hw, enum ice_bank_select bank, struct ice_nv
* inactive NVM bank. Used to access version data for a pending update that
* has not yet been activated.
*/
-enum ice_status ice_get_inactive_nvm_ver(struct ice_hw *hw, struct ice_nvm_info *nvm)
+int ice_get_inactive_nvm_ver(struct ice_hw *hw, struct ice_nvm_info *nvm)
{
return ice_get_nvm_ver_info(hw, ICE_INACTIVE_FLASH_BANK, nvm);
}
@@ -932,13 +946,13 @@ enum ice_status ice_get_inactive_nvm_ver(struct ice_hw *hw, struct ice_nvm_info
* Read the security revision out of the CSS header of the active OROM module
* bank.
*/
-static enum ice_status ice_get_orom_srev(struct ice_hw *hw, enum ice_bank_select bank, u32 *srev)
+static int ice_get_orom_srev(struct ice_hw *hw, enum ice_bank_select bank, u32 *srev)
{
u32 orom_size_word = hw->flash.banks.orom_size / 2;
- enum ice_status status;
u16 srev_l, srev_h;
u32 css_start;
u32 hdr_len;
+ int status;
status = ice_get_nvm_css_hdr_len(hw, bank, &hdr_len);
if (status)
@@ -964,7 +978,7 @@ static enum ice_status ice_get_orom_srev(struct ice_hw *hw, enum ice_bank_select
*srev = srev_h << 16 | srev_l;
- return ICE_SUCCESS;
+ return 0;
}
/**
@@ -976,13 +990,14 @@ static enum ice_status ice_get_orom_srev(struct ice_hw *hw, enum ice_bank_select
* Searches through the Option ROM flash contents to locate the CIVD data for
* the image.
*/
-static enum ice_status
+static int
ice_get_orom_civd_data(struct ice_hw *hw, enum ice_bank_select bank,
struct ice_orom_civd_info *civd)
{
- u8 *orom_data;
- enum ice_status status;
+ struct ice_orom_civd_info civd_data_section;
+ int status;
u32 offset;
+ u32 tmp;
/* The CIVD section is located in the Option ROM aligned to 512 bytes.
* The first 4 bytes must contain the ASCII characters "$CIV".
@@ -993,38 +1008,37 @@ ice_get_orom_civd_data(struct ice_hw *hw, enum ice_bank_select bank,
* usually somewhere in the middle of the bank. We need to scan the
* Option ROM bank to locate it.
*
- * It's significantly faster to read the entire Option ROM up front
- * using the maximum page size, than to read each possible location
- * with a separate firmware command.
*/
- orom_data = (u8 *)ice_calloc(hw, hw->flash.banks.orom_size, sizeof(u8));
- if (!orom_data)
- return ICE_ERR_NO_MEMORY;
-
- status = ice_read_flash_module(hw, bank, ICE_SR_1ST_OROM_BANK_PTR, 0,
- orom_data, hw->flash.banks.orom_size);
- if (status) {
- ice_debug(hw, ICE_DBG_NVM, "Unable to read Option ROM data\n");
- goto exit_error;
- }
/* Scan the memory buffer to locate the CIVD data section */
for (offset = 0; (offset + 512) <= hw->flash.banks.orom_size; offset += 512) {
- struct ice_orom_civd_info *tmp;
u8 sum = 0, i;
- tmp = (struct ice_orom_civd_info *)&orom_data[offset];
+ status = ice_read_flash_module(hw, bank, ICE_SR_1ST_OROM_BANK_PTR,
+ offset, (u8 *)&tmp, sizeof(tmp));
+ if (status) {
+ ice_debug(hw, ICE_DBG_NVM, "Unable to read Option ROM data\n");
+ return status;
+ }
/* Skip forward until we find a matching signature */
- if (memcmp("$CIV", tmp->signature, sizeof(tmp->signature)) != 0)
+ if (memcmp("$CIV", &tmp, sizeof(tmp)) != 0)
continue;
ice_debug(hw, ICE_DBG_NVM, "Found CIVD section at offset %u\n",
offset);
+ status = ice_read_flash_module(hw, bank, ICE_SR_1ST_OROM_BANK_PTR,
+ offset, (u8 *)&civd_data_section,
+ sizeof(civd_data_section));
+ if (status) {
+ ice_debug(hw, ICE_DBG_NVM, "Unable to read CIVD data\n");
+ goto exit_error;
+ }
+
/* Verify that the simple checksum is zero */
- for (i = 0; i < sizeof(*tmp); i++)
- sum += ((u8 *)tmp)[i];
+ for (i = 0; i < sizeof(civd_data_section); i++)
+ sum += ((u8 *)&civd_data_section)[i];
if (sum) {
ice_debug(hw, ICE_DBG_NVM, "Found CIVD data with invalid checksum of %u\n",
@@ -1033,16 +1047,15 @@ ice_get_orom_civd_data(struct ice_hw *hw, enum ice_bank_select bank,
goto exit_error;
}
- *civd = *tmp;
- ice_free(hw, orom_data);
- return ICE_SUCCESS;
+ *civd = civd_data_section;
+
+ return 0;
}
status = ICE_ERR_NVM;
ice_debug(hw, ICE_DBG_NVM, "Unable to locate CIVD data within the Option ROM\n");
exit_error:
- ice_free(hw, orom_data);
return status;
}
@@ -1055,12 +1068,12 @@ exit_error:
* Read Option ROM version and security revision from the Option ROM flash
* section.
*/
-static enum ice_status
+static int
ice_get_orom_ver_info(struct ice_hw *hw, enum ice_bank_select bank, struct ice_orom_info *orom)
{
struct ice_orom_civd_info civd;
- enum ice_status status;
u32 combo_ver;
+ int status;
status = ice_get_orom_civd_data(hw, bank, &civd);
if (status) {
@@ -1080,7 +1093,7 @@ ice_get_orom_ver_info(struct ice_hw *hw, enum ice_bank_select bank, struct ice_o
return status;
}
- return ICE_SUCCESS;
+ return 0;
}
/**
@@ -1092,7 +1105,7 @@ ice_get_orom_ver_info(struct ice_hw *hw, enum ice_bank_select bank, struct ice_o
* section of flash. Used to access version data for a pending update that has
* not yet been activated.
*/
-enum ice_status ice_get_inactive_orom_ver(struct ice_hw *hw, struct ice_orom_info *orom)
+int ice_get_inactive_orom_ver(struct ice_hw *hw, struct ice_orom_info *orom)
{
return ice_get_orom_ver_info(hw, ICE_INACTIVE_FLASH_BANK, orom);
}
@@ -1107,13 +1120,13 @@ enum ice_status ice_get_inactive_orom_ver(struct ice_hw *hw, struct ice_orom_inf
* Topology section to find the Netlist ID block and extract the relevant
* information into the netlist version structure.
*/
-static enum ice_status
+static int
ice_get_netlist_info(struct ice_hw *hw, enum ice_bank_select bank,
struct ice_netlist_info *netlist)
{
u16 module_id, length, node_count, i;
- enum ice_status status;
u16 *id_blk;
+ int status;
status = ice_read_netlist_module(hw, bank, ICE_NETLIST_TYPE_OFFSET, &module_id);
if (status)
@@ -1181,7 +1194,7 @@ exit_error:
*
* Get the netlist version information
*/
-enum ice_status ice_get_netlist_ver_info(struct ice_hw *hw, struct ice_netlist_info *netlist)
+int ice_get_netlist_ver_info(struct ice_hw *hw, struct ice_netlist_info *netlist)
{
return ice_get_netlist_info(hw, ICE_ACTIVE_FLASH_BANK, netlist);
}
@@ -1195,7 +1208,7 @@ enum ice_status ice_get_netlist_ver_info(struct ice_hw *hw, struct ice_netlist_i
* extract version data of a pending flash update in order to display the
* version data.
*/
-enum ice_status ice_get_inactive_netlist_ver(struct ice_hw *hw, struct ice_netlist_info *netlist)
+int ice_get_inactive_netlist_ver(struct ice_hw *hw, struct ice_netlist_info *netlist)
{
return ice_get_netlist_info(hw, ICE_INACTIVE_FLASH_BANK, netlist);
}
@@ -1208,10 +1221,10 @@ enum ice_status ice_get_inactive_netlist_ver(struct ice_hw *hw, struct ice_netli
* the actual size is smaller. Use bisection to determine the accessible size
* of flash memory.
*/
-static enum ice_status ice_discover_flash_size(struct ice_hw *hw)
+static int ice_discover_flash_size(struct ice_hw *hw)
{
u32 min_size = 0, max_size = ICE_AQC_NVM_MAX_OFFSET + 1;
- enum ice_status status;
+ int status;
ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__);
@@ -1229,7 +1242,7 @@ static enum ice_status ice_discover_flash_size(struct ice_hw *hw)
hw->adminq.sq_last_status == ICE_AQ_RC_EINVAL) {
ice_debug(hw, ICE_DBG_NVM, "%s: New upper bound of %u bytes\n",
__func__, offset);
- status = ICE_SUCCESS;
+ status = 0;
max_size = offset;
} else if (!status) {
ice_debug(hw, ICE_DBG_NVM, "%s: New lower bound of %u bytes\n",
@@ -1265,10 +1278,9 @@ err_read_flat_nvm:
* sector size by using the highest bit. The reported pointer value will be in
* bytes, intended for flat NVM reads.
*/
-static enum ice_status
-ice_read_sr_pointer(struct ice_hw *hw, u16 offset, u32 *pointer)
+static int ice_read_sr_pointer(struct ice_hw *hw, u16 offset, u32 *pointer)
{
- enum ice_status status;
+ int status;
u16 value;
status = ice_read_sr_word(hw, offset, &value);
@@ -1281,7 +1293,7 @@ ice_read_sr_pointer(struct ice_hw *hw, u16 offset, u32 *pointer)
else
*pointer = value * 2;
- return ICE_SUCCESS;
+ return 0;
}
/**
@@ -1297,10 +1309,9 @@ ice_read_sr_pointer(struct ice_hw *hw, u16 offset, u32 *pointer)
* Each area size word is specified in 4KB sector units. This function reports
* the size in bytes, intended for flat NVM reads.
*/
-static enum ice_status
-ice_read_sr_area_size(struct ice_hw *hw, u16 offset, u32 *size)
+static int ice_read_sr_area_size(struct ice_hw *hw, u16 offset, u32 *size)
{
- enum ice_status status;
+ int status;
u16 value;
status = ice_read_sr_word(hw, offset, &value);
@@ -1310,7 +1321,7 @@ ice_read_sr_area_size(struct ice_hw *hw, u16 offset, u32 *size)
/* Area sizes are always specified in 4KB units */
*size = value * 4 * 1024;
- return ICE_SUCCESS;
+ return 0;
}
/**
@@ -1323,12 +1334,11 @@ ice_read_sr_area_size(struct ice_hw *hw, u16 offset, u32 *size)
* structure for later use in order to calculate the correct offset to read
* from the active module.
*/
-static enum ice_status
-ice_determine_active_flash_banks(struct ice_hw *hw)
+static int ice_determine_active_flash_banks(struct ice_hw *hw)
{
struct ice_bank_info *banks = &hw->flash.banks;
- enum ice_status status;
u16 ctrl_word;
+ int status;
status = ice_read_sr_word(hw, ICE_SR_NVM_CTRL_WORD, &ctrl_word);
if (status) {
@@ -1393,7 +1403,7 @@ ice_determine_active_flash_banks(struct ice_hw *hw)
return status;
}
- return ICE_SUCCESS;
+ return 0;
}
/**
@@ -1403,12 +1413,12 @@ ice_determine_active_flash_banks(struct ice_hw *hw)
* This function reads and populates NVM settings such as Shadow RAM size,
* max_timeout, and blank_nvm_mode
*/
-enum ice_status ice_init_nvm(struct ice_hw *hw)
+int ice_init_nvm(struct ice_hw *hw)
{
struct ice_flash_info *flash = &hw->flash;
- enum ice_status status;
u32 fla, gens_stat;
u8 sr_size;
+ int status;
ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__);
@@ -1459,7 +1469,7 @@ enum ice_status ice_init_nvm(struct ice_hw *hw)
if (status)
ice_debug(hw, ICE_DBG_INIT, "Failed to read netlist info.\n");
- return ICE_SUCCESS;
+ return 0;
}
/**
@@ -1473,10 +1483,10 @@ enum ice_status ice_init_nvm(struct ice_hw *hw)
* method. The buf read is preceded by the NVM ownership take
* and followed by the release.
*/
-enum ice_status
+int
ice_read_sr_buf(struct ice_hw *hw, u16 offset, u16 *words, u16 *data)
{
- enum ice_status status;
+ int status;
status = ice_acquire_nvm(hw, ICE_RES_READ);
if (!status) {
@@ -1498,7 +1508,7 @@ ice_read_sr_buf(struct ice_hw *hw, u16 offset, u16 *words, u16 *data)
* reception) by caller. To commit SR to NVM update checksum function
* should be called.
*/
-enum ice_status
+int
__ice_write_sr_word(struct ice_hw *hw, u32 offset, const u16 *data)
{
__le16 data_local = CPU_TO_LE16(*data);
@@ -1521,11 +1531,11 @@ __ice_write_sr_word(struct ice_hw *hw, u32 offset, const u16 *data)
* on ARQ completion event reception by caller. To commit SR to NVM update
* checksum function should be called.
*/
-enum ice_status
+int
__ice_write_sr_buf(struct ice_hw *hw, u32 offset, u16 words, const u16 *data)
{
- enum ice_status status;
__le16 *data_local;
+ int status;
void *vmem;
u32 i;
@@ -1559,12 +1569,12 @@ __ice_write_sr_buf(struct ice_hw *hw, u32 offset, u16 words, const u16 *data)
* is customer specific and unknown. Therefore, this function skips all maximum
* possible size of VPD (1kB).
*/
-static enum ice_status ice_calc_sr_checksum(struct ice_hw *hw, u16 *checksum)
+static int ice_calc_sr_checksum(struct ice_hw *hw, u16 *checksum)
{
- enum ice_status status = ICE_SUCCESS;
u16 pcie_alt_module = 0;
u16 checksum_local = 0;
u16 vpd_module;
+ int status = 0;
void *vmem;
u16 *data;
u16 i;
@@ -1596,7 +1606,7 @@ static enum ice_status ice_calc_sr_checksum(struct ice_hw *hw, u16 *checksum)
u16 words = ICE_SR_SECTOR_SIZE_IN_WORDS;
status = ice_read_sr_buf_aq(hw, i, &words, data);
- if (status != ICE_SUCCESS)
+ if (status)
goto ice_calc_sr_checksum_exit;
}
@@ -1630,11 +1640,11 @@ ice_calc_sr_checksum_exit:
* on ARQ completion event reception by caller.
* This function will commit SR to NVM.
*/
-enum ice_status ice_update_sr_checksum(struct ice_hw *hw)
+int ice_update_sr_checksum(struct ice_hw *hw)
{
- enum ice_status status;
__le16 le_sum;
u16 checksum;
+ int status;
ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__);
@@ -1655,11 +1665,11 @@ enum ice_status ice_update_sr_checksum(struct ice_hw *hw)
* Performs checksum calculation and validates the Shadow RAM SW checksum.
* If the caller does not need checksum, the value can be NULL.
*/
-enum ice_status ice_validate_sr_checksum(struct ice_hw *hw, u16 *checksum)
+int ice_validate_sr_checksum(struct ice_hw *hw, u16 *checksum)
{
- enum ice_status status;
u16 checksum_local;
u16 checksum_sr;
+ int status;
ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__);
@@ -1694,11 +1704,11 @@ enum ice_status ice_validate_sr_checksum(struct ice_hw *hw, u16 *checksum)
*
* Verify NVM PFA checksum validity (0x0706)
*/
-enum ice_status ice_nvm_validate_checksum(struct ice_hw *hw)
+int ice_nvm_validate_checksum(struct ice_hw *hw)
{
struct ice_aqc_nvm_checksum *cmd;
struct ice_aq_desc desc;
- enum ice_status status;
+ int status;
status = ice_acquire_nvm(hw, ICE_RES_READ);
if (status)
@@ -1725,11 +1735,11 @@ enum ice_status ice_nvm_validate_checksum(struct ice_hw *hw)
*
* Recalculate NVM PFA checksum (0x0706)
*/
-enum ice_status ice_nvm_recalculate_checksum(struct ice_hw *hw)
+int ice_nvm_recalculate_checksum(struct ice_hw *hw)
{
struct ice_aqc_nvm_checksum *cmd;
struct ice_aq_desc desc;
- enum ice_status status;
+ int status;
status = ice_acquire_nvm(hw, ICE_RES_READ);
if (status)
@@ -1767,12 +1777,11 @@ enum ice_status ice_nvm_recalculate_checksum(struct ice_hw *hw)
* is updated with the flags reported by firmware indicating certain status,
* such as whether EMP reset is enabled.
*/
-enum ice_status
-ice_nvm_write_activate(struct ice_hw *hw, u16 cmd_flags, u8 *response_flags)
+int ice_nvm_write_activate(struct ice_hw *hw, u16 cmd_flags, u8 *response_flags)
{
struct ice_aqc_nvm *cmd;
struct ice_aq_desc desc;
- enum ice_status err;
+ int err;
cmd = &desc.params.nvm;
ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_nvm_write_activate);
@@ -1795,11 +1804,11 @@ ice_nvm_write_activate(struct ice_hw *hw, u16 cmd_flags, u8 *response_flags)
* Read the Minimum Security Revision TLV and extract the revision values from
* the flash image into a readable structure for processing.
*/
-enum ice_status
+int
ice_get_nvm_minsrevs(struct ice_hw *hw, struct ice_minsrev_info *minsrevs)
{
struct ice_aqc_nvm_minsrev data;
- enum ice_status status;
+ int status;
u16 valid;
ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__);
@@ -1840,7 +1849,7 @@ ice_get_nvm_minsrevs(struct ice_hw *hw, struct ice_minsrev_info *minsrevs)
minsrevs->orom_valid = true;
}
- return ICE_SUCCESS;
+ return 0;
}
/**
@@ -1853,11 +1862,11 @@ ice_get_nvm_minsrevs(struct ice_hw *hw, struct ice_minsrev_info *minsrevs)
* fields to determine what update is being requested. If the valid bit is not
* set for that module, then the associated minsrev will be left as is.
*/
-enum ice_status
+int
ice_update_nvm_minsrevs(struct ice_hw *hw, struct ice_minsrev_info *minsrevs)
{
struct ice_aqc_nvm_minsrev data;
- enum ice_status status;
+ int status;
ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__);
@@ -1911,7 +1920,7 @@ exit_release_res:
* Fill in the data section of the NVM access request with a copy of the NVM
* features structure.
*/
-enum ice_status
+int
ice_nvm_access_get_features(struct ice_nvm_access_cmd *cmd,
union ice_nvm_access_data *data)
{
@@ -1932,7 +1941,7 @@ ice_nvm_access_get_features(struct ice_nvm_access_cmd *cmd,
data->drv_features.size = sizeof(struct ice_nvm_features);
data->drv_features.features[0] = ICE_NVM_FEATURES_0_REG_ACCESS;
- return ICE_SUCCESS;
+ return 0;
}
/**
@@ -1977,7 +1986,7 @@ u32 ice_nvm_access_get_adapter(struct ice_nvm_access_cmd *cmd)
* register offset. First validates that the module and flags are correct, and
* then ensures that the register offset is one of the accepted registers.
*/
-static enum ice_status
+static int
ice_validate_nvm_rw_reg(struct ice_nvm_access_cmd *cmd)
{
u32 module, flags, offset;
@@ -2005,18 +2014,18 @@ ice_validate_nvm_rw_reg(struct ice_nvm_access_cmd *cmd)
case GLNVM_GENS:
case GLNVM_FLA:
case PF_FUNC_RID:
- return ICE_SUCCESS;
+ return 0;
default:
break;
}
for (i = 0; i <= GL_HIDA_MAX_INDEX; i++)
if (offset == (u32)GL_HIDA(i))
- return ICE_SUCCESS;
+ return 0;
for (i = 0; i <= GL_HIBA_MAX_INDEX; i++)
if (offset == (u32)GL_HIBA(i))
- return ICE_SUCCESS;
+ return 0;
/* All other register offsets are not valid */
return ICE_ERR_OUT_OF_RANGE;
@@ -2030,11 +2039,11 @@ ice_validate_nvm_rw_reg(struct ice_nvm_access_cmd *cmd)
*
* Process an NVM access request to read a register.
*/
-enum ice_status
+int
ice_nvm_access_read(struct ice_hw *hw, struct ice_nvm_access_cmd *cmd,
union ice_nvm_access_data *data)
{
- enum ice_status status;
+ int status;
ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__);
@@ -2052,7 +2061,7 @@ ice_nvm_access_read(struct ice_hw *hw, struct ice_nvm_access_cmd *cmd,
/* Read the register and store the contents in the data field */
data->regval = rd32(hw, cmd->offset);
- return ICE_SUCCESS;
+ return 0;
}
/**
@@ -2063,11 +2072,11 @@ ice_nvm_access_read(struct ice_hw *hw, struct ice_nvm_access_cmd *cmd,
*
* Process an NVM access request to write a register.
*/
-enum ice_status
+int
ice_nvm_access_write(struct ice_hw *hw, struct ice_nvm_access_cmd *cmd,
union ice_nvm_access_data *data)
{
- enum ice_status status;
+ int status;
ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__);
@@ -2077,21 +2086,24 @@ ice_nvm_access_write(struct ice_hw *hw, struct ice_nvm_access_cmd *cmd,
return status;
/* Reject requests to write to read-only registers */
- switch (cmd->offset) {
- case GL_HICR_EN:
- case GLGEN_RSTAT:
- return ICE_ERR_OUT_OF_RANGE;
- default:
- break;
+ if (hw->mac_type == ICE_MAC_E830) {
+ if (cmd->offset == E830_GL_HICR_EN)
+ return ICE_ERR_OUT_OF_RANGE;
+ } else {
+ if (cmd->offset == GL_HICR_EN)
+ return ICE_ERR_OUT_OF_RANGE;
}
+ if (cmd->offset == GLGEN_RSTAT)
+ return ICE_ERR_OUT_OF_RANGE;
+
ice_debug(hw, ICE_DBG_NVM, "NVM access: writing register %08x with value %08x\n",
cmd->offset, data->regval);
/* Write the data field to the specified register */
wr32(hw, cmd->offset, data->regval);
- return ICE_SUCCESS;
+ return 0;
}
/**
@@ -2107,7 +2119,7 @@ ice_nvm_access_write(struct ice_hw *hw, struct ice_nvm_access_cmd *cmd,
* For valid commands, perform the necessary function, copying the data into
* the provided data buffer.
*/
-enum ice_status
+int
ice_handle_nvm_access(struct ice_hw *hw, struct ice_nvm_access_cmd *cmd,
union ice_nvm_access_data *data)
{
@@ -2146,3 +2158,59 @@ ice_handle_nvm_access(struct ice_hw *hw, struct ice_nvm_access_cmd *cmd,
}
}
+/**
+ * ice_nvm_sanitize_operate - Clear the user data
+ * @hw: pointer to the HW struct
+ *
+ * Clear user data from NVM using AQ command (0x070C).
+ *
+ * Return: the exit code of the operation.
+ */
+s32 ice_nvm_sanitize_operate(struct ice_hw *hw)
+{
+ s32 status;
+ u8 values;
+
+ u8 cmd_flags = ICE_AQ_NVM_SANITIZE_REQ_OPERATE |
+ ICE_AQ_NVM_SANITIZE_OPERATE_SUBJECT_CLEAR;
+
+ status = ice_nvm_sanitize(hw, cmd_flags, &values);
+ if (status)
+ return status;
+ if ((!(values & ICE_AQ_NVM_SANITIZE_OPERATE_HOST_CLEAN_DONE) &&
+ !(values & ICE_AQ_NVM_SANITIZE_OPERATE_BMC_CLEAN_DONE)) ||
+ ((values & ICE_AQ_NVM_SANITIZE_OPERATE_HOST_CLEAN_DONE) &&
+ !(values & ICE_AQ_NVM_SANITIZE_OPERATE_HOST_CLEAN_SUCCESS)) ||
+ ((values & ICE_AQ_NVM_SANITIZE_OPERATE_BMC_CLEAN_DONE) &&
+ !(values & ICE_AQ_NVM_SANITIZE_OPERATE_BMC_CLEAN_SUCCESS)))
+ return ICE_ERR_AQ_ERROR;
+
+ return ICE_SUCCESS;
+}
+
+/**
+ * ice_nvm_sanitize - Sanitize NVM
+ * @hw: pointer to the HW struct
+ * @cmd_flags: flag to the ACI command
+ * @values: values returned from the command
+ *
+ * Sanitize NVM using AQ command (0x070C).
+ *
+ * Return: the exit code of the operation.
+ */
+s32 ice_nvm_sanitize(struct ice_hw *hw, u8 cmd_flags, u8 *values)
+{
+ struct ice_aqc_nvm_sanitization *cmd;
+ struct ice_aq_desc desc;
+ s32 status;
+
+ cmd = &desc.params.sanitization;
+ ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_nvm_sanitization);
+ cmd->cmd_flags = cmd_flags;
+
+ status = ice_aq_send_cmd(hw, &desc, NULL, 0, NULL);
+ if (values)
+ *values = cmd->values;
+
+ return status;
+}