]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
ixgbe: add support for FW rollback mode
authorAndrii Staikov <andrii.staikov@intel.com>
Thu, 10 Apr 2025 13:00:08 +0000 (15:00 +0200)
committerTony Nguyen <anthony.l.nguyen@intel.com>
Tue, 15 Apr 2025 14:36:33 +0000 (07:36 -0700)
The driver should detect whether the device entered FW rollback
mode and then notify user with the dedicated message including
FW and NVM versions.

Even if the driver detected rollback mode, this should not result
in an probe error and the normal flow proceeds.

FW tries to rollback to "old" operational FW located in the
inactive NVM bank in cases when newly loaded FW exhibits faulty
behavior. If something goes wrong during boot the FW may switch
into rollback mode in an attempt to avoid recovery mode and stay
operational. After rollback is successful, the banks are swapped,
and the "rollback" bank becomes the active bank for the next reset.

Reviewed-by: Mateusz Polchlopek <mateusz.polchlopek@intel.com>
Signed-off-by: Andrii Staikov <andrii.staikov@intel.com>
Signed-off-by: Jedrzej Jagielski <jedrzej.jagielski@intel.com>
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
drivers/net/ethernet/intel/ixgbe/devlink/devlink.c
drivers/net/ethernet/intel/ixgbe/ixgbe.h
drivers/net/ethernet/intel/ixgbe/ixgbe_e610.c
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
drivers/net/ethernet/intel/ixgbe/ixgbe_type.h
drivers/net/ethernet/intel/ixgbe/ixgbe_type_e610.h

index 3e79e446a9449e61d36c3501f6b016723faff5a4..54f1b83dfe42e02b341c4a9d3bbf9a852205ede1 100644 (file)
@@ -471,7 +471,8 @@ static int ixgbe_devlink_reload_empr_finish(struct devlink *devlink,
 
        *actions_performed = BIT(DEVLINK_RELOAD_ACTION_FW_ACTIVATE);
 
-       adapter->flags2 &= ~IXGBE_FLAG2_API_MISMATCH;
+       adapter->flags2 &= ~(IXGBE_FLAG2_API_MISMATCH |
+                            IXGBE_FLAG2_FW_ROLLBACK);
 
        return 0;
 }
index 2246997bc9fb4583043e822c6d365cf6950ace4a..23c2e2c2649ceffeba1e5ef99d2602257ff41172 100644 (file)
@@ -672,6 +672,7 @@ struct ixgbe_adapter {
 #define IXGBE_FLAG2_NO_MEDIA                   BIT(21)
 #define IXGBE_FLAG2_MOD_POWER_UNSUPPORTED      BIT(22)
 #define IXGBE_FLAG2_API_MISMATCH               BIT(23)
+#define IXGBE_FLAG2_FW_ROLLBACK                        BIT(24)
 
        /* Tx fast path data */
        int num_tx_queues;
index 58deb89beb75ed2efed03a039160c386d6486469..9ada35f7d8f76ba8c0f1f0d8d3de0f36472e972b 100644 (file)
@@ -1832,6 +1832,22 @@ static bool ixgbe_fw_recovery_mode_e610(struct ixgbe_hw *hw)
        return !!(fwsm & IXGBE_GL_MNG_FWSM_RECOVERY_M);
 }
 
+/**
+ * ixgbe_fw_rollback_mode_e610 - Check FW NVM rollback mode
+ * @hw: pointer to hardware structure
+ *
+ * Check FW NVM rollback mode by reading the value of
+ * the dedicated register.
+ *
+ * Return: true if FW is in rollback mode, otherwise false.
+ */
+static bool ixgbe_fw_rollback_mode_e610(struct ixgbe_hw *hw)
+{
+       u32 fwsm = IXGBE_READ_REG(hw, IXGBE_GL_MNG_FWSM);
+
+       return !!(fwsm & IXGBE_GL_MNG_FWSM_ROLLBACK_M);
+}
+
 /**
  * ixgbe_init_phy_ops_e610 - PHY specific init
  * @hw: pointer to hardware structure
@@ -3163,6 +3179,22 @@ int ixgbe_get_inactive_nvm_ver(struct ixgbe_hw *hw, struct ixgbe_nvm_info *nvm)
        return ixgbe_get_nvm_ver_info(hw, IXGBE_INACTIVE_FLASH_BANK, nvm);
 }
 
+/**
+ * ixgbe_get_active_nvm_ver - Read Option ROM version from the active bank
+ * @hw: pointer to the HW structure
+ * @nvm: storage for Option ROM version information
+ *
+ * Reads the NVM EETRACK ID, Map version, and security revision of the
+ * active NVM bank.
+ *
+ * Return: the exit code of the operation.
+ */
+static int ixgbe_get_active_nvm_ver(struct ixgbe_hw *hw,
+                                   struct ixgbe_nvm_info *nvm)
+{
+       return ixgbe_get_nvm_ver_info(hw, IXGBE_ACTIVE_FLASH_BANK, nvm);
+}
+
 /**
  * ixgbe_get_netlist_info - Read the netlist version information
  * @hw: pointer to the HW struct
@@ -3893,6 +3925,8 @@ static const struct ixgbe_mac_operations mac_ops_e610 = {
        .get_media_type                 = ixgbe_get_media_type_e610,
        .setup_link                     = ixgbe_setup_link_e610,
        .fw_recovery_mode               = ixgbe_fw_recovery_mode_e610,
+       .fw_rollback_mode               = ixgbe_fw_rollback_mode_e610,
+       .get_nvm_ver                    = ixgbe_get_active_nvm_ver,
        .get_link_capabilities          = ixgbe_get_link_capabilities_e610,
        .get_bus_info                   = ixgbe_get_bus_info_generic,
        .acquire_swfw_sync              = ixgbe_acquire_swfw_sync_X540,
index 1c69f58466fdca9bb42cf1ff4edb444be81db472..cdfafc477ee0d6258292915b272adc36694ddfca 100644 (file)
@@ -8424,6 +8424,32 @@ static bool ixgbe_check_fw_error(struct ixgbe_adapter *adapter)
                        return true;
        }
 
+       /* return here if FW rollback mode has been already detected */
+       if (adapter->flags2 & IXGBE_FLAG2_FW_ROLLBACK)
+               return false;
+
+       if (hw->mac.ops.fw_rollback_mode && hw->mac.ops.fw_rollback_mode(hw)) {
+               struct ixgbe_nvm_info *nvm_info = &adapter->hw.flash.nvm;
+               char ver_buff[64] = "";
+
+               if (hw->mac.ops.get_fw_ver && hw->mac.ops.get_fw_ver(hw))
+                       goto no_version;
+
+               if (hw->mac.ops.get_nvm_ver &&
+                   hw->mac.ops.get_nvm_ver(hw, nvm_info))
+                       goto no_version;
+
+               snprintf(ver_buff, sizeof(ver_buff),
+                        "Current version is NVM:%x.%x.%x, FW:%d.%d. ",
+                        nvm_info->major, nvm_info->minor, nvm_info->eetrack,
+                        hw->fw_maj_ver, hw->fw_maj_ver);
+no_version:
+               e_dev_warn("Firmware rollback mode detected. %sDevice may exhibit limited functionality. Refer to the Intel(R) Ethernet Adapters and Devices User Guide for details on firmware rollback mode.",
+                          ver_buff);
+
+               adapter->flags2 |= IXGBE_FLAG2_FW_ROLLBACK;
+       }
+
        return false;
 }
 
index 6bf6ba7dcdccd9e9e9c76f1b462e6d6d179af114..892fa6c1f87974de99094c6e3b26ac56bd2727fa 100644 (file)
@@ -3525,6 +3525,8 @@ struct ixgbe_mac_operations {
        int (*get_thermal_sensor_data)(struct ixgbe_hw *);
        int (*init_thermal_sensor_thresh)(struct ixgbe_hw *hw);
        bool (*fw_recovery_mode)(struct ixgbe_hw *hw);
+       bool (*fw_rollback_mode)(struct ixgbe_hw *hw);
+       int (*get_nvm_ver)(struct ixgbe_hw *hw, struct ixgbe_nvm_info *nvm);
        void (*disable_rx)(struct ixgbe_hw *hw);
        void (*enable_rx)(struct ixgbe_hw *hw);
        void (*set_source_address_pruning)(struct ixgbe_hw *, bool,
index c035ac787b6c975d6ab663aa5c7a5c8a2a41294c..bea94e5ccb730a7f0a15075ac18dac72a0c04945 100644 (file)
@@ -90,6 +90,7 @@
 
 #define IXGBE_GL_MNG_FWSM              0x000B6134 /* Reset Source: POR */
 #define IXGBE_GL_MNG_FWSM_RECOVERY_M   BIT(1)
+#define IXGBE_GL_MNG_FWSM_ROLLBACK_M    BIT(2)
 
 /* Flash Access Register */
 #define IXGBE_GLNVM_FLA                        0x000B6108 /* Reset Source: POR */