Skip to content

Commit 0cf736a

Browse files
vikasbrcmkuba-moo
authored andcommitted
bnxt_en: fix the handling of PCIE-AER
Fix the sequence required for PCIE-AER. While slot reset occurs, firmware might not be ready and the driver needs to check for its recovery. We also need to remap the health registers for some chips and clear the resource reservations. The resources will be allocated again during bnxt_io_resume(). Fixes: fb1e6e5 ("bnxt_en: Fix AER recovery.") Signed-off-by: Vikas Gupta <vikas.gupta@broadcom.com> Signed-off-by: Michael Chan <michael.chan@broadcom.com> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
1 parent b4c6642 commit 0cf736a

3 files changed

Lines changed: 31 additions & 2 deletions

File tree

drivers/net/ethernet/broadcom/bnxt/bnxt.c

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13922,7 +13922,9 @@ static pci_ers_result_t bnxt_io_slot_reset(struct pci_dev *pdev)
1392213922
pci_ers_result_t result = PCI_ERS_RESULT_DISCONNECT;
1392313923
struct net_device *netdev = pci_get_drvdata(pdev);
1392413924
struct bnxt *bp = netdev_priv(netdev);
13925-
int err = 0, off;
13925+
int retry = 0;
13926+
int err = 0;
13927+
int off;
1392613928

1392713929
netdev_info(bp->dev, "PCI Slot Reset\n");
1392813930

@@ -13950,11 +13952,36 @@ static pci_ers_result_t bnxt_io_slot_reset(struct pci_dev *pdev)
1395013952
pci_restore_state(pdev);
1395113953
pci_save_state(pdev);
1395213954

13955+
bnxt_inv_fw_health_reg(bp);
13956+
bnxt_try_map_fw_health_reg(bp);
13957+
13958+
/* In some PCIe AER scenarios, firmware may take up to
13959+
* 10 seconds to become ready in the worst case.
13960+
*/
13961+
do {
13962+
err = bnxt_try_recover_fw(bp);
13963+
if (!err)
13964+
break;
13965+
retry++;
13966+
} while (retry < BNXT_FW_SLOT_RESET_RETRY);
13967+
13968+
if (err) {
13969+
dev_err(&pdev->dev, "Firmware not ready\n");
13970+
goto reset_exit;
13971+
}
13972+
1395313973
err = bnxt_hwrm_func_reset(bp);
1395413974
if (!err)
1395513975
result = PCI_ERS_RESULT_RECOVERED;
13976+
13977+
bnxt_ulp_irq_stop(bp);
13978+
bnxt_clear_int_mode(bp);
13979+
err = bnxt_init_int_mode(bp);
13980+
bnxt_ulp_irq_restart(bp, err);
1395613981
}
1395713982

13983+
reset_exit:
13984+
bnxt_clear_reservations(bp, true);
1395813985
rtnl_unlock();
1395913986

1396013987
return result;

drivers/net/ethernet/broadcom/bnxt/bnxt.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1621,6 +1621,7 @@ struct bnxt_fw_health {
16211621

16221622
#define BNXT_FW_RETRY 5
16231623
#define BNXT_FW_IF_RETRY 10
1624+
#define BNXT_FW_SLOT_RESET_RETRY 4
16241625

16251626
enum board_idx {
16261627
BCM57301,

drivers/net/ethernet/broadcom/bnxt/bnxt_hwrm.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -476,7 +476,8 @@ static int __hwrm_send(struct bnxt *bp, struct bnxt_hwrm_ctx *ctx)
476476
memset(ctx->resp, 0, PAGE_SIZE);
477477

478478
req_type = le16_to_cpu(ctx->req->req_type);
479-
if (BNXT_NO_FW_ACCESS(bp) && req_type != HWRM_FUNC_RESET) {
479+
if (BNXT_NO_FW_ACCESS(bp) &&
480+
(req_type != HWRM_FUNC_RESET && req_type != HWRM_VER_GET)) {
480481
netdev_dbg(bp->dev, "hwrm req_type 0x%x skipped, FW channel down\n",
481482
req_type);
482483
goto exit;

0 commit comments

Comments
 (0)