|
@@ -535,10 +535,13 @@ static void ice_reset_subtask(struct ice_pf *pf)
|
|
ice_prepare_for_reset(pf);
|
|
ice_prepare_for_reset(pf);
|
|
|
|
|
|
/* make sure we are ready to rebuild */
|
|
/* make sure we are ready to rebuild */
|
|
- if (ice_check_reset(&pf->hw))
|
|
|
|
|
|
+ if (ice_check_reset(&pf->hw)) {
|
|
set_bit(__ICE_RESET_FAILED, pf->state);
|
|
set_bit(__ICE_RESET_FAILED, pf->state);
|
|
- else
|
|
|
|
|
|
+ } else {
|
|
|
|
+ /* done with reset. start rebuild */
|
|
|
|
+ pf->hw.reset_ongoing = false;
|
|
ice_rebuild(pf);
|
|
ice_rebuild(pf);
|
|
|
|
+ }
|
|
clear_bit(__ICE_RESET_RECOVERY_PENDING, pf->state);
|
|
clear_bit(__ICE_RESET_RECOVERY_PENDING, pf->state);
|
|
goto unlock;
|
|
goto unlock;
|
|
}
|
|
}
|
|
@@ -1754,7 +1757,8 @@ static irqreturn_t ice_misc_intr(int __always_unused irq, void *data)
|
|
* We also make note of which reset happened so that peer
|
|
* We also make note of which reset happened so that peer
|
|
* devices/drivers can be informed.
|
|
* devices/drivers can be informed.
|
|
*/
|
|
*/
|
|
- if (!test_bit(__ICE_RESET_RECOVERY_PENDING, pf->state)) {
|
|
|
|
|
|
+ if (!test_and_set_bit(__ICE_RESET_RECOVERY_PENDING,
|
|
|
|
+ pf->state)) {
|
|
if (reset == ICE_RESET_CORER)
|
|
if (reset == ICE_RESET_CORER)
|
|
set_bit(__ICE_CORER_RECV, pf->state);
|
|
set_bit(__ICE_CORER_RECV, pf->state);
|
|
else if (reset == ICE_RESET_GLOBR)
|
|
else if (reset == ICE_RESET_GLOBR)
|
|
@@ -1762,7 +1766,20 @@ static irqreturn_t ice_misc_intr(int __always_unused irq, void *data)
|
|
else
|
|
else
|
|
set_bit(__ICE_EMPR_RECV, pf->state);
|
|
set_bit(__ICE_EMPR_RECV, pf->state);
|
|
|
|
|
|
- set_bit(__ICE_RESET_RECOVERY_PENDING, pf->state);
|
|
|
|
|
|
+ /* There are couple of different bits at play here.
|
|
|
|
+ * hw->reset_ongoing indicates whether the hardware is
|
|
|
|
+ * in reset. This is set to true when a reset interrupt
|
|
|
|
+ * is received and set back to false after the driver
|
|
|
|
+ * has determined that the hardware is out of reset.
|
|
|
|
+ *
|
|
|
|
+ * __ICE_RESET_RECOVERY_PENDING in pf->state indicates
|
|
|
|
+ * that a post reset rebuild is required before the
|
|
|
|
+ * driver is operational again. This is set above.
|
|
|
|
+ *
|
|
|
|
+ * As this is the start of the reset/rebuild cycle, set
|
|
|
|
+ * both to indicate that.
|
|
|
|
+ */
|
|
|
|
+ hw->reset_ongoing = true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
@@ -4185,7 +4202,14 @@ static int ice_vsi_stop_tx_rings(struct ice_vsi *vsi)
|
|
}
|
|
}
|
|
status = ice_dis_vsi_txq(vsi->port_info, vsi->num_txq, q_ids, q_teids,
|
|
status = ice_dis_vsi_txq(vsi->port_info, vsi->num_txq, q_ids, q_teids,
|
|
NULL);
|
|
NULL);
|
|
- if (status) {
|
|
|
|
|
|
+ /* if the disable queue command was exercised during an active reset
|
|
|
|
+ * flow, ICE_ERR_RESET_ONGOING is returned. This is not an error as
|
|
|
|
+ * the reset operation disables queues at the hardware level anyway.
|
|
|
|
+ */
|
|
|
|
+ if (status == ICE_ERR_RESET_ONGOING) {
|
|
|
|
+ dev_dbg(&pf->pdev->dev,
|
|
|
|
+ "Reset in progress. LAN Tx queues already disabled\n");
|
|
|
|
+ } else if (status) {
|
|
dev_err(&pf->pdev->dev,
|
|
dev_err(&pf->pdev->dev,
|
|
"Failed to disable LAN Tx queues, error: %d\n",
|
|
"Failed to disable LAN Tx queues, error: %d\n",
|
|
status);
|
|
status);
|