public inbox for netdev@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH iwl-next v1] ixgbe: fix eeprom_id staleness and non-fatal EMPR reload failure
@ 2026-03-20  5:14 Aleksandr Loktionov
  2026-03-27 10:10 ` Simon Horman
  0 siblings, 1 reply; 2+ messages in thread
From: Aleksandr Loktionov @ 2026-03-20  5:14 UTC (permalink / raw)
  To: intel-wired-lan, anthony.l.nguyen, aleksandr.loktionov; +Cc: netdev

Three related bugs around FW version reporting after EMPR reset on E610:

1. ixgbe_refresh_fw_version() silently discarded the error return from
   ixgbe_get_flash_data(), so a failed NVM re-read left adapter->eeprom_id
   with whatever stale data it held before the reset.  Propagate the error
   and set eeprom_id to "unknown" on failure so that ethtool -i and
   devlink dev info never show a version that no longer reflects reality.

2. ixgbe_devlink_reload_empr_finish() returned 0 without ever refreshing
   the FW version after the EMPR completed.  Add the refresh call, but
   treat it as best-effort: a failure to re-read flash does not mean the
   EMPR itself failed.  Log a netdev_warn() and return 0 so devlink
   reports the correct reload outcome.

3. ixgbe_reinit_locked() never refreshed the FW version for E610.
   Because E610 has no FW event that notifies peer PFs when an EMPR
   triggered by another PF's devlink reload completes, any PF that
   subsequently goes through reinit would keep stale data in hw->flash
   and adapter->eeprom_id.  Add the same best-effort refresh here,
   gated on ixgbe_mac_e610, with a netdev_warn() on failure.

Signed-off-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
---
 .../ethernet/intel/ixgbe/devlink/devlink.c    | 25 ++++++++++++++++---
 drivers/net/ethernet/intel/ixgbe/ixgbe.h      |  2 +-
 .../net/ethernet/intel/ixgbe/ixgbe_ethtool.c  | 22 ++++++++++++++--
 drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 15 +++++++++++
 4 files changed, 57 insertions(+), 7 deletions(-)

diff --git a/drivers/net/ethernet/intel/ixgbe/devlink/devlink.c b/drivers/net/ethernet/intel/ixgbe/devlink/devlink.c
index b0404f3..4581605 100644
--- a/drivers/net/ethernet/intel/ixgbe/devlink/devlink.c
+++ b/drivers/net/ethernet/intel/ixgbe/devlink/devlink.c
@@ -322,8 +322,13 @@ static int ixgbe_devlink_info_get(struct devlink *devlink,
 	if (!ctx)
 		return -ENOMEM;
 
-	if (hw->mac.type == ixgbe_mac_e610)
-		ixgbe_refresh_fw_version(adapter);
+	if (hw->mac.type == ixgbe_mac_e610) {
+		err = ixgbe_refresh_fw_version(adapter);
+		if (err)
+			netdev_warn(adapter->netdev,
+				    "Failed to refresh FW version for devlink info: %d\n",
+				    err);
+	}
 
 	ixgbe_info_get_dsn(adapter, ctx);
 	err = devlink_info_serial_number_put(req, ctx->buf);
@@ -442,7 +447,9 @@ static int ixgbe_devlink_reload_empr_start(struct devlink *devlink,
  *
  * Wait for new NVM to be loaded during EMP reset.
  *
- * Return: -ETIME when timer is exceeded, 0 on success.
+ * Return: -ETIME when timer is exceeded, 0 on success. A failure to re-read
+ * the FW version after the reset completes is non-fatal and does not cause
+ * this function to return an error.
  */
 static int ixgbe_devlink_reload_empr_finish(struct devlink *devlink,
 					    enum devlink_reload_action action,
@@ -452,7 +459,7 @@ static int ixgbe_devlink_reload_empr_finish(struct devlink *devlink,
 {
 	struct ixgbe_adapter *adapter = devlink_priv(devlink);
 	struct ixgbe_hw *hw = &adapter->hw;
-	int i = 0;
+	int i = 0, err;
 	u32 fwsm;
 
 	do {
@@ -474,6 +481,16 @@ static int ixgbe_devlink_reload_empr_finish(struct devlink *devlink,
 	adapter->flags2 &= ~(IXGBE_FLAG2_API_MISMATCH |
 			     IXGBE_FLAG2_FW_ROLLBACK);
 
+	/* Re-reading the FW version is best-effort; the EMPR itself completed
+	 * successfully.  Log any failure so the user knows eeprom_id has been
+	 * reset to "unknown".
+	 */
+	err = ixgbe_refresh_fw_version(adapter);
+	if (err)
+		netdev_warn(adapter->netdev,
+			    "Failed to refresh FW version after EMPR: %d\n",
+			    err);
+
 	return 0;
 }
 
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe.h b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
index 59a1cee4..9b82175 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe.h
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
@@ -974,7 +974,7 @@ int ixgbe_init_interrupt_scheme(struct ixgbe_adapter *adapter);
 bool ixgbe_wol_supported(struct ixgbe_adapter *adapter, u16 device_id,
 			 u16 subdevice_id);
 void ixgbe_set_fw_version_e610(struct ixgbe_adapter *adapter);
-void ixgbe_refresh_fw_version(struct ixgbe_adapter *adapter);
+int ixgbe_refresh_fw_version(struct ixgbe_adapter *adapter);
 #ifdef CONFIG_PCI_IOV
 void ixgbe_full_sync_mac_table(struct ixgbe_adapter *adapter);
 #endif
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c
index 56aabaa..40d593b 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c
@@ -1155,12 +1155,30 @@ static int ixgbe_set_eeprom(struct net_device *netdev,
 	return ret_val;
 }
 
-void ixgbe_refresh_fw_version(struct ixgbe_adapter *adapter)
+/**
+ * ixgbe_refresh_fw_version - re-read flash data and update eeprom_id cache
+ * @adapter: board private structure
+ *
+ * Re-reads the NVM/flash and refreshes the cached adapter->eeprom_id string.
+ * On failure the cache is set to "unknown" so that ethtool -i never shows a
+ * stale version string after a failed reset.
+ *
+ * Return: 0 on success, negative error code on failure.
+ */
+int ixgbe_refresh_fw_version(struct ixgbe_adapter *adapter)
 {
 	struct ixgbe_hw *hw = &adapter->hw;
+	int err;
+
+	err = ixgbe_get_flash_data(hw);
+	if (err) {
+		strscpy(adapter->eeprom_id, "unknown",
+			sizeof(adapter->eeprom_id));
+		return err;
+	}
 
-	ixgbe_get_flash_data(hw);
 	ixgbe_set_fw_version_e610(adapter);
+	return 0;
 }
 
 static void ixgbe_get_drvinfo(struct net_device *netdev,
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index 0bc806a..d209cfc 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -6289,6 +6289,21 @@ void ixgbe_reinit_locked(struct ixgbe_adapter *adapter)
 	if (adapter->flags & IXGBE_FLAG_SRIOV_ENABLED)
 		msleep(2000);
 	ixgbe_up(adapter);
+
+	/* E610 has no FW event to notify peer PFs that an EMPR reset occurred.
+	 * Refresh the cached FW version here so that a PF completing reinit
+	 * after an EMPR triggered by another PF's devlink reload picks up the
+	 * new version in adapter->eeprom_id.
+	 */
+	if (adapter->hw.mac.type == ixgbe_mac_e610) {
+		int err = ixgbe_refresh_fw_version(adapter);
+
+		if (err)
+			netdev_warn(adapter->netdev,
+				    "Failed to refresh FW version after reset: %d\n",
+				    err);
+	}
+
 	clear_bit(__IXGBE_RESETTING, &adapter->state);
 }
 
-- 
2.52.0


^ permalink raw reply related	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2026-03-27 10:10 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-03-20  5:14 [PATCH iwl-next v1] ixgbe: fix eeprom_id staleness and non-fatal EMPR reload failure Aleksandr Loktionov
2026-03-27 10:10 ` Simon Horman

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox