mirror of
https://github.com/torvalds/linux.git
synced 2024-11-24 21:21:41 +00:00
bnxt_en: fix error path of FW reset
When bnxt_open() fails in the firmware reset path, the driver needs to
gracefully abort, but it is executing code that should be invoked only
in the success path. Define a function to abort FW reset and
consolidate all error paths to call this new function.
Fixes: dab62e7c2d
("bnxt_en: Implement faster recovery for firmware fatal error.")
Signed-off-by: Somnath Kotur <somnath.kotur@broadcom.com>
Signed-off-by: Michael Chan <michael.chan@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
6cd657cb3e
commit
3958b1da72
@ -11959,10 +11959,21 @@ static bool bnxt_fw_reset_timeout(struct bnxt *bp)
|
||||
(bp->fw_reset_max_dsecs * HZ / 10));
|
||||
}
|
||||
|
||||
static void bnxt_fw_reset_abort(struct bnxt *bp, int rc)
|
||||
{
|
||||
clear_bit(BNXT_STATE_IN_FW_RESET, &bp->state);
|
||||
if (bp->fw_reset_state != BNXT_FW_RESET_STATE_POLL_VF) {
|
||||
bnxt_ulp_start(bp, rc);
|
||||
bnxt_dl_health_status_update(bp, false);
|
||||
}
|
||||
bp->fw_reset_state = 0;
|
||||
dev_close(bp->dev);
|
||||
}
|
||||
|
||||
static void bnxt_fw_reset_task(struct work_struct *work)
|
||||
{
|
||||
struct bnxt *bp = container_of(work, struct bnxt, fw_reset_task.work);
|
||||
int rc;
|
||||
int rc = 0;
|
||||
|
||||
if (!test_bit(BNXT_STATE_IN_FW_RESET, &bp->state)) {
|
||||
netdev_err(bp->dev, "bnxt_fw_reset_task() called when not in fw reset mode!\n");
|
||||
@ -11993,8 +12004,9 @@ static void bnxt_fw_reset_task(struct work_struct *work)
|
||||
bp->fw_reset_timestamp = jiffies;
|
||||
rtnl_lock();
|
||||
if (test_bit(BNXT_STATE_ABORT_ERR, &bp->state)) {
|
||||
bnxt_fw_reset_abort(bp, rc);
|
||||
rtnl_unlock();
|
||||
goto fw_reset_abort;
|
||||
return;
|
||||
}
|
||||
bnxt_fw_reset_close(bp);
|
||||
if (bp->fw_cap & BNXT_FW_CAP_ERR_RECOVER_RELOAD) {
|
||||
@ -12043,6 +12055,7 @@ static void bnxt_fw_reset_task(struct work_struct *work)
|
||||
if (val == 0xffff) {
|
||||
if (bnxt_fw_reset_timeout(bp)) {
|
||||
netdev_err(bp->dev, "Firmware reset aborted, PCI config space invalid\n");
|
||||
rc = -ETIMEDOUT;
|
||||
goto fw_reset_abort;
|
||||
}
|
||||
bnxt_queue_fw_reset_work(bp, HZ / 1000);
|
||||
@ -12052,6 +12065,7 @@ static void bnxt_fw_reset_task(struct work_struct *work)
|
||||
clear_bit(BNXT_STATE_FW_FATAL_COND, &bp->state);
|
||||
if (pci_enable_device(bp->pdev)) {
|
||||
netdev_err(bp->dev, "Cannot re-enable PCI device\n");
|
||||
rc = -ENODEV;
|
||||
goto fw_reset_abort;
|
||||
}
|
||||
pci_set_master(bp->pdev);
|
||||
@ -12078,9 +12092,10 @@ static void bnxt_fw_reset_task(struct work_struct *work)
|
||||
}
|
||||
rc = bnxt_open(bp->dev);
|
||||
if (rc) {
|
||||
netdev_err(bp->dev, "bnxt_open_nic() failed\n");
|
||||
clear_bit(BNXT_STATE_IN_FW_RESET, &bp->state);
|
||||
dev_close(bp->dev);
|
||||
netdev_err(bp->dev, "bnxt_open() failed during FW reset\n");
|
||||
bnxt_fw_reset_abort(bp, rc);
|
||||
rtnl_unlock();
|
||||
return;
|
||||
}
|
||||
|
||||
bp->fw_reset_state = 0;
|
||||
@ -12107,12 +12122,8 @@ fw_reset_abort_status:
|
||||
netdev_err(bp->dev, "fw_health_status 0x%x\n", sts);
|
||||
}
|
||||
fw_reset_abort:
|
||||
clear_bit(BNXT_STATE_IN_FW_RESET, &bp->state);
|
||||
if (bp->fw_reset_state != BNXT_FW_RESET_STATE_POLL_VF)
|
||||
bnxt_dl_health_status_update(bp, false);
|
||||
bp->fw_reset_state = 0;
|
||||
rtnl_lock();
|
||||
dev_close(bp->dev);
|
||||
bnxt_fw_reset_abort(bp, rc);
|
||||
rtnl_unlock();
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user