Commit c3812c95 authored by Jakub Kicinski's avatar Jakub Kicinski

Merge branch 'bnxt_en-bug-fixes'

Michael Chan says:

====================
bnxt_en: Bug fixes

This bug fix series includes fixes for PCIE AER, a crash that may occur
when doing ethtool -C in the middle of error recovery, and aRFS.
====================

Link: https://lore.kernel.org/r/1667518407-15761-1-git-send-email-michael.chan@broadcom.comSigned-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents 1118b204 02597d39
...@@ -9983,17 +9983,12 @@ static int bnxt_try_recover_fw(struct bnxt *bp) ...@@ -9983,17 +9983,12 @@ static int bnxt_try_recover_fw(struct bnxt *bp)
return -ENODEV; return -ENODEV;
} }
int bnxt_cancel_reservations(struct bnxt *bp, bool fw_reset) static void bnxt_clear_reservations(struct bnxt *bp, bool fw_reset)
{ {
struct bnxt_hw_resc *hw_resc = &bp->hw_resc; struct bnxt_hw_resc *hw_resc = &bp->hw_resc;
int rc;
if (!BNXT_NEW_RM(bp)) if (!BNXT_NEW_RM(bp))
return 0; /* no resource reservations required */ return; /* no resource reservations required */
rc = bnxt_hwrm_func_resc_qcaps(bp, true);
if (rc)
netdev_err(bp->dev, "resc_qcaps failed\n");
hw_resc->resv_cp_rings = 0; hw_resc->resv_cp_rings = 0;
hw_resc->resv_stat_ctxs = 0; hw_resc->resv_stat_ctxs = 0;
...@@ -10006,6 +10001,20 @@ int bnxt_cancel_reservations(struct bnxt *bp, bool fw_reset) ...@@ -10006,6 +10001,20 @@ int bnxt_cancel_reservations(struct bnxt *bp, bool fw_reset)
bp->tx_nr_rings = 0; bp->tx_nr_rings = 0;
bp->rx_nr_rings = 0; bp->rx_nr_rings = 0;
} }
}
int bnxt_cancel_reservations(struct bnxt *bp, bool fw_reset)
{
int rc;
if (!BNXT_NEW_RM(bp))
return 0; /* no resource reservations required */
rc = bnxt_hwrm_func_resc_qcaps(bp, true);
if (rc)
netdev_err(bp->dev, "resc_qcaps failed\n");
bnxt_clear_reservations(bp, fw_reset);
return rc; return rc;
} }
...@@ -12894,8 +12903,8 @@ static int bnxt_rx_flow_steer(struct net_device *dev, const struct sk_buff *skb, ...@@ -12894,8 +12903,8 @@ static int bnxt_rx_flow_steer(struct net_device *dev, const struct sk_buff *skb,
rcu_read_lock(); rcu_read_lock();
hlist_for_each_entry_rcu(fltr, head, hash) { hlist_for_each_entry_rcu(fltr, head, hash) {
if (bnxt_fltr_match(fltr, new_fltr)) { if (bnxt_fltr_match(fltr, new_fltr)) {
rc = fltr->sw_id;
rcu_read_unlock(); rcu_read_unlock();
rc = 0;
goto err_free; goto err_free;
} }
} }
...@@ -13913,7 +13922,9 @@ static pci_ers_result_t bnxt_io_slot_reset(struct pci_dev *pdev) ...@@ -13913,7 +13922,9 @@ static pci_ers_result_t bnxt_io_slot_reset(struct pci_dev *pdev)
pci_ers_result_t result = PCI_ERS_RESULT_DISCONNECT; pci_ers_result_t result = PCI_ERS_RESULT_DISCONNECT;
struct net_device *netdev = pci_get_drvdata(pdev); struct net_device *netdev = pci_get_drvdata(pdev);
struct bnxt *bp = netdev_priv(netdev); struct bnxt *bp = netdev_priv(netdev);
int err = 0, off; int retry = 0;
int err = 0;
int off;
netdev_info(bp->dev, "PCI Slot Reset\n"); netdev_info(bp->dev, "PCI Slot Reset\n");
...@@ -13941,11 +13952,36 @@ static pci_ers_result_t bnxt_io_slot_reset(struct pci_dev *pdev) ...@@ -13941,11 +13952,36 @@ static pci_ers_result_t bnxt_io_slot_reset(struct pci_dev *pdev)
pci_restore_state(pdev); pci_restore_state(pdev);
pci_save_state(pdev); pci_save_state(pdev);
bnxt_inv_fw_health_reg(bp);
bnxt_try_map_fw_health_reg(bp);
/* In some PCIe AER scenarios, firmware may take up to
* 10 seconds to become ready in the worst case.
*/
do {
err = bnxt_try_recover_fw(bp);
if (!err)
break;
retry++;
} while (retry < BNXT_FW_SLOT_RESET_RETRY);
if (err) {
dev_err(&pdev->dev, "Firmware not ready\n");
goto reset_exit;
}
err = bnxt_hwrm_func_reset(bp); err = bnxt_hwrm_func_reset(bp);
if (!err) if (!err)
result = PCI_ERS_RESULT_RECOVERED; result = PCI_ERS_RESULT_RECOVERED;
bnxt_ulp_irq_stop(bp);
bnxt_clear_int_mode(bp);
err = bnxt_init_int_mode(bp);
bnxt_ulp_irq_restart(bp, err);
} }
reset_exit:
bnxt_clear_reservations(bp, true);
rtnl_unlock(); rtnl_unlock();
return result; return result;
......
...@@ -1621,6 +1621,7 @@ struct bnxt_fw_health { ...@@ -1621,6 +1621,7 @@ struct bnxt_fw_health {
#define BNXT_FW_RETRY 5 #define BNXT_FW_RETRY 5
#define BNXT_FW_IF_RETRY 10 #define BNXT_FW_IF_RETRY 10
#define BNXT_FW_SLOT_RESET_RETRY 4
enum board_idx { enum board_idx {
BCM57301, BCM57301,
......
...@@ -162,7 +162,7 @@ static int bnxt_set_coalesce(struct net_device *dev, ...@@ -162,7 +162,7 @@ static int bnxt_set_coalesce(struct net_device *dev,
} }
reset_coalesce: reset_coalesce:
if (netif_running(dev)) { if (test_bit(BNXT_STATE_OPEN, &bp->state)) {
if (update_stats) { if (update_stats) {
rc = bnxt_close_nic(bp, true, false); rc = bnxt_close_nic(bp, true, false);
if (!rc) if (!rc)
......
...@@ -476,7 +476,8 @@ static int __hwrm_send(struct bnxt *bp, struct bnxt_hwrm_ctx *ctx) ...@@ -476,7 +476,8 @@ static int __hwrm_send(struct bnxt *bp, struct bnxt_hwrm_ctx *ctx)
memset(ctx->resp, 0, PAGE_SIZE); memset(ctx->resp, 0, PAGE_SIZE);
req_type = le16_to_cpu(ctx->req->req_type); req_type = le16_to_cpu(ctx->req->req_type);
if (BNXT_NO_FW_ACCESS(bp) && req_type != HWRM_FUNC_RESET) { if (BNXT_NO_FW_ACCESS(bp) &&
(req_type != HWRM_FUNC_RESET && req_type != HWRM_VER_GET)) {
netdev_dbg(bp->dev, "hwrm req_type 0x%x skipped, FW channel down\n", netdev_dbg(bp->dev, "hwrm req_type 0x%x skipped, FW channel down\n",
req_type); req_type);
goto exit; goto exit;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment