Skip to content

Commit cfa747a

Browse files
jacob-kellerkuba-moo
authored andcommitted
ice: fix reads from NVM Shadow RAM on E830 and E825-C devices
The ice driver reads data from the Shadow RAM portion of the NVM during initialization, including data used to identify the NVM image and device, such as the ETRACK ID used to populate devlink dev info fw.bundle. Currently it is using a fixed offset defined by ICE_CSS_HEADER_LENGTH to compute the appropriate offset. This worked fine for E810 and E822 devices which both have CSS header length of 330 words. Other devices, including both E825-C and E830 devices have different sizes for their CSS header. The use of a hard coded value results in the driver reading from the wrong block in the NVM when attempting to access the Shadow RAM copy. This results in the driver reporting the fw.bundle as 0x0 in both the devlink dev info and ethtool -i output. The first E830 support was introduced by commit ba20ecb ("ice: Hook up 4 E830 devices by adding their IDs") and the first E825-C support was introducted by commit f64e189 ("ice: introduce new E825C devices family") The NVM actually contains the CSS header length embedded in it. Remove the hard coded value and replace it with logic to read the length from the NVM directly. This is more resilient against all existing and future hardware, vs looking up the expected values from a table. It ensures the driver will read from the appropriate place when determining the ETRACK ID value used for populating the fw.bundle_id and for reporting in ethtool -i. The CSS header length for both the active and inactive flash bank is stored in the ice_bank_info structure to avoid unnecessary duplicate work when accessing multiple words of the Shadow RAM. Both banks are read in the unlikely event that the header length is different for the NVM in the inactive bank, rather than being different only by the overall device family. Fixes: ba20ecb ("ice: Hook up 4 E830 devices by adding their IDs") Co-developed-by: Paul Greenwalt <paul.greenwalt@intel.com> Signed-off-by: Paul Greenwalt <paul.greenwalt@intel.com> Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com> Tested-by: Pucha Himasekhar Reddy <himasekharx.reddy.pucha@intel.com> Signed-off-by: Jacob Keller <jacob.e.keller@intel.com> Link: https://lore.kernel.org/r/20240603-net-2024-05-30-intel-net-fixes-v2-2-e3563aa89b0c@intel.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
1 parent 03e4a09 commit cfa747a

File tree

2 files changed

+93
-9
lines changed

2 files changed

+93
-9
lines changed

drivers/net/ethernet/intel/ice/ice_nvm.c

Lines changed: 87 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -374,11 +374,25 @@ ice_read_nvm_module(struct ice_hw *hw, enum ice_bank_select bank, u32 offset, u1
374374
*
375375
* Read the specified word from the copy of the Shadow RAM found in the
376376
* specified NVM module.
377+
*
378+
* Note that the Shadow RAM copy is always located after the CSS header, and
379+
* is aligned to 64-byte (32-word) offsets.
377380
*/
378381
static int
379382
ice_read_nvm_sr_copy(struct ice_hw *hw, enum ice_bank_select bank, u32 offset, u16 *data)
380383
{
381-
return ice_read_nvm_module(hw, bank, ICE_NVM_SR_COPY_WORD_OFFSET + offset, data);
384+
u32 sr_copy;
385+
386+
switch (bank) {
387+
case ICE_ACTIVE_FLASH_BANK:
388+
sr_copy = roundup(hw->flash.banks.active_css_hdr_len, 32);
389+
break;
390+
case ICE_INACTIVE_FLASH_BANK:
391+
sr_copy = roundup(hw->flash.banks.inactive_css_hdr_len, 32);
392+
break;
393+
}
394+
395+
return ice_read_nvm_module(hw, bank, sr_copy + offset, data);
382396
}
383397

384398
/**
@@ -1023,6 +1037,72 @@ static int ice_determine_active_flash_banks(struct ice_hw *hw)
10231037
return 0;
10241038
}
10251039

1040+
/**
1041+
* ice_get_nvm_css_hdr_len - Read the CSS header length from the NVM CSS header
1042+
* @hw: pointer to the HW struct
1043+
* @bank: whether to read from the active or inactive flash bank
1044+
* @hdr_len: storage for header length in words
1045+
*
1046+
* Read the CSS header length from the NVM CSS header and add the Authentication
1047+
* header size, and then convert to words.
1048+
*
1049+
* Return: zero on success, or a negative error code on failure.
1050+
*/
1051+
static int
1052+
ice_get_nvm_css_hdr_len(struct ice_hw *hw, enum ice_bank_select bank,
1053+
u32 *hdr_len)
1054+
{
1055+
u16 hdr_len_l, hdr_len_h;
1056+
u32 hdr_len_dword;
1057+
int status;
1058+
1059+
status = ice_read_nvm_module(hw, bank, ICE_NVM_CSS_HDR_LEN_L,
1060+
&hdr_len_l);
1061+
if (status)
1062+
return status;
1063+
1064+
status = ice_read_nvm_module(hw, bank, ICE_NVM_CSS_HDR_LEN_H,
1065+
&hdr_len_h);
1066+
if (status)
1067+
return status;
1068+
1069+
/* CSS header length is in DWORD, so convert to words and add
1070+
* authentication header size
1071+
*/
1072+
hdr_len_dword = hdr_len_h << 16 | hdr_len_l;
1073+
*hdr_len = (hdr_len_dword * 2) + ICE_NVM_AUTH_HEADER_LEN;
1074+
1075+
return 0;
1076+
}
1077+
1078+
/**
1079+
* ice_determine_css_hdr_len - Discover CSS header length for the device
1080+
* @hw: pointer to the HW struct
1081+
*
1082+
* Determine the size of the CSS header at the start of the NVM module. This
1083+
* is useful for locating the Shadow RAM copy in the NVM, as the Shadow RAM is
1084+
* always located just after the CSS header.
1085+
*
1086+
* Return: zero on success, or a negative error code on failure.
1087+
*/
1088+
static int ice_determine_css_hdr_len(struct ice_hw *hw)
1089+
{
1090+
struct ice_bank_info *banks = &hw->flash.banks;
1091+
int status;
1092+
1093+
status = ice_get_nvm_css_hdr_len(hw, ICE_ACTIVE_FLASH_BANK,
1094+
&banks->active_css_hdr_len);
1095+
if (status)
1096+
return status;
1097+
1098+
status = ice_get_nvm_css_hdr_len(hw, ICE_INACTIVE_FLASH_BANK,
1099+
&banks->inactive_css_hdr_len);
1100+
if (status)
1101+
return status;
1102+
1103+
return 0;
1104+
}
1105+
10261106
/**
10271107
* ice_init_nvm - initializes NVM setting
10281108
* @hw: pointer to the HW struct
@@ -1069,6 +1149,12 @@ int ice_init_nvm(struct ice_hw *hw)
10691149
return status;
10701150
}
10711151

1152+
status = ice_determine_css_hdr_len(hw);
1153+
if (status) {
1154+
ice_debug(hw, ICE_DBG_NVM, "Failed to determine Shadow RAM copy offsets.\n");
1155+
return status;
1156+
}
1157+
10721158
status = ice_get_nvm_ver_info(hw, ICE_ACTIVE_FLASH_BANK, &flash->nvm);
10731159
if (status) {
10741160
ice_debug(hw, ICE_DBG_INIT, "Failed to read NVM info.\n");

drivers/net/ethernet/intel/ice/ice_type.h

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -482,6 +482,8 @@ struct ice_bank_info {
482482
u32 orom_size; /* Size of OROM bank */
483483
u32 netlist_ptr; /* Pointer to 1st Netlist bank */
484484
u32 netlist_size; /* Size of Netlist bank */
485+
u32 active_css_hdr_len; /* Active CSS header length */
486+
u32 inactive_css_hdr_len; /* Inactive CSS header length */
485487
enum ice_flash_bank nvm_bank; /* Active NVM bank */
486488
enum ice_flash_bank orom_bank; /* Active OROM bank */
487489
enum ice_flash_bank netlist_bank; /* Active Netlist bank */
@@ -1087,17 +1089,13 @@ struct ice_aq_get_set_rss_lut_params {
10871089
#define ICE_SR_SECTOR_SIZE_IN_WORDS 0x800
10881090

10891091
/* CSS Header words */
1092+
#define ICE_NVM_CSS_HDR_LEN_L 0x02
1093+
#define ICE_NVM_CSS_HDR_LEN_H 0x03
10901094
#define ICE_NVM_CSS_SREV_L 0x14
10911095
#define ICE_NVM_CSS_SREV_H 0x15
10921096

1093-
/* Length of CSS header section in words */
1094-
#define ICE_CSS_HEADER_LENGTH 330
1095-
1096-
/* Offset of Shadow RAM copy in the NVM bank area. */
1097-
#define ICE_NVM_SR_COPY_WORD_OFFSET roundup(ICE_CSS_HEADER_LENGTH, 32)
1098-
1099-
/* Size in bytes of Option ROM trailer */
1100-
#define ICE_NVM_OROM_TRAILER_LENGTH (2 * ICE_CSS_HEADER_LENGTH)
1097+
/* Length of Authentication header section in words */
1098+
#define ICE_NVM_AUTH_HEADER_LEN 0x08
11011099

11021100
/* The Link Topology Netlist section is stored as a series of words. It is
11031101
* stored in the NVM as a TLV, with the first two words containing the type

0 commit comments

Comments
 (0)