On 17.09.2026 11:43, Aleksandr Loktionov wrote:
> diff --git a/drivers/net/ethernet/intel/ice/ice_nvm.c 
> b/drivers/net/ethernet/intel/ice/ice_nvm.c
> index 21f3b61..9ae7de2 100644
> --- a/drivers/net/ethernet/intel/ice/ice_nvm.c
> +++ b/drivers/net/ethernet/intel/ice/ice_nvm.c
> @@ -1105,6 +1105,45 @@ static int ice_determine_css_hdr_len(struct ice_hw *hw)
>       return 0;
>  }
>  
> +/**
> + * ice_parse_erot_presence - detect eRoT and populate hw->erot_present
> + * @hw: pointer to the HW struct
> + *
> + * Uses the device capability LIBIE_AQC_CAPS_EXTERNAL_PQC_ROT_PRESENT when
> + * advertised by firmware, falling back to the eRoT Presence fuse only when
> + * the capability is not advertised at all (older firmware).
> + *
> + * Priority:
> + *  1. Device capability external_pqc_rot_present (advertised && == 1)
> + *     => eRoT present
> + *  2. Fuse BIT(0) set (only when capability not advertised)
> + *     => eRoT present
> + *  3. Otherwise => eRoT not present
> + */
> +void ice_parse_erot_presence(struct ice_hw *hw)
> +{
> +     u16 fuse = 0;
> +     int err;
> +
> +     hw->erot_present = false;
> +
> +     if (hw->dev_caps.common_cap.external_pqc_rot_present) {
> +             hw->erot_present = true;
> +     } else if 
> (!hw->dev_caps.common_cap.external_pqc_rot_present_cap_advertised) {
> +             err = ice_read_sr_word(hw, ICE_SR_EROT_PRESENCE_FUSE, &fuse);
> +             if (err)

On a read failure the code assumes erot_present = false, i.e. fails open on a 
mechanism whose whole purpose is preventing bricking from partial updates. A 
transient SR read failure on real eRoT hardware silently disables the guard in 
patch 2. Consider treating a read failure as erot_present = true instead, or 
justify why fail-open is safe here.

> +                     dev_warn(ice_hw_to_dev(hw),
> +                              "Unable to read eRoT presence fuse (SR 
> 0x%04x), err %d; assuming eRoT not present\n",
> +                              ICE_SR_EROT_PRESENCE_FUSE, err);
> +             else if (fuse & ICE_EROT_PRESENCE_FUSE_PRESENT)
> +                     hw->erot_present = true;
> +     }
> +
> +     if (hw->erot_present)
> +             dev_info(ice_hw_to_dev(hw),
> +                      "eRoT (external Root of Trust) present\n");
> +}
> +
>  /**
>   * ice_init_nvm - initializes NVM setting
>   * @hw: pointer to the HW struct
> diff --git a/drivers/net/ethernet/intel/ice/ice_nvm.h 
> b/drivers/net/ethernet/intel/ice/ice_nvm.h
> index e1d1a11..4b31dfc 100644
> --- a/drivers/net/ethernet/intel/ice/ice_nvm.h
> +++ b/drivers/net/ethernet/intel/ice/ice_nvm.h
> @@ -28,7 +28,12 @@ int ice_get_inactive_nvm_ver(struct ice_hw *hw, struct 
> ice_nvm_info *nvm);
>  int
>  ice_get_inactive_netlist_ver(struct ice_hw *hw, struct ice_netlist_info 
> *netlist);
>  int ice_read_pba_string(struct ice_hw *hw, u8 *pba_num, u32 pba_num_size);
> +/* eRoT Presence fuse SR offset; BIT(0) set means eRoT present */
> +#define ICE_SR_EROT_PRESENCE_FUSE    0x1016
> +#define ICE_EROT_PRESENCE_FUSE_PRESENT       BIT(0)

Commit message and function doc describe the fuse as "bits[1:0]", but only bit 
0 is checked/masked. Please confirm with the fuse spec whether bit 1 is truly 
unused, or whether this needs GENMASK(1,0) with a specific expected value.

> +
>  int ice_init_nvm(struct ice_hw *hw);
> +void ice_parse_erot_presence(struct ice_hw *hw);
>  int ice_read_sr_word(struct ice_hw *hw, u16 offset, u16 *data);
>  int
>  ice_aq_update_nvm(struct ice_hw *hw, u16 module_typeid, u32 offset,


Reply via email to